Франкенштейнизация Voldemort или key-value
данные в Одноклассниках

Роман Антипин
инженер-программист
проекта Одноклассники
2
Данные в Одноклассниках
•
•
•
•
•

SQL (MSSQL): ~ 330 серверов без учета backup, ~28 TB
Blob storage (OBS): ~ 460 серверов, ~1.5 PB
Column Family (Cassandra): ~ 410 серверов, ~70 TB
Key-Value (Voldemort): ~ 220 серверов, ~2.2 TB
Key-Value, Queue (Berkeley DB): ~100 серверов, ~1 TB

3 года назад:
• SQL (MSSQL)
• Key-Value, Queue (Berkeley DB)

3
CAP теорема

4
Развитие Key-Value хранилищ

5
Решение на основе Berkley DB

6
Недостатки решения с Berkley DB
•
•
•
•
•

Низкая отказоустойчивость (data corruption)
Ограничение в масштабируемости
Сложное обслуживание (ручная работа по восстановлению)
Высокая стоимость (много update => slave == backup)
Berkley DB 4.5 (Си) необходимо использовать JNI
– Пробовали Berkley DB 5.0 (Си) – снижение производительности

7
Требования к key-value хранилищу. Итерация 1

•
•
•
•
•
•

Open source
Высокая доступность, отказоустойчивость (data corruption)
Неограниченная масштабируемость без down time
Высокая производительность для отношения 3:R / 1:W
Возможность использования дешевого железа
Простота обслуживания (минимум ручной работы, только
для восстановления персистентных отказов оборудования)

8
Анализ существующих решений (2010 г.)
• Cassandra 0.6.4
–
–
–
–

Column Family
Поддерживает Hinted Handoff и Read-repair
Java
Нет механизма определения конфликтов (timestamp)

• Voldemort 0.8.1
–
–
–
–
–

Pluggable backend (default Berkley DB)
Поддерживает Read-repair
Механизм определения конфликтов (Vector Clock)
Java
Отсутствие Hinted Handoff

• Riak
– Сопоставим с Voldemort
– Erlang

9
Архитектура Voldemort

10
Vector clock

11
Tarantool как back end для Voldemort
• In-Memory NoSQL database
– Высокая производительность без деградации
– Ограничение по RAM

•
•
•
•
•
•
•

Персистентность за счет commit logs и snapshots
Поддержка вторичных индексов
Поддержка хранимых процедур на lua
Опыт использования в @mail.ru
Кооперативная многозадачность
Отсутствие embedded решения
Максимальный размер кортежа 1Мб

12
Исследование производительности
Тесты для кластера 3 ноды с replication factor 3, read/write quorum 2
Сервера SuperMicro 2 CPU(8 cores), RAM 32 Gb, 500 Gb SATA 7200.
Размер данных ~1-5Kb, объем данных 25Gb, read 50%, write 50%

• Voldemort 0.8.1 (BerkeleyDB java edition)
– Read: ~32K req/sec
– Write: ~7.5K req/sec

• Voldemort 0.8.1 (Tarantool)
– Read: ~36K req/sec
– Write: ~9K req/sec

13
Результаты использования Voldemort+Tarantool
•
•
•
•
•

Нет повреждений данных (data corruption)
Высокая доступность (устойчивость к падению любой ноды)
Масштабируемость без down time
Время старта кластера ~20 минут (объем ноды ~80G)
Необходимость ручной работы только в случае полного
восстановления ноды или расширения кластера
• Увеличение пропускной способности (throughput) в ~2 раза
• Увеличение среднего времени операций (latency) на ~50%
• Наличие небольшого количества повторных изменений

14
Примеры использования
Всего на данный момент запущено 25 кластеров
Service

Servers

Calls / calls
per node,
ops

Average
request
time

Average
data size

Cluster
size

Instantmessenger

24

600k / 26k

1.3ms

1.5kb

224G

Suggested

12

140k / 11k

1.5ms

22kb

584G

Black list

12

400k / 33k

1.1ms

0.6kb

20G

Music playlist

9

37k / 4k

0.9ms

1.4kb

90G

P.S: ping local DC ~150µs , cross DC ~500µs
15
Графики на примере сервиса сообщений

16
Требования к key-value хранилищу. Итерация 2

•
•
•
•
•

Избавиться от In-Memory ограничения
Увеличение производительности
Простая миграция на новое хранилище
Embedded storage engine
Желательно pure Java

17
Анализ решений на замену Tarantool
• Kyoto Cabinet 1.2.76
– Key-Value
– Различные типы storage (HashDB, TreeDB, …)
– C++

• LevelDB 1.9.0
– Key-Value
– Использует LSM Tree и SSTable
– C++

• Cassandra 0.6.4
– Column Family
– Использует LSM Tree и SSTable
– Java

18
Тестовая конфигурация
• Тестовый сервер
–
–
–
–
–
–

Intel Xeon CPU E5506 2.13GHz
RAM: 48Gb
Linux kernel: 2.6.34
HDD ST3500320NS (7200rpm 32Mb)
SSD INTEL SSDSA2CW300G3
File system: xfs rw, noatime, nodiratime, delaylog, noquota

• Тестовые данные
– 90M записей key – long , value – byte[1000]

19
Kyoto Cabinet 1.2.76
Параметры: HashDB, opts=TLINEAR, bnum=200M, msiz=30G, dfunit=8
60000

Insert data, 10 threads
50000

rps

40000

30000

20000

10000

0
0

1000

2000

3000

4000

5000

6000

7000

time
20
LevelDB 1.9.0
50000

Параметры конфигурации:

45000

•
•
•
•
•
•
•

40000

30000
25000
20000
15000
10000
5000
0
0

100

200

300

400
time

500

600

700

800
30000
25000

Параметры теста:
•
•
•
•

cache hit rate 90%
read threads 30
write threads 10
write unlimited

20000
read rps

write rps

35000

max_open_files=100K
block_size=4000 byte
write_buffer_size=512M
block_cache=LRUCache(30G)
filter_policy=NewBloomFilterPolicy(10)
logs - hdd, sstables – ssd,
увеличен размер L0

15000
10000
5000
0
0

100

200

300

400
time

500

600

700

21

800
LevelDB 1.9.0
14000
12000

8000
6000
4000
2000
0
0

50

100

150
time

200

250

300
45000
40000
35000

Параметры теста:
•
•
•
•

cache hit rate 90%
read threads 30
write threads 10
write limit 10K

30000
read rps

write rps

10000

25000
20000
15000
10000
5000
0
0

50

100

150
time

200

250

300

22
Cassandra 0.6.4
90000

Параметры конфигурации:

80000

•
•
•
•
•
•

70000

50000
40000
30000
20000
10000
0
0

150

300

450

600

750

900
40000

time

35000

Параметры теста:
•
•
•
•

cache hit rate 90%
read threads 30
write threads 10
write unlimited

30000
read rps

write rps

60000

RowsCached=15M
MemtableThroughputInMB=512
IndexInterval=128
CommitLogRotationThresholdMB=128
DiskAccessMode=mmap
logs - hdd, sstables – ssd

25000
20000
15000
10000
5000
0
0

150

300

450
time

600

750

23

900
Cassandra 0.6.4
25000

15000
10000
5000
0
0

50

100

150

200

250
70000

time

60000
50000

Параметры теста:
•
•
•
•

cache hit rate 90%
read threads 30
write threads 10
write limit 10K

read rps

write rps

20000

40000
30000
20000
10000
0
0

50

100

150
time

200

250

24
LSM Tree & SSTable

25
Интересные факты
• Не используем Cassandra cache
– Используем ConcurrentLinkedHashMap SECOND_CHANCE
– Производительность ConcurrentLinkedHashMap 1.4 LRU < ~50%
– В качестве Value MemoryWrapper через sun.misc.Unsafe

• Off heap allocation malloc (glibс 2.5) -> tcmalloc
– Отсутствие деградации
– Average allocation time ~ 800 ns против десятков µs

• Тюнинг linux по примеру LVS и HAProxy, снижение average
client time на ~30%

26
Результаты
•
•
•
•

Снято ограничение In-Memory
Embedded java storage
Возможность максимально использовать железо
Увеличение производительности
–
–
–
–

Instant-messenger (~1.5 kb данные) с одной ноды ~30K -> ~90K
Cache hit rate ~95%
Reads ~75K Writes ~15K
Сокращение количества серверов с 24 -> 12

• Cleanup без полного обхода, сохраняется информация о
tombstone на каждой ноде

27
Спасибо!
Контакты
http://habrahabr.ru/company/odnoklassniki/blog/
https://github.com/odnoklassniki/

roman.antipin@odnoklassniki.ru

http://v.ok.ru

Франкенштейнизация Voldemort или key-value данные в Одноклассниках. Роман Антипин