cassandra design patterns

27
Cassandra. Patterns.

Upload: denis-gabaydulin

Post on 14-Apr-2017

273 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Cassandra design patterns

Cassandra. Patterns.

Page 2: Cassandra design patterns

Для кого докладДля разработчиков, которые уже знают что такое Cassandra, для чего она нужна и попробовали ее использовать.

Page 3: Cassandra design patterns

Cassandra. Internals.Cassandra имеет внутри структуру хранения, похожую на lsm tree + wal.Верхний уровень - memtable (sorted by row key, btree-like).Нижний уровень - disk (sstable + bloom filter).

Page 4: Cassandra design patterns

Cassandra. Java point of view.

SortedMap<RowKey, SortedMap<ColumnKey, ColumnValue>>

Page 5: Cassandra design patterns

Cassandra. Internals. Write path.

Page 6: Cassandra design patterns

Cassandra. Internals. Read path.

Page 7: Cassandra design patterns

Cassandra. Сильные стороны.Почти линейная масштабируемость

записи и чтенияНе нужно backup, все

восстанавливается на летуЕсть поддержка нескольких ДЦ

Настраиваемая модель (в терминах CAP)Стабильный продукт с первоклассным community

Page 8: Cassandra design patterns

Нет ACID транзакцийЧастое удаление данных это проблемаНет хороших secondary index** Индексы сейчас улучшаются:

https://github.com/xedin/sasi и CASSANDRA-10661)

Cassandra. Слабые стороны.

Page 9: Cassandra design patterns

ЛайкиCREATE TABLE LikedByObject( user_id bigint, object_id bigint, created bigint, PRIMARY KEY (object_id, user_id));

CREATE TABLE LikedByUser( user_id bigint, object_id bigint, created bigint, type_id int, PRIMARY KEY ((user_id, type_id), object_id));

Page 10: Cassandra design patterns

ЛайкиВыбрать всех кто лайкал объектselect * from LikedByObject where object_id = 42

Выбрать все что лайкал пользовательselect * from LikedByUser where user_id = 42 and type_id in (1, 2, 3)

Page 11: Cassandra design patterns

ЛайкиНет secondary index, используем materialized view. Почти всегда копирование данных более предпочтительно, так как самое затратное при чтении данных с диска это seek. Прочитать чуть больше данных, но из одного место быстрее, чем из двух.

Page 12: Cassandra design patterns

Уведомления

Page 13: Cassandra design patterns

УведомленияCREATE TABLE NotificationByUser ( user_id bigint, shard_part text, id timeuuid, type_id int, ..... PRIMARY KEY ((user_id, shard_part), id)) WITH CLUSTERING ORDER BY (id DESC);

CREATE TABLE NotificationByUserAndType ( ..... PRIMARY KEY ((user_id, type_id, shard_part), id)) WITH CLUSTERING ORDER BY (id DESC);

CREATE TABLE NotificationSeen ( user_id bigint, id timeuuid, value boolean, PRIMARY KEY (user_id, id)) WITH CLUSTERING ORDER BY (id DESC);

Page 14: Cassandra design patterns

УведомленияУведомления всегда отсортированы по времени события, к которому они относятся. Используем clustering order, чтобы данные физически хранились в нужном порядке.

Уведомления могут быть непросмотренные и просмотренные. Выделим мутабельную часть данных в отдельную cf. Это упрощает процесс обновления данных и API.

Page 15: Cassandra design patterns

УведомленияCREATE TABLE NotificationByUser ( user_id bigint, shard_part text, id timeuuid, type_id int, ..... PRIMARY KEY ((user_id, shard_part), id)) WITH CLUSTERING ORDER BY (id DESC);

У одного пользователя может быть очень много уведомлений. Таким образом у нас могут появится wide rows. Их нужно избегать (OOM, additional seeks, вот это вот все). Добавим в partition key дату.

Page 16: Cassandra design patterns

Partition keysКак правильно выбрать partition key?Распределение колонок внутри строки должно быть равномерным в идеале. В одной строке не должно быть слишком много данных (wide rows).

Варианты:Сам ключКлюч + timebased частьКлюч + partition (n of partitions fixed or any)

Page 17: Cassandra design patterns

Partition keysЛайки. У одного объекта очень редко бывает слишком много лайков. Object id хороший partition key.

Уведомления. У одного пользователя может быть очень много уведомлений, так как они накапливаются со временем. User id плохой partition key. Нужно добавить что-то еще. User id + date.Можно также сделать предположение, что уведомления более-менее распределены по дням равномерно, поэтому date подходит.

Page 18: Cassandra design patterns

Partition keysЛента постов по тегу.CREATE TABLE TagPosts (

tag text,partition int,post_id bigint,PRIMARY KEY((tag, partition), post_id)

) WITH CLUSTERING ORDER BY (post_id DESC);

Просто tag взять нельзя, потому что распределение имеет выбросы (тренды) и длинный хвост. Date плохая идея, так как хвост и тренды не зависят от даты.

Page 19: Cassandra design patterns

Partition keysНеестественное разбиение данных на любое количество partitions сложнее. При вставке нужно вычислять partition.

CREATE TABLE TagPostsPartitions (tag text,partition int,post_count counter,PRIMARY KEY (tag, partition)

) WITH CLUSTERING ORDER BY (partition DESC);

Page 20: Cassandra design patterns

Partition keysЕсли вы уверены, что кол-во данных по каждому ключу примерно одинаково, то вычисление partition может быть простым:

key % n partitions

Page 21: Cassandra design patterns

Partition keysВопрос: можно ли делать skinny partitions*?*skinny partition - в одной партиции одна строка

Ответ: да, если паттерн доступа random и нет range queries.

CREATE TABLE BlackList ( login text, created bigint, PRIMARY KEY (login));

Page 22: Cassandra design patterns

ВставкаИспользуйте batches, только если вам

действительно нужна атомарностьДля производительности используйте

асинхронные операции (в драйвере) с одиночными запросами*

*http://lostechies.com/ryansvihla/2014/08/28/cassandra-batch-loading-without-the-batch-keyword/

Page 23: Cassandra design patterns

УдалениеCREATE TABLE Queues ( queue_id bigint, enqueued timeuuid, PRIMARY KEY (queue_id, enqueued));

Классический anti-pattern!

Page 24: Cassandra design patterns

УдалениеКак и в любом log-structure engine, данные физически сразу не удаляются. Удаленные данные будут помечены, как tombstone, и через некоторое время (настраивается) будут физически удалены при очередном compaction.

Операция DELETE по ключу ввполняется за O(1).Операция выборки вида:select * from Queues where queue_id = 42 order by enqueued limit 1может выполняться за O(n).

Page 25: Cassandra design patterns

УдалениеДумайте про удаление заранееСтарайтесь удалять партиции целиком

Page 26: Cassandra design patterns

Избегайте RMWДелайте операции идемпотентными и

переписывайте данныеИспользуйте counter columnsИспользуйте транзакции осторожно, они

замедляют производительность и все равно не ACID

Page 27: Cassandra design patterns

Вопросыhttps://facebook.com/denis.gabaydulin (messanger)

[email protected]