93
Cassandra. Курс молодого бойца Никита Бурлаков, СКБ Контур

Cassandra:Курс молодого бойца

Embed Size (px)

Citation preview

Cassandra.Курс молодого

бойцаНикита Бурлаков, СКБ

Контур

План• Вводная

• Моделирование данных

• Архитектура кластера

• Примеры

• Грабли

За кадром• DevOps–Мониторинг– Настройка кластера– Утилиты обслуживания

• CQL– Уровень абстракции над внутренней

моделью– SQL-like

Историческая справка• Facebook Inbox Message Search• Написана на Java• 2008 – open source• 2017 – version 3.9

Характеристики• Нет единой точки отказа (мульти-

мастер)• Настраиваемая репликация (в т.ч.

между дата-центрами)• Линейная масштабируемость• Настраиваемая консистентность• Интеграция с Hadoop

Cassandra в Контур.Биллинге

• 2 кластера – 6 узлов и 3 узла• 64 GB памяти, используется ~17

GB• 2000 RPS на чтение, 1000 RPS на

запись• ~6 TB данных• Лучше железо, виртуалки – отстой• Всё под Linux

Модель данных SQL

Song Artist Album YearBank Holiday

Blur Parklife 1994

Tell Me Why

The Beatles

A Hard Day’s Night

1964

Go Robot Red Hot Chili Peppers

The Getaway 2016

Hells Bells AC/DC Back In Black 1980

Primary key

ColumnsTable

Rows

Модель данных Cassandra

Row key ColumnsColumn Family

Rows

Song Artist Album YearBank Holiday

Blur Parklife 1994

Tell Me Why

The Beatles

A Hard Day’s Night

1964

Go Robot Red Hot Chili Peppers

The Getaway 2016

Hells Bells AC/DC Back In Black 1980

Модель данных CassandraBank

HolidayArtist Album YearBlur Parklife 1994

The Beatles A Hard Day’s Night

1964

Red Hot Chili Peppers

The Getaway 2016

AC/DC Back In Black 1980

Tell Me Why

Go Robot

Hells Bells

Schema-lessBank

HolidayArtist Album YearBlur Parklife 1994

The Beatles A Hard Day’s Night

1964

Red Hot Chili Peppers

The Getaway 2016

AC/DC Back In Black 1980

Tell Me Why

Go Robot

Hells Bells

Структура колонки

• Метка времени (64-битное число)

• Можно управлять в приложении

• Нужен для разрешения конфликтов записи

Про Timestamp

Основные запросы

Основные запросы

Внутреннее хранилище

SSTables

CassandraNode

CommitLog

MemTable

Write

FlushCommit

Внутреннее хранилище

SSTable1

MemTable

Flush

Внутреннее хранилище

SSTable1

MemTable

Flush

SSTable2

Внутреннее хранилище

SSTable1

MemTable

Flush

SSTable2 SSTable3

Внутреннее хранилище

SSTable1 SSTable2

• Слишком много файлов

SSTable3 SSTable4

Внутреннее хранилище

SSTable1 SSTable2

• Compaction!

SSTable3 SSTable4

Внутреннее хранилище

SSTable12

SSTable34

Внутреннее хранилище

SSTables

CassandraNode MemTable

Read

Оптимизация чтения:

• Bloom Filter• Row Caches• Key Caches

Внутреннее хранилище• Быстрая запись

• Медленное чтение

• Свежие записи читаются из памяти (кэш)

• LSM-tree

Архитектура кластера

• Кольцо равных

[0, 5)

[5,15)

[15,25)

[25,35)

[35,50)

Client

• Распределение данных по строкам• Hash = 7

[0, 5)

[5,15)

[15,25)

[25,35)

[35,50)

Client

• Репликация (ReplicationFactor = 3)• Hash = 7

[0, 5)

[5,15)

[15,25)

[25,35)

[35,50)

Client

ОК, как быть с отказоустойчивостью?

• Сколько подтверждений нужно получить при операции– One– Two– Quorum– All

Consistency Level

Write (Quorum)

Координатор

Read (Quorum)

Побеждает больший Timestamp

Value = 42Timestamp = 10

Value = 1Timestamp = 3

Value = 42Timestamp = 10

Write (Quorum) - FAILED

NO ROLLBACK!!1

Какая настройка круче?• Зависит от сценария

• Строгая согласованность – R + W > RF

• Часто R = W = Quorum

Strong Consistency

Какая настройка круче?• Зависит от сценария

• Строгая согласованность – R + W > RF

• Часто R = W = Quorum

• Instagram: W = 2, R = 1

Восстановление данных

Read Repair

Value = 42Timestamp = 10

Value = 42Timestamp = 10

Value = 666Timestamp = 2

Hinted Handoff

Hinted Handoff

До трёх часов после отказа

Node Repair

Время проектировать!

Задачка №1Журнал

активностей

Почему Cassandra?• Часто пишем

• Редко читаем

• Читаем пачкой

ColumnName Valuetimestamp1:id1 action1timestamp2:id2 action2timestamp3:id3 action3

@BurlakovNick

Пацаны, вы не забыли про меня?

Сколько влезет в строчку?• 2 миллиарда колонок

• Или 2 GB данных

• Но на практике – порядки нескольких MB и миллионов строк

@BurlakovNick_2015

@BurlakovNick_2016

ColumnName Valuetimestamp1:id1

action1

timestamp2:id2

action2

timestamp3:id3

action3

Примеры из Контур.Биллинга

• Сервис истории

• Тарификация документооборота

Задачка №2Шина событий

Event Bus

Publisher

Subscriber Subscrib

er

Subscriber

ColumnName Valuetimestamp1:id1 event1timestamp2:id2 event2timestamp3:id3 event3

2016_09

timestamp4:id4 event4timestamp5:id5 event5timestamp6:id6 event6

2016_10

Сентябрь

2016_09

Сентябрь

Октябрь

Ноябрь

[Month]_1

Publisher

GetHashCode(Event) % N

[Month]_2

[Month]_N

[Month]_1

[Month]_2

[Month]_N

Reader_1

Reader_2

Reader_N

Subscriber Subscrib

er

Subscriber

Не изобретайте велосипед

Задачка №3Баланс клиента

• Какой баланс денег у клиента?

• Пополнения баланса

• Списания с баланса

ColumnName

Value

CurrentBalance

20$userId

BalanceService

currentBalance

Read Balance += value

Проблемы

Last Write Wins

Node 1

Balance=5

Value=5Timestamp

=42

Last Write Wins

Node 1 Node 2

Balance=5

Время на реплике отстало

Value=5Timestamp

=42

Value=666Timestamp

=10

Событийная модель

Снимки состояний (Snapshots) для быстрого восстановления состояния

ColumnName Valuetimestamp1:id1

20$

timestamp2:id2

-50$

timestamp3:id3

15$

userId

Задачка №4News Feed

ТвитыColumnName Valuetimestamp1:id1

tweet_1

timestamp2:id2

tweet_2

timestamp3:id3

tweet_3

userId_date

ПодпискиColumnName ValueuserId1 #userId2 #userId3 #

userId

SELECT *FROM Followers fJOIN Tweets t ON f.FollowId = t.UserIdWHERE f.UserId =

@BurlakovNickORDER BY t.Date

NewsFeed

UserId1 tweets

UserId2 tweets

UserId3 tweets

200 медленных чтений

Тяжелый JOIN в памяти

Денормализация

Храним ленту для каждого

пользователяColumnName Valuetimestamp1:id1

tweet_1

timestamp2:id2

tweet_2

timestamp3:id3

tweet_3

userId_date

NewTweet

UserId1 feed

UserId2 feed

UserId3 feed

Архитектурные компромиссы

Выводы• Хороший инструмент

…но не для всех задач

• Подумай о распределении данныхи нагрузки

• Используй неизменяемые события

• Денормализуй данные под запрос

Delete (Quorum)

Timestamp=3

Timestamp=3

Timestamp=3

Timestamp=5Tombstone!

Timestamp=5Tombstone!

Read (Quorum) – after delete

Timestamp=3

Timestamp=5Tombstone!

Timestamp=5Tombstone!

Timestamp=5Tombstone!

Спустя gc_grace_seconds

Read (Quorum) – after delete

Timestamp=3