2015-05-08 16 views
5

Próbuję zrozumieć, co dokładnie dzieje się wewnętrznie w silniku pamięci masowej, gdy wiersz (kolumny) zostanie wstawiony w tabeli stylu CQL.Cassandra storage internal

CREATE TABLE log_date (
    userid bigint, 
    time timeuuid, 
    category text, 
    subcategory text, 
    itemid text, 
    count int, 
    price int, 
    PRIMARY KEY ((userid), time) - #1 
    PRIMARY KEY ((userid), time, category, subcategory, itemid, count, price) - #2 
); 

Załóżmy, że mam tabelę jak powyżej.

W przypadku numeru 1, wiersz CQL wygeneruje 6 (lub 5?) Kolumn w pamięci.
W przypadku numeru 2, wiersz CQL wygeneruje bardzo złożoną kolumnę w pamięci.

Zastanawiam się, jaki jest skuteczniejszy sposób przechowywania dzienników w Cassandrze.
Skoncentruj się na tych dwóch sytuacjach.
Nie potrzebuję żadnych odczytów w czasie rzeczywistym. Tylko pisma.



Jeśli chcesz zasugerować inne opcje, zapoznaj się z poniższymi informacjami.
powodów, dla których wybraliśmy Cassandrę do przechowywania logów są

  1. liniowa skalowalność i dobre dla ciężkich piśmie.
  2. Ma schemat w języku CQL. Naprawdę wolę mieć schemat.
  3. Wydaje się wesprzeć Sparka wystarczająco dobrze. Złącze iskrobezpieczeństwa Datastax wydaje się mieć świadomość lokalizacji danych.
+0

Podczas pracy z plikami dbs bez instrukcji SQL, pierwszym pytaniem, które należy zadać, jest pytanie: jakie zapytania należy wykonywać w odniesieniu do danych? – maasg

+0

Zrobiłem wystarczająco dużo badań na temat tego rodzaju rzeczy. Tak jak w przypadku strategii partycjonowania, unikaj tworzenia hot spotów, itp. –

+0

, więc jakie zapytania musisz uruchomić na zebranych danych? – maasg

Odpowiedz

7

Próbuję zrozumieć, co dokładnie dzieje się wewnętrznie w poziomie silnika przechowywania, gdy wiersz (kolumny) jest włożona w tabeli stylów CQL.

Powiedzmy, że mogę zbudować tabele z oboma swoimi klucze podstawowe i wstawić niektóre dane:

[email protected]:stackoverflow2> SELECT userid, time, dateof(time), category, subcategory, itemid, count, price FROM log_date1; 

userid | time         | dateof(time)    | category | subcategory | itemid   | count | price 
--------+--------------------------------------+--------------------------+----------+----------------+-------------------+-------+------- 
    1002 | e2f67ec0-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:48:20-0500 | Books |   Novels | 678-2-44398-312-9 |  1 | 798 
    1002 | 15d0fd20-f589-11e4-ade7-21b264d4c94d | 2015-05-08 08:49:45-0500 | Audio |  Headphones | 228-5-44343-344-5 |  1 | 4799 
    1001 | 32671010-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:43:23-0500 | Books | Computer Books | 978-1-78398-912-6 |  1 | 2200 
    1001 | 74ad4f70-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:45:14-0500 | Books |   Novels | 678-2-44398-312-9 |  1 | 798 
    1001 | a3e1f750-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:46:34-0500 | Books | Computer Books | 977-8-78998-466-4 |  1 | 599 

(5 rows) 
[email protected]:stackoverflow2> SELECT userid, time, dateof(time), category, subcategory, itemid, count, price FROM log_date2; 

userid | time         | dateof(time)    | category | subcategory | itemid   | count | price 
--------+--------------------------------------+--------------------------+----------+----------------+-------------------+-------+------- 
    1002 | e2f67ec0-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:48:20-0500 | Books |   Novels | 678-2-44398-312-9 |  1 | 798 
    1002 | 15d0fd20-f589-11e4-ade7-21b264d4c94d | 2015-05-08 08:49:45-0500 | Audio |  Headphones | 228-5-44343-344-5 |  1 | 4799 
    1001 | 32671010-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:43:23-0500 | Books | Computer Books | 978-1-78398-912-6 |  1 | 2200 
    1001 | 74ad4f70-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:45:14-0500 | Books |   Novels | 678-2-44398-312-9 |  1 | 798 
    1001 | a3e1f750-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:46:34-0500 | Books | Computer Books | 977-8-78998-466-4 |  1 | 599 

(5 rows) 

Wygląda prawie tak samo poprzez cqlsh. Warto więc spojrzeć z cassandra-cli i kwerendy wszystkie wiersze Foor userid 1002:

RowKey: 1002 
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:, value=, timestamp=1431092900008568) 
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:category, value=426f6f6b73, timestamp=1431092900008568) 
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:count, value=00000001, timestamp=1431092900008568) 
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:itemid, value=3637382d322d34343339382d3331322d39, timestamp=1431092900008568) 
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:price, value=0000031e, timestamp=1431092900008568) 
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:subcategory, value=4e6f76656c73, timestamp=1431092900008568) 
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:, value=, timestamp=1431092985326774) 
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:category, value=417564696f, timestamp=1431092985326774) 
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:count, value=00000001, timestamp=1431092985326774) 
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:itemid, value=3232382d352d34343334332d3334342d35, timestamp=1431092985326774) 
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:price, value=000012bf, timestamp=1431092985326774) 
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:subcategory, value=4865616470686f6e6573, timestamp=1431092985326774) 

dość proste, prawda? Postrzegamy userid 1002 jako RowKey, a naszą kolumnę skupiającą time jako klucz kolumny. Następnie są wszystkie nasze kolumny dla każdego klucza kolumny (time). I wierzę, że twoja pierwsza instancja generuje 6 kolumn, ponieważ jestem prawie pewien, że zawiera symbol zastępczy dla klucza kolumny, ponieważ twój klucz podstawowy może wskazywać na pustą wartość (jak robi to twój drugi przykładowy klucz).

Ale co z drugą wersją dla userid 1002?

RowKey: 1002 
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:Books:Novels:678-2-44398-312-9:1:798:, value=, timestamp=1431093011349994) 
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:Audio:Headphones:228-5-44343-344-5:1:4799:, value=, timestamp=1431093011360402) 

dwie kolumny są zawracane do RowKey 1002, po jednej dla każdego unikalnego połączeniu naszego kolumny (klasterów) klucze, z pustym wartości (jak wspomniano powyżej).

Co to wszystko oznacza dla Ciebie? Cóż, kilka rzeczy:

  • To powinno ci powiedzieć, że KLUCZE PIERWSZE w Cassandrze zapewniają wyjątkowość.Jeśli więc zdecydujesz, że musisz zaktualizować kluczowe wartości, takie jak category lub subcategory (drugi przykład), naprawdę nie można, chyba że USUNĄĆ i ponownie utworzyć wiersz. Chociaż z perspektywy logowania, to chyba w porządku.
  • Cassandra przechowuje wszystkie dane dla określonego klucza partycji/wiersza (userid) razem, posortowane według klucza (klastrowanie) kluczy. Jeśli obawiasz się zapytań i sortowania danych, ważne jest, aby zrozumieć, że musisz wykonać zapytanie dla każdego konkretnego userid dla porządku sortowania, aby wprowadzić jakąkolwiek różnicę.
  • Największym problemem, jaki widzę, jest to, że teraz ustawiasz się na nieograniczony wzrost kolumn. Klucze partycji/wiersza mogą obsługiwać maksymalnie 2 miliardy kolumn, więc Twój drugi przykład pomoże ci najbardziej. Jeśli uważasz, że niektóre z twoich userid s mogą przekroczyć to, możesz zaimplementować "datownik" jako dodatkowy klucz partycji (powiedzmy, gdybyś wiedział, że userid nigdy nie przekroczy 2 miliardy w ciągu roku, lub cokolwiek innego).

Wygląda na to, że druga opcja może być lepszym wyborem. Ale szczerze mówiąc za to, co robisz, każda z nich prawdopodobnie będzie dobrze działać.

+0

Dziękuję za długą szczegółową odpowiedź. Czy mogę prosić o jeszcze jedno? Czy uważasz, że druga opcja może być lepsza nawet po dodaniu klucza partycji kuponu daty do mojego schematu tabeli? –

+0

Czy możesz wskazać mi kod źródłowy, który zapisuje/ładuje kolumny kompozytowe do/z SSTable? –

+0

@WoojunKim Jedyną wadą dodającą wiadro daty do klucza partycji jest to, że musisz również wysłać to podczas zapytania. Ale ponieważ zapytania nie są dla ciebie główną troską, nie sądzę, że to naprawdę zaszkodzi obu scenariuszom. Jeśli chodzi o kod źródłowy, nie jestem pewien, gdzie jest ta część. Spróbuj przeszukać projekt na GitHub. – Aaron