Druga sprawa: Wszystkie operacje wyszukiwania których nie można zaindeksować na tabeli 500GB zapisanej na HDD trwają kilka - kilkadziesiąt godzin. Nie jestem do końca przekonany czy warto w ogóle interesować się takimi przypadkami?
Nie mieszaj analityki z zastosowaniami transakcyjnymi. Dwa zupełnie różne światy. W systemach transakcyjnych nigdy nie masz full-scanów, chyba że dla tabelki mającej 20 rowków i wiesz, że będzie mieć 20 rowków a nie 2000. Szybkość skanowania danych jest interesująca tylko dla analityków.
Muszę przyznać że do tej pory nie zastanawiałem się nad rozróżnieniem systemów na analityczne i transakcyjne.
Nawet skanowanie 100 MB danych trwałoby zbyt długo dla typowych systemów transakcyjnych, które wymagają odpowiedzi w pojedyncze milisekundy.
Zgodzę się z Tobą. W milisekundę ciężko cokolwiek zrobić na komputerze, za wyjątkiem uruchomionego procesu który przez 1ms może wykonać miliony operacji na jednym rdzeniu. Jednak w praktyce odpowiedź bazy w granicach 0.2 - 0.5 sekundy jest akceptowalna. Potem dochodzi czas na jakiś przesył danych, renderowanie interfejsu, albo na składanie wyników gdy używamy map-reduce, więc w efekcie odpowiedź całego systemu będzie na poziomie 2s. To zazwyczaj jest bardzo dobry czas. Alegro mi bardzo imponuje, można wyszukiwać po tekscie, po wielu innych parametrach, sortować według wielu kryteriów i odpowiedź jest błyskawiczna.
Zobacz, Google ma zaindeksowane petabajty danych, a wyszukuje w nich w milisekundy.
W ogóle stąd się wzięło BigData i NoSQL (później wiele pomysłów przeszło z NoSQL do klasycznych RDBMSów) - trzeba było wymyślić coś na te wszystkie przypadki, gdzie jeden serwer nie wystarczał.
Dawno straciłem wyczucie co w przypadku słynnego Google jest mitem, a co prawdą. Ile wyników wyszukiwania widziałeś najwięcej, bo ja jeden tysiąc, nigdy nie widziałem chociażby 10 tys. W przypadku wyszukiwarek internetowych największym problemem jest posortowanie wyników, a czemu zawdzięczają szybkość działania, to nie jestem pewny. Raczej przeglądarki nie działają tak że mają zapełnione dyski hdd i do wyszukiwania typowy indeks z RDBMSa, np. taki jak btree lub hashtable.
Generalnie moje pytanie jest takie, dlaczego warto się interesować takim przypadkiem?
Zbieramy dane z tysięcy czujników / transakcji i chcemy generować w locie ostrzeżenia o np. podejrzanych transakcjach (wszelkie banki czy systemy płatności). Albo robimy serwis ala Spotify / Facebook / Gmail itp. Po prostu jest całe mnóstwo przypadków gdzie dane nie mieszczą się w pamięci, a jednak chcemy je szybko wyszukiwać i musimy dawać odpowiedzi w milisekundy. A nawet jeśli dane mieszczą się w pamięci to i tak nie ma czasu skanować całej pamięci, bo to też trwa za długo.
No tak, ale jeśli użyjemy przeciętnego RDBMSa i dostępnych w nim indeksów, to zbyt inteligentnego wyszukiwania nie będziemy mieli? Mamy np. bazę artykułów. W artykule jak wiadomo mamy np. 1-5tys słów. Użytkownik wpisuje 5-10 słów kluczowych które mają się pojawić i z 2-3 które nie mogą się pojawić. Przy czym w słowach mogą być literówki, bo google z literówką sobie poradzi. Ponadto, jeśli 'ciągła fraza' się pojawia na stronie X, a na stronie Y pojawiają się rozbite słowa kluczowe, to strona X powinna być wyświetlona wyżej niż strona Y. Podsumowując - nie wierzę, aby to zadanie nadawało się na dyski hdd z odpowiednim indeksem.
Trzecia sprawa: piszesz że Cassandra 'na takim' - nie wiem czy chodzi o ten w RAM, czy o ten 500GB na HDD. Jeśli chodzi o ten na HDD, to znaczy, że Cassandra nie sprawdza unikalności klucza, ale zakłada jego unikalność (np. zawsze inkrementuje o jeden) i zapisuje sekwencyjnie bez sprawdzania po 'losowo' rozrzuconych węzłach b-tree.
Miałem na myśli ten przypadek z 500 GB. Nie zgaduj, tylko poczytaj jak to jest zrobione, bo błądzisz w mroku.
Nie poczytam, bo nie przebrnę przez szczegóły. Ogólnie zastanowiłem się jak to może być rozwiązane.
Nie sprawdza unikalności i nie zakłada jego unikalności, ale po operacji wstawienia jest zawsze unikalny.
Tutaj chyba jest sprzeczność. Unikalność musi z czegoś wynikać. Może wynikać ze sprawdzenia czy jest unikalny, albo z założenia, że dany algorytm nigdy nie wygeneruje dwóch identycznych wartości.
Baza SQLowa tak nie może, bo SQL ma taką a nie inną sematykę, że INSERT wymaga rzuceniem błędu przy próbie wstawienia czegoś co już jest.
Cassandra, podobnie jak wiele baz klucz-wartość, wybiera po prostu nadpisanie danych o tym samym kluczu i tyle, tak jak typowy HashMap / słownik.
Z punktu widzenia wydajności, albo z punktu widzenia możliwości sekwencyjnego zapisu (bo od tych tematów się zaczął ten wątek) to jest to samo. Obojętnie czy rzucimy wyjątek, czy nadpiszemy dane, to musimy sprawdzić czy dany klucz nie istnieje, albo musimy założyć że nie istnieje. Gdy sprawdzamy, to jedna i druga baza musi posłużyć jakimś indeksem. Jeśli posluguje się indeksem nie mieszczącym się w RAM, to nie zapiszemy na HDD więcej niż 50 rekordów na sekundę. Gdy używamy w dodatku podwójnego zapisu (dziennik) to nie zdziwiłbym się, gdyby 'ograniczenia technologii' były na poziomie 30 rekordów na sekundę. Ograniczenia technologii, czyli dowolna baza ich nie przeskoczy.
Poza tym nie wiem czemu myślisz o kluczu jako o liczbie. Klucz może być czymkolwiek. Np. stringiem. I klucza nie generuje baza, a użytkownik. W RDBMSach owszem czasem stosuje się sekwencje lub kolumny auto-increment, ale w systemie rozproszonym takie rozwiązanie nie ma racji bytu, bo kto miałby niby generować ten unikatowy licznik?
Nie myślę o kluczu jako o liczbie, tylko użyłem przykładu w którym klucz jest zdefiniowany na jednej kolumnie typu int. Użyłem takiego przykładu, ponieważ operacje na intach są szybkie, a my o szybkim wykonywaniu operacji rozmawialiśmy.
P.S.
Testów dalszych na razie nie mam, bo chwilowy brak czasu, ale będę kontynuował, będą agregacje i nie tylko.
Pozdrawiam
Aventus