Your SlideShare is downloading. ×
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassandra Conf 2013

896

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
896
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
17
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Моделирование данных с CQL3: типичные паттерны и анти-паттерны Aleksey Yeschenko
 Apache Cassandra Committer, Engineer @DataStax @AYeschenko
  • 2. Кто я такой • Backend Ruby web-dev (давно и неправда) • Telecom Erlang dev (недавно и правда) • Принуждают использовать Java+Python (cqlsh) в DataStax с июля 2012 • Apache Cassandra committer с ноября 2012 • @AYeschenko
  • 3. Когда использовать C* • Необходима Active-Active репликация между несколькими датацентрами • Необходим (около) 100% аптайм • Данные больше не умещаются в PostgreSQL/MySQL/etc. • PostgreSQL/MySQL/etc. больше не справляются с объёмом записи • Модель Cassandra изначально идеально подходит для приложения • Нет необходимости в ad-hoc запросах • Любое другое решение стоит $$$$$ * 1 и более пунктов из списка == true
  • 4. Когда не использовать C* • Во всех остальных случаях
  • 5. Как использовать, если использовать
  • 6. Корни С* Dynamo BigTable • http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html • http://research.google.com/archive/bigtable.html
  • 7. Как хранятся данные + терминология • Partition ключ и множество ячеек (до 2 миллиардов) • Хэш partition ключа определяет ноды, к которым принадлежит partition • Быстрое чтение по partition ключу • На диске и в памяти, ячейки всегда отсортированы по имени • Компаратор для сортировки задаётся пользователем 1 Имя ячейки 2 Миллиарда ... Имя ячейки Значение ячейки Значение ячейки Timestamp Timestamp TTL TTL Partition ключ
  • 8. Идеальная нагрузка • Запись доминирует • Перезапись/удаление ячеек отсутствуют или не очень часты • Чтение по ключу + (имени ячейки или небольшим отрезкам ячеек в порядке компаратора)
  • 9. Идеальная нагрузка • Логи • Данные с сенсоров • Финансовые данные (ticks) • Ads - клики и отображения, аналитика • Необязательно именно временные ряды (в порядке timestamp); любые данные, естественно упорядоченные по последовательному значению • Нужны последние N значений
  • 10. Паттерн #1: временной ряд
  • 11. Паттерн #1: временной ряд CREATE TABLE temperature ( weatherstation_id text, partition ключ event_time timestamp, кластеринговая колонка temp int, PRIMARY KEY (weatherstation_id, event_time) ) WITH CLUSTERING ORDER BY (event_time DESC); составной ключ обратный порядок сортировки ячеек • Каждая станция регулярно собирает показания • Один partition == одна станция • Одно показание == одна ячейка (здесь две, технически) • Потенциально очень широкий partition
  • 12. Паттерн #1: временной ряд CREATE TABLE temperature ( weatherstation_id text, partition ключ event_time timestamp, кластеринговая колонка temp int, PRIMARY KEY (weatherstation_id, event_time) составной ключ обратный порядок сортировки ячеек ) WITH CLUSTERING ORDER BY (event_time DESC); SVO weatherstation_id 1386475781 1386475781:temp 1386475780 1386475780:temp 1386475779 1386475779:temp … * -6 * event_time -6 * temp -5 … * маркеры CQL3 ряда
  • 13. Паттерн #1: временной ряд CREATE TABLE temperature ( weatherstation_id text, date text, составной partition ключ event_time timestamp, temp int, PRIMARY KEY ((weatherstation_id, date), event_time) ) WITH COMPACT STORAGE AND CLUSTERING ORDER BY (event_time DESC); • Один partition для пары {weatherstation_id, date} • Отсутствие оверхеда маркера ряда и имени колонки
  • 14. Паттерн #1: временной ряд CREATE TABLE temperature ( weatherstation_id text, date text, составной partition ключ event_time timestamp, temp int, PRIMARY KEY ((weatherstation_id, date), event_time) ) WITH COMPACT STORAGE AND CLUSTERING ORDER BY (event_time DESC); SVO:2013-12-09 1386475781 1386475780 1386475779 … -6 -6 -5 … date weatherstation_id timestamp temp
  • 15. Анти-паттерн #1: неуместное использование встроенных индексов • RDBMS опыт с индексацией НЕ переносится в C*
  • 16. Анти-паттерн #1: неуместное использование встроенных индексов • RDBMS опыт с индексацией НЕ переносится в C* • Встроенные индексы в C* != RDBMS индексы
  • 17. Анти-паттерн #1: неуместное использование встроенных индексов • RDBMS опыт с индексацией НЕ переносится в C* • Встроенные индексы в C* != RDBMS индексы • Встроенные индексы в C* != RDBMS индексы
  • 18. Анти-паттерн #1: неуместное использование встроенных индексов • RDBMS опыт с индексацией НЕ переносится в C* • Встроенные индексы в C* != RDBMS индексы • Встроенные индексы в C* != RDBMS индексы • Встроенные индексы в C* != RDBMS индексы
  • 19. Анти-паттерн #1: неуместное использование встроенных индексов • RDBMS опыт с индексацией НЕ переносится в C* • Встроенные индексы в C* != RDBMS индексы • Встроенные индексы в C* != RDBMS индексы • Встроенные индексы в C* != RDBMS индексы • Для удобства, не для улучшения производительности • Достаточно ограничены в плане удобства • Следует избегать, по большей части
  • 20. Анти-паттерн #1: неуместное использование встроенных индексов cqlsh:nope> CREATE TABLE users ( ... username varchar, ... email varchar, ... fullname varchar, ... last_login timestamp, ... PRIMARY KEY (username) ... ); ! cqlsh:nope> INSERT INTO users (username, email, fullname) VALUES ('ay', 'aleksey@datastax.com', 'Aleksey Yeschenko'); ! cqlsh:nope> SELECT * FROM users WHERE email = 'aleksey@datastax.com'; Bad Request: No indexed columns present in by-columns clause with Equal operator
  • 21. Анти-паттерн #1: неуместное использование встроенных индексов
  • 22. Анти-паттерн #1: неуместное использование встроенных индексов cqlsh:nope> CREATE INDEX ON users (email); ! cqlsh:nope> SELECT * FROM users WHERE email = 'aleksey@datastax.com'; username | email | fullname | last_login ----------+----------------------+-------------------+------------ ay | aleksey@datastax.com | Aleksey Yeschenko | ! (1 rows) null
  • 23. Анти-паттерн #1: неуместное использование встроенных индексов • При высокой и средней кардинальности колонки решается ‘ручным’ вторичным индексом • Отдельная таблица для обратного лукапа
  • 24. Анти-паттерн #1: неуместное использование встроенных индексов cqlsh:yep> CREATE TABLE users ( ... username varchar, ... email varchar, ... fullname varchar, ... last_login timestamp, ... PRIMARY KEY (username) ... ); cqlsh:yep> CREATE TABLE users_by_email_idx ( ... email varchar, ... username varchar, ... PRIMARY KEY (email, username) ... );
  • 25. Анти-паттерн #1: неуместное использование встроенных индексов cqlsh:yep> BEGIN BATCH ... INSERT INTO users (username, email, fullname) VALUES ('ay', 'aleksey@datastax.com', 'Aleksey Yeschenko'); ... INSERT INTO users_by_email_idx (email, username) VALUES ('aleksey@datastax.com', 'ay'); ... APPLY BATCH; ! cqlsh:yep> SELECT username FROM users_by_email_idx WHERE email = 'aleksey@datastax.com'; username ---------- ay ! cqlsh:yep> SELECT * FROM users WHERE username = 'ay'; username | email | fullname | last_login ----------+----------------------+-------------------+------------ ay | aleksey@datastax.com | Aleksey Yeschenko | null
  • 26. Анти-паттерн #1: неуместное использование встроенных индексов • При средней/низкой кардинальности свой, отдельный набор проблем • Главная - большое количество random i/o • Решается правильной моделью/денормализацией вместо использования встроенных индексов
  • 27. Анти-паттерн #1: неуместное использование встроенных индексов • Q: Когда вообще следует использовать встроенные индексы? • A: Для поиска рядов с 1+ кластеринговыми колонками внутри определённого partition (зная partition ключ)
  • 28. Анти-паттерн #1: неуместное использование встроенных индексов CREATE TABLE example ( partition_key varchar, clustering_col0 varchar, clustering_col1 varchar, val varchar ); ! CREATE INDEX ON example (val); ! SELECT * FROM example WHERE partition_key = ‘some_pk’ AND val = ‘some_val’;
  • 29. Анти-паттерн #1: неуместное использование встроенных индексов • Всё вышесказанное распространяется на индексы коллекций в 2.1 • Обращайтесь со встроенными индексами как с expert-level feature
  • 30. Паттерн #2: денормализация • Отношения без реляционности • Без использования foreign key CREATE TABLE users (! username varchar,! firstname varchar,! lastname varchar,! email varchar, ! PRIMARY KEY(username)! ); • Users 1-M Videos Users username firstname lastname email tcodd rboyce Edgar Raymond Codd Boyce videoid 99051fe9 videoname My funny cat b3a76c6b Math Videos tcodd@relational.com rboyce@relational.com username description tcodd My cat plays the pianodog Now my tcodd plays tags cats,piano,lol dogs,piano,lol CREATE TABLE videos (! videoid uuid,! videoname varchar,! username varchar,! description varchar, ! tags varchar,! upload_date timestamp,! PRIMARY KEY(videoid)! );
  • 31. Паттерн #2: денормализация • Лукап видео по username • Запись в две таблицы сразу • Без встроенных индексов CREATE TABLE username_video_index (! username varchar,! videoid uuid,! upload_date timestamp,! video_name varchar,! PRIMARY KEY (username, videoid)! ); SELECT video_name! FROM username_video_index! WHERE username = ‘ctodd’! AND videoid = ‘99051fe9’
  • 32. Паттерн #2: денормализация • Users 1-M Comments • Videos 1-M Comments • Без встроенных индексов Users username firstname lastname email tcodd rboyce Codd Boyce videoid 99051fe9 Edgar Raymond videoname My funny cat b3a76c6b Math Videos tcodd@relational.com rboyce@relational.com username description tcodd My cat plays the pianodog Now my tcodd plays tags cats,piano,lol dogs,piano,lol Comments username tcodd videoid 99051fe9 comment Sweet! rboyce b3a76c6b Boring :(
  • 33. Паттерн #2: денормализация • Две таблицы для выборки по видео и по пользователям • Запись в три таблицы сразу (comments, comments_by_video, comments_by_user) • Не жалеть запись CREATE TABLE comments_by_video (! videoid uuid,! username varchar,! comment_ts timestamp,! comment varchar,! PRIMARY KEY (videoid,username)! ); CREATE TABLE comments_by_user (! username varchar,! videoid uuid,! comment_ts timestamp,! comment varchar,! PRIMARY KEY (username,videoid)! );
  • 34. Анти-паттерн #2: очереди и очередеподобные нагрузки
  • 35. Анти-паттерн #2: очереди и очередеподобные нагрузки • Cassandra не лучшее решение для очередей • Можно, но требует гимнастики • Лучше использовать что-нибудь вроде Kafka/RabbitMQ • Любой паттерн, где в partition удаляются ячейки и выполняются slice сканы, включающие удалённые ячейки • Пример - нарочно упрощён, ради иллюстрации
  • 36. Анти-паттерн #2: очереди и очередеподобные нагрузки —— naive путь CREATE TABLE queues ( name text, enqueued_at timeuuid, payload blob, PRIMARY KEY (name, enqueued_at) —— ячейки упорядочены по времени вставки, ASC ) WITH COMPACT STORAGE;
  • 37. Анти-паттерн #2: очереди и очередеподобные нагрузки —— 1000x добавить в очередь: INSERT INTO queues (name, enqueued_at, payload) VALUES (‘queue-1’, now(), 0x…); ! —— 999x убрать из очереди, индивидуально: DELETE FROM queues WHERE name = ‘queue-1’ AND enqueued_at = ?; ! —— достать последний элемент из очереди: SELECT enqueued_at, payload FROM queues WHERE name = 'queue-1' LIMIT 1;
  • 38. Анти-паттерн #2: очереди и очередеподобные нагрузки queue-1 51c220e0-60… 58940a00-60.. 61163b30-60.. 995 x … X X X X 6e1ac030-60… ab36fa10-60.. X <some blob>
  • 39. Анти-паттерн #2: очереди и очередеподобные нагрузки activity | source | elapsed -------------------------------------------+-----------+-------- execute_cql3_query | 127.0.0.3 | 0 Message received from /127.0.0.3 | 127.0.0.1 | 42 Sending message to /127.0.0.1 | 127.0.0.3 | 718 Executing single-partition query on queues | 127.0.0.1 | 145 Acquiring sstable references | 127.0.0.1 | 158 Merging memtable contents | 127.0.0.1 | 189 Merging data from memtables and 0 sstables | 127.0.0.1 | 235 Read 1 live and 9999 tombstoned cells | 127.0.0.1 | 251102 Enqueuing response to /127.0.0.3 | 127.0.0.1 | 252976 Sending message to /127.0.0.3 | 127.0.0.1 | 253052 Message received from /127.0.0.1 | 127.0.0.3 | 324314 Processing response from /127.0.0.1 | 127.0.0.3 | 324535 Request complete | 127.0.0.3 | 324812
  • 40. Анти-паттерн #2: очереди и очередеподобные нагрузки • partition сканируется до тех пор пока LIMIT неудалённых ячеек не будет собран, или • пока не закончились ячейки в partition, или • пока не встретится ячейка вне заданных границ (если указано в where)
  • 41. Анти-паттерн #2: очереди и очередеподобные нагрузки —— зная последний удалённый элемент SELECT enqueued_at, payload FROM queues WHERE name = 'queue-1' AND enqueued_at > 6e1ac030-60b9-11e3-949a-0800200c9a66 LIMIT 1;
  • 42. Анти-паттерн #2: очереди и очередеподобные нагрузки queue-1 51c220e0-60… 58940a00-60.. 61163b30-60.. 995 x … X X X X 6e1ac030-60… ab36fa10-60.. X <some blob>
  • 43. Анти-паттерн #2: очереди и очередеподобные нагрузки activity | source | elapsed -------------------------------------------+-----------+-------- execute_cql3_query | 127.0.0.3 | 0 Sending message to /127.0.0.1 | 127.0.0.3 | 965 Message received from /127.0.0.3 | 127.0.0.1 | 34 Executing single-partition query on queues | 127.0.0.1 | 339 Acquiring sstable references | 127.0.0.1 | 355 Merging memtable contents | 127.0.0.1 | 461 Partition index lookup over for sstable 3 | 127.0.0.1 | 1122 Merging data from memtables and 1 sstables | 127.0.0.1 | 2268 Read 1 live and 0 tombstoned cells | 127.0.0.1 | 4404 Message received from /127.0.0.1 | 127.0.0.3 | 6109 Enqueuing response to /127.0.0.3 | 127.0.0.1 | 4492 Sending message to /127.0.0.3 | 127.0.0.1 | 4606 Processing response from /127.0.0.1 | 127.0.0.3 | 6608 Request complete | 127.0.0.3 | 6901
  • 44. Анти-паттерн #2: очереди и очередеподобные нагрузки • partitioning по дате • хинты для чтения • то же относится к TTL • худший сценарий - death by OOM • https://issues.apache.org/jira/browse/CASSANDRA-6117 (Avoid death-by-tombstone by default) 10k warning, 50k error • http://www.datastax.com/dev/blog/cassandra-anti-patternsqueues-and-queue-like-datasets
  • 45. Что дальше - вебинары по моделированию • http://youtu.be/px6U2n74q3g - The Data Model is Dead, Long Live the Data Model • http://youtu.be/qphhxujn5Es - Become a Super Modeler • http://youtu.be/T_WRC_GjRd0 - The World's Next Top Data Model • http://youtu.be/UP74jC1kM3w - Understanding How CQL3 Maps to Cassandra's Internal Data Structure
  • 46. Вопросы?

×