Dlaczego dokładne liczenie się rozpraszają na dużym skalę
Jasna metoda do liczenia jednostek jest zapamiętywanie każdego obiekta, który już widzieliśmy, zwykle w zestawie hash, i sprawdzanie nowych obiektów przeciwko nim. To działa doskonale dla małych zbiorów danych, ale skali się bardzo źle. Aby liczyć dokładnie miliardy unikalnych identyfikatorów użytkowników, potrzebujesz przechowywać około miliarda wpisów w pamięci, co może znaczyć wiele gigabajtów RAM. Pomnożenie tego na tysiące różnych miar, takich jak unikalni odwiedzający stronu, dziennie, krajowo, dokładne liczenie staje się finansowo i operacyjnie niemożliwe. Pasażerem problemu jest to, że dokładna liczba kart wymaga pamięci proporcjonalnej do liczby unikalnych obiektów, niezależnie od tego, jak ciekawym sposobem je przechowywane są. Systemy rzeczywiste, takie jak platformy analtyczne, sieci reklamowe i bazy danych często muszą śledzić liczby unikalne dla milionów oddzielnych kluczy jednocześnie, każdy z potencjalnie bilionami elementów. Przechowywanie pełnego zestawu dla każdego z nich prostym jest nie do zmieszczenia w pamięci ani budżecji. To właśnie puste miejsce, które estymatory kardynalności probabilistycznych były zaprojektowane, aby uzupełnić. Poprzez przyjmowanie małej, statystycznie ograniczonej ilości błędu, zwykle kilkuset procent, algorytmy takie jak HyperLogLog zmniejszają wymagania pamięci od gigabajtów do kilobajtów, co stanowi redukcję wielu rzędów dziesiętnych. Ta transakcja, mały błąd za ogromne oszczędności pamięci, jest to, co sprawia, że liczenie na skalę internetowej jest w ogóle możliwe.
Kluczowe Zrozumienie: Wskazówka odnosząca się do Cyfr Odciętych
Podstawowa idea HyperLogLog polega na haszowaniu. Każdy element, który liczymy, jest przetwarzany przez funkcję haszującą, która tworzy ciąg bitów wydajny i losowy. Dobra funkcja haszująca rozprowadza wyniki jednorodnie, co oznacza, że każdy bit w tym ciągu jest równie prawdopodobny do wystąpienia jako 0 lub 1, niezależnie od innych. Teraz zastanówmy się nad ciągiem cyfr odciętych na początku hasha, czyli ile cyfr 0 znajduje się przed pierwszym 1. Prawdopodobieństwo tego, że pojedyncze losowe haszanie zaczyna się dokładnie od jednej cyfry odciętej, wynosi połowa. Prawdopodobieństwo tego, że zaczyna się ono od dwóch cyfr odciętych, wynosi czwartą część, ponieważ oba pierwsze dwa bity muszą być zerami. Ciąg k cyfr odciętych ma prawdopodobieństwo jedno do dwójki do potęgi k. To oznacza, że zauważenie długiego ciągu cyfr odciętych w pojedynczym haszu jest rzadkie. Ale jeśli haszysz wiele różnych elementów i śledzisz najdłuższy ciąg cyfr odciętych obserwowany wśród wszystkich tych haszowanych, to ten maksymalny ciąg rośnie wraz z dodaniem więcej różnych elementów. Intuicyjnie mówiąc, jeśli do tej pory widziałeś najdłuższy ciąg cyfr odciętych równy 10, to jest to zdarzenie prawdopodobne jedynie co 1024, więc prawdopodobnie musisz było spróbować około tysiąca różnych haszowanych elementów, aby ich spotkać. Tym jednym numerycznym parametrem, tzn. długości maksymalnego ciągu cyfr odciętych, staje się przybliżony, ale rzeczywisty estymator statystyczny liczby różnych elementów haszowanych.
Rozdzielanie na Kompartmenty: Dlaczego Jedna Licznik Nie Sufficencyjna
Jedna maksymalna licznik zerowych jest szumowym estymatorem. Jeden szczęśliwy lub nie szczęśliwy hash może znacząco zniekształcić całą ocenę, ponieważ estymata rośnie eksponencjalnie ze długością ciągu zerowych. Realny HyperLogLog naprawia to dzieląc przestrzeń haszująca na wiele niezależnych kompartmentów, często nazywanych rejestrkami, zazwyczaj między kilkoma setkami a kilkoma tysiącami. Kilka bitów każdego hasha, np. pierwszych bitów, wyznacza, w jakim kompartmentu znajduje się hasz danego elementu, a pozostałe bity są używane do obliczenia długości ciągu zerowych w tym samym kompartmentie. Każdy kompartment niezależnie śledzi tylko własną maksymalną długość ciągu zerowych. Zamiast zależeć na jednym szumowym liczniku, teraz masz setki lub tysiące niezależnych szumowych estymacji. Średnianie wielu niezależnych sygnałów szumowych znacznie zmniejsza wariancję, co jest ogólnej i mocną statystyczną zasługą. HyperLogLog specjalnie używa średniej harmonicznej zamiast prostego średnia arytmetyczna do łączenia estymacji dla poszczególnych kompartmentów, ponieważ średnie harmoniczne są znacznie mniej wrażliwe na rzadkie duże wartości wyjatkowe, które tutaj mają duży wpływ, ponieważ estymaty długości ciągu rosną eksponencjalnie. Ostateczna szacunek liczby elementów jest pochodna z tej średniej harmonicznej, pomnożona przez stałą korekcji błędu dostosowaną do liczby używanych kompartmentów.
Dokładność wobec pamięci: Znaczna Ważona Odpowiedzialność
Zarówno praktyczne korzyści, jak i wymagania pamięci z podejścia opartego na koszach i wartościach średniogarmatnych są nieocenione. Dzięki tylko kilku tysiącom rejestrów, każdy potrzebujący tylko kilka bitów do przechowywania małej wartości długości przepływu, HyperLogLog może szacować liczbę elementów zbioru z błędem standardowym około 2 procent, niezależnie od tego, czy rzeczywista liczba to tysiąc czy miliard. W praktyce zużycie pamięci dla takiej dokładności wynosi obecnie około 1,5 kilobajtów, często podawane jako około 6 bitów na rejestr, np. przy 16384 rejestrowych konfiguracjach o bardzo wysokiej precyzji zużywa około 12 kilobajtów. Porównaj to z dokładnym liczeniem, które mogłoby wymagać wielu gigabajtów do śledzenia miliarda unikalnych identyfikatorów 64-bitowych, uwzględniając nadmiar pamięci w tabeli haszującej. Jest to redukcja pamięci o wiele rzędów dla małego, przewidywalnego i matematycznie ograniczonego błędu. Istotne jest, że ten błąd nie rośnie z rozmiarem zbioru. Błąd standardowy pozostaje prawie stały wraz z wzrostem liczby elementów, co sprawia, że HyperLogLog jest wyjątkowo odpowiednie do śledzenia ogromnych i ciągle rosnących zbiorów danych. Możesz dostosować tę ważoną odpowiedzialność wybierając więcej lub mniej rejestrów: więcej rejestrow przekłada się na niższy błąd, ale większą zużycie pamięci, co jest zgodne z dobrze zrozumiałym matematycznym związkem między liczbą rejestrow a oczekiwanym błędem standardowym.
Zastosowania w praktyce: od Redis do analiz webowych
HyperLogLog nie jest tylko akademickim zainteresowaniem – jest wdrożone w produkcyjnych systemach obsługujących ogromne skalę codziennie. Redis, popularna magazyn data w pamięci RAM, oferuje wbudowaną obsługę HyperLogLog poprzez polecenia takie jak PFADD do dodawania elementów i PFCOUNT do pobierania szacunku liczby kartecji, wszystko oparte na strukturze danych, która Redis ogranicza do około 12 kilobajtów niezależnie od ilości miliardów elementów dodanych. Zespoly inżynieryjne korzystają z tego do liczenia unikalnych wizytatorów witryny internetowej, unikalnych zapytań wyszukiwania podawanych przez wyszukiwarce, unikalnych adresów IP dotykających API lub unikalnych produktów widzianych w katalogu e-commerce, bez wymagania pamięci wybuchowej, jaką wymagałby dokładny licznik. Duże platformy i bazy danych analizowe, w tym systemy zbudowane przez duże wyszukiwarki internetowe i sieci społecznościowe, używają HyperLogLog lub bliskich mu wariantów wewnętrznie dla tej samej powodów: przybliżone odpowiedzi dostarczone natychmiastowo i dość drogo są często znacznie wartościowe niż dokładne odpowiedzi, które byłyby zbyt wolne lub zbyt drogie do obliczenia. Inny wygodny atrybut polega na tym, że struktury HyperLogLog z różnych shardów lub okresów czasowych można łączyć ze sobą, co pozwala na liczenie unikalnych liczb w połączonych zestawach danych bez ponownego skanowania oryginalnych danych, co naturalnie wpada w ramy architektur rozproszonych i strumieniowych.
Często zadawane pytania
Czy szacunek z użyciem HyperLogLog jest zawsze dokładny?
Nie, jest to szacunek prawdopodobieństwowy o ograniczonej błędu standardowego, typowo okolicznie 2 procent przy standardowych konfiguracjach. Zwykle nie będzie dokładnie poprawny, ale pozostanie w przewidywalnej statystycznej dziedzinie prawdziwej liczby.
Dlaczego nie można użyć normalnego zestawu hashów do liczenia unikalnych elementów?
Zestaw hashów przechowuje każdy odrobinę unikalny element, co powoduje liniowe wzrost zużycia pamięci z rosnącą liczbą unikalnych elementów, potencjalnie osiągając gigabajty dla danych o skali miliarda. HyperLogLog używa stałej, małej ilości pamięci niezależnie od liczby kardynalności.
Co się stanie, jeśli dwa różne elementy wygenerują ten sam hash?
Kolizje hashów są bardzo rzadkie z dobrym funkcjonałem hashującego i dużym rozmiarem wyjściowym, a matematyka HyperLogLog już uwzględnia małą statystyczną szum, który one wprowadza, więc nie znacząco wpływają na dokładność.
Czy można łączyć liczenia z użyciem HyperLogLog pochodzące z wielu źródeł?
Tak, to jedna z najbardziej przydatnych właściwości. Możesz scalić dwa struktury HyperLogLog, biorąc elementowe maksimum ich rejestrów, co tworzy prawidłową strukturę dla unii obu oryginalnych zbiorów bez potrzeby oryginalnych danych.
Dlaczego HyperLogLog używa średniej harmonicznej zamiast prostej średniej arytmetycznej?
Szacunki długości odcinka rosną eksponencjalnie, więc pojedynczy niezwykle duży wartość w prostej średniej mogłaby znacznie utrudnić wynik. Średnia harmoniczna jest znacznie mniej czuła na takie wykazane wartości, co prowadzi do bardziej stabilnej ogólnej szacunku.
Wypróbuj na żywo
Wszystko powyżej działa bezpośrednio w Twojej przeglądarce — otwórz HyperLogLog: Counting Billions of Unique Items in a Few Kilobytes i zmieniaj parametry podczas działania. Nic nie jest instalowane ani przesyłane na serwer, cały model działa w jednej karcie.
▶ Otwórz symulację HyperLogLog: Counting Billions of Unique Items in a Few Kilobytes