Sprytny sposób na oszczędność miejsca w Elasticsearch

wiadrodanych.pl 10 miesięcy temu
Zdjęcie: elasticsearch index order syntetic


W artykule dowiesz się dwóch oryginalnych sposobów na zmniejszenie danych w Elasticsearch nawet o 67%.

Sposób 1 – posortuj dane

Sposób ten jest wspominany w dokumentacji , ale nie ma konkretnych informacji ile można zyskać. Na tegorocznym ElasticON w Amsterdamie dowiedziałem się, iż ElastiFlow korzysta z TSDB oraz sortowania do zmniejszenia rozmiaru indeksów. Postanowiłem to sprawdzić!
Sortowanie wprowadzono już w wersji 6. Sortowanie może przyśpieszyć wyszukiwanie oraz zmniejszyć rozmiar danych. Jest to związane z umieszczeniem podobnych danych blisko siebie.

Porównałbym to do formatów kolumnowych (o których mówiłem w tym artykule). Podobne dane lepiej się kompresują. Niestety są też wady sortowania na poziomie indeksu: indeksowanie może trwać dłużej/jest bardziej kosztowne obliczeniowo.

PUT my-index-000001 { "settings": { "index": { "sort.field": [ "username", "date" ], "sort.order": [ "asc", "desc" ] } }, "mappings": { "properties": { "username": { "type": "keyword", "doc_values": true }, "date": { "type": "date" } } } }

Sposób 2 – syntetic context

Elastic wdrożył TSDB, czyli zoptymalizowaną strukturę dla danych typu szeregi czasowe. Choć strumień jest głównie pod metryki, wykorzystuje interesujący mechanizm syntetic _source który możemy wykorzystać w przypadku logów.

Pole _source to oryginalny JSON dokumentu. “Czasem” się przydaje… na przykład jak chcemy wyświetlić dokument lub zrobić reindex. Możemy go wyłączyć. Wyszukiwanie przez cały czas będzie działać, ale… ciężko będzie zobaczyć co dokładnie znaleźliśmy.

Syntetic rozwiązuje ten problem. Elasticsearch odbudowuje dokument na podstawie indeksów. Jest trochę wolniej, ale oszczędzamy miejsce na dysku. Warto pamiętać, iż są pewne ograniczenia.

PUT idx { "mappings": { "_source": { "mode": "synthetic" } } }

Testy

Małe indeksy

Pierwsze testy robiłem na podzbiorze dużego indeksu z logami z firewalla. 12 shardów (bez replik) ważyło razem 14,6 gb (wersja v0). Poniżej znajduje się tabelka z wynikami. W kolumnie sort wpisałem liczbę pól po których sortowałem. Kolejno były to pola: event.type, network.transport, event.action, source.ip, destinatnion.ip, destination.port i @timestamp.

versionsortshardssyntheticsize [gb]diff [%]
v0012014,60,00%
v1412012,812,33%
v2612012,117,12%
v36601217,81%
v476011,322,60%
v57619,336,30%

Na śmiesznie małym indeksie (i jednocześnie dużej liczbie shardów) zysk wyniósł maksymalnie 36,3 %. Zakładając, iż nie możemy wykorzystać syntetic source: 22,6 %. To i tak nie jest źle! Załóżmy, iż teraz Data Stream waży 10 TB. Samo sortowanie zmniejszy go do 7,74 TB. Zyskaliśmy ponad 2 TB miejsca!

Duże indeksy

Ale to były rookie numbers. Sprawdźmy to na prawdziwych danych!

Prawdziwe, ale skopiowane

indexsize [gb]diff [%]
original608,40%
original-sorted467,323%
original-sorted-syntetic200,167%

Sortowanie dało podobny wynik co poprzednio, czyli około 23%. Zaskakuje zysk dla syntetic source: 67%!

Prawdziwy datastream

Nie zawsze możemy zmienić source na syntetic, a zmiana sortowania to mało roboty. Zmieniamy Template, robimy roll over (lub czekamy aż sam się zrobi). Voila! Jakie efekty?

indexdoc countsize [gb]diff [%]
some-index-00000194 661 042100.19gb0%
some-index-000002138 696 780100.77gb32%

Tym razem trochę inny układ tabeli, bo ILM działa na podstawie rozmiaru shardów. Na pierwszy rzut oka widać różnicę w liczbie dokumentów. W najnowszym indeksie zmieściło ich się znacznie więcej. Zyskaliśmy około 32% miejsca dla tego Data Streamu.

Podsumowanie

Liczby mówią same za siebie. Sortowanie to zysk w okolicy 20-30 %. Syntetic source to 40-50%. Warto pobawić się adekwatnościami indeksów. Większość osób pewnie choćby nie odczuje wolniejszego indeksowania dokumentów.

Idź do oryginalnego materiału