2016-07-07 50 views
15

Potrzebuję zaoszczędzić około 7,8 miliarda rekordów w tabeli Mysql. Tabela intensywnie czyta i zapisuje. Muszę utrzymywać co najmniej 0,02 miliarda rekordów na godzinę wskaźnika wstawienia. Wyszukiwanie w tabeli nie powinno trwać dłużej niż 10 sekund. Mamy interfejs użytkownika, z którego użytkownicy mogą wyszukiwać w oparciu o różne właściwości colums.Mysql: 7 miliardów rekordów w tabeli

Głównie szukane zapytanie może być tak:

  1. select * from mytable where prop1='sip:+100008521149' and prop2='asdsa' order by event_timestamp desc limit 10;

  2. select * from mytable where prop1='sip:+100008521149' order by event_timestamp desc limit 10;

  3. select * from mytable where prop2='asdsa' order by event_timestamp desc limit 10;

Obecnie istnieją 2 indeksy na stole:

1- idx_1(prop1,event_timestamp) 
2- idx_2(prop2,event_timestamp) 

InnoDB ustawienia są następujące:

innodb_buffer_pool_size = 70G 
    innodb_log_file_size = 4G 
    innodb_io_capacity=2000 
    innodb_io_capacity_max=6000 
    innodb_lru_scan_depth=2000 
    innodb_flush_log_at_trx_commit=2 
    innodb_log_buffer_size=16M 
    innodb_thread_concurrency = 0 
    innodb_read_io_threads = 64 
    innodb_write_io_threads = 64 
    innodb_autoinc_lock_mode = 2 
    bulk_insert_buffer_size=33554432 
    query_cache_type=1 
    query_cache_size=64M 
    innodb_flush_neighbors=0 
    expire_logs_days=10 
    max-connections=500 
    long_query_time = 5 
    read_buffer_size=16M 
    sort_buffer_size=16M 
    read_rnd_buffer_size=16M 
    innodb_doublewrite = 0 
    innodb_flush_method=O_DIRECT 

Machine's RAM size is 99 GB. 

Po uruchomieniu system był szybki, ale zmniejsza wydajność dużo kiedy płyta osiągnęła 0,22 mld. Chociaż używamy LOAD INFILE, szybkość wstawiania była bardzo wolna. Wyszukiwarka była dość szybka podczas wyszukiwania indeksowanych parametrów. Wygląda na to, że puli buforów nie wystarczy.

mam kilka pytań:

  1. to jest możliwe, aby wspierać tego rodzaju danych z tej konfiguracji.

  2. Jaki powinien być idealny i praktyczny rozmiar puli buforów dla rekordów 7 miliardów.

  3. DATA + INDEX rozmiar zbliża się do 150 GB z tylko 0,22 miliarda rekordów . Wygląda na to, że potrzebuję TB's of RAM.
  4. Myślimy o konfiguracji Master/Slave, aby congif dla odczytu i zapisu dominujący na odpowiednich serwerach.
  5. Każdy inny lepszy sposób zaprojektowania tego rozwiązania?
  6. Zwiększenie liczby indeksów powoduje, że wyszukiwanie interfejsu użytkownika jest lepsze, ale zwiększenie wartości pojedynczego indeksu zmniejsza szybkość wstawiania wielu zagięć.

UPADTE: 1

Q- tabela jest znacznie większy niż RAM, prawda? Pula_buforowa nie może być wystarczająco duża - musi być mniejsza niż pamięć RAM, lub wydajność ucierpi.

A- Rozmiar pamięci RAM to 100 GB, bufor bufora to 70 G. Tak, rozmiar danych jest zbyt duży niż pamięci RAM.

Q- Proszę podać SHOW CREATE TABLE; jest kilka kwestii, które muszę zbadać. (typy danych, rozmiary pól, itp.)

A- Wszystkie pola są typu string.użyliśmy varchar (127) dla wszystkich. PK to autogeneracja id bigint (20).

Q- Ile rekordów w INFINACJI DANYCH LOAD? Czy ładujesz bezpośrednio do stołu? Jak często jest LOAD?

A- 100000 rekordów na plik. Wiele wątków ładuje dane z pliku CSV do DB. W początkowej migracji musimy ładować ją nieprzerwanie do 0,65 miliarda rekordów. Po tej częstotliwości zmniejszy się do około na 15 minut.

Q- Master + Slave: Należy pamiętać, że wszystkie zapisy są wykonywane również na Slave. Jeśli masz dużo lektur, wtedy więcej niż jeden Slave rozprzestrzeniłby odczyty, powodując w ten sposób pewne skalowanie.

A-Testujemy obecnie z podejściem MASTER/SLAVE.

Wykonaliśmy MASTER z MYISAM i bez indeksów. MASTER zostanie użyty dla insertów. SLAVE o INNODB i 2 indeksach. Wyszukiwanie zostanie wykonane na nim. Obie są różnymi maszynami i nie udostępniają pamięci RAM ani procesora. Aplikacja znajduje się na trzecim komputerze.

Q- Czy masz dyski spinningowe? Lub dyski SSD? A- Jak to sprawdzić?

Q- Twoje rzędy wydają się dość duże. Czy są jakieś TEKSTY lub BLOBY? Jeśli tak, SELECT * może stanowić poważne obciążenie dla wydajności.

A-tak rzędy mają 50 kolumn, ale dane są w około 15-20 kolumnach. Nie możemy zmniejszyć rozmiaru typów danych, ponieważ wszystkie pola mogą pomieścić dowolną ilość danych alfanumerycznych. Wszystkie są TEKSTAMI bez BLOBÓW.

+1

Wierzę, że chcesz mieć indeks "(prop1, prop2, event_timestamp)" dla tego zapytania. – zerkms

+0

możesz przesłać mi wynik z ** SELECT * FROM mytable PROCEDURE ANALYZE(); ** –

+0

@zerkms: Proszę zobaczyć aktualne informacje na temat indeksów. – Mudit

Odpowiedz

1

Osiągnąłem ten wymóg, zastępując MYSQL DB przez Elasticsearch. Wygląda idealnie do szybkiego wstawiania i cholernie szybkiego wyszukiwania. Co więcej, pełno tekstowe możliwości Lucene sprawiają, że jest to doskonałe narzędzie. Najlepszą częścią ES jest to, że ma bardzo niskie wymagania sprzętowe. Skaluje się poziomo, a nie pionowo.

2

To nie jest odpowiedź, ale nie mogę sformatować go w komentarzu

można proszę spróbować sprawdzić, czy to szybciej. tak MySQL nie musi uporządkować szeregu otworów tylko identyfikator (klucz podstawowy)

SELECT r.* 
FROM (
    SELECT id 
    FROM mytable 
    WHERE 
     prop1='sip:+100008521149' 
    AND 
     prop2='asdsa' 
    ORDER BY event_timestamp DESC 
    LIMIT 10 
) AS r 
LEFT JOIN mytable m ON m.id =r.id 
ORDER BY r.event_timestamp DESC; 
+0

Ale w przypadku braku wyraźnego 'order by', porządek jest niezdefiniowany. –

+0

@Sergio Tulentsev - poprawne! , możesz dodać go ponownie na końcu zapytania, a następnie posortować tylko 10 wierszy. –

+1

To musi być porównane. Mam silne przeczucie, że mysql użyje indeksu do sortowania w tym miejscu (co oznacza, że ​​ta sztuczka nie jest potrzebna i prawdopodobnie wolniej) –

3

Wyłącz cache zapytań: Należy usunąć wszystkie wpisy w QC każdym razem, gdy INSERT występuje - to 5555 razy na sekundę!

query_cache_type = 0 
query_cache_size = 0 

Pierwsze zapytanie wymaga INDEX(prop1, prop2, event_timestamp). (Prop1 i prop2 mogą być zamienione.)

Z tym dodanym indeksem każde z trzech zapytań dotknie nie więcej niż 10 wierszy indeksu i nie spowoduje więcej niż 10 losowych (?) Pobrań danych. W najgorszym przypadku jest to tylko około 11 trafień na dysku. A "leniwy eval" Bernda nie poprawi tego.

Tabela jest znacznie większa niż pamięć RAM, prawda? Pula buforów nie może być wystarczająco duża - musi być mniejsza niż ram, lub wydajność cierpi.

Proszę podać SHOW CREATE TABLE; jest kilka kwestii, które muszę zbadać. (typy danych, rozmiary pól, itp.)

Ile rekordów w LOAD DATA INFILE? Czy jesteś LOAD bezpośrednio w tabeli? Jak często jest LOAD?

Master + Slave: Należy pamiętać, że wszystkie zapisy są wykonywane również na Slave.Jeśli masz dużo odczytów, wtedy więcej niż jeden Slave rozprzestrzeniłby się na , czytając w ten sposób, uzyskując w ten sposób pewne skalowanie.

Czy masz dyski obrotowe? Lub dyski SSD?

Twoje rzędy wydają się dość duże. Czy istnieje TEXTs lub BLOBs? Jeśli tak, SELECT * może być poważnym obciążeniem wydajnościowym.

+0

Wyłączenie kontroli jakości wygląda jak bardzo dobra sugestia (+1): w tym scenariuszu wydaje się mało prawdopodobne, aby była używana. – LSerni

+0

lub ustaw typ bufora zapytań na ** NA ŻĄDANIE **, aby można je było dla każdego zapytania. –

+0

Odpływ wydajności to wielokrotne przycinanie QC, które ma miejsce, gdy jest włączone. 'ŻĄDANIE' nie zapobiega przycinaniu. –