48
Практика использования NoSQL в высоконагруженном проекте Ананьев Дмитрий "Мамба"

Практика использования NoSQL в высоконагруженном проекте (Дмитрий Ананьев)

  • Upload
    ontico

  • View
    3.974

  • Download
    0

Embed Size (px)

Citation preview

Практика использования NoSQL в

высоконагруженном проекте

Ананьев Дмитрий"Мамба"

Необходимость в NoSQL

Messenger

Сервис для ведения личной переписки

- MySQL- 45 серверов (шардинг)- 15 000 req/s- 350 req/s на один сервер в праймтайм

Messenger - счётчики сообщений- 27% запросов к MySQL - это счётчики- При каждой отправке/прочтении сообщений- Простые запросы:

1) UPDATE folder SET messages = messages + 1,

unread = unread + 1WHERE id = 4321;2) SELECT * FROM folder WHERE id = 4321;

Messenger - профиль нагрузки

Большой объём данных, но востребованные в конкретный момент данные составляют лишь малую часть.

- 18 000 000 пользователей- 150 000 онлайн- 700 сообщений/сек- В основном общаются только с онлайн пользователями

Варианты

memcache- не персистентный- ram-only

redis+ персистентный- ram-only

memcachedb+ персистентный+ не ограничен объёмом ram

tokyotyrant+ персистетный+ не ограничен объёмом ram

Варианты

memcache- не персистентный- ram-only

redis+ персистентный- ram-only

memcachedb+ персистентный+ не ограничен объёмом ram

tokyotyrant+ персистетный+ не ограничен объёмом ram

Варианты

memcache- не персистентный- ram-only

redis+ персистентный- ram-only

memcachedb+ персистентный+ не ограничен объёмом ram

tokyotyrant+ персистетный+ не ограничен объёмом ram

Тестирование - Brutis- простой- гибкий- много настроек- написан на PHP

- 30 серверов- 30 потоков на сервер- 30 минутРасчётная нагрузка (пример)

- 4 500 get/s- 1 600 inc/s- 200 байт - размер каждой записи- 90 000 000 записей

Brutis - как тестировали

Результаты тестирования

- memcachedb - при частой записи сильно нагружал

диск во время синка, в эти моменты его скорость снижалась в 100 раз

- tokyotyrant - 10 000 get/s- 5 000 set/s

Перекрёстная репликация

M

S

M

S

Sharding

Backup

disk 1

disk 2

RAID 1

Перекрёстная репликация

M

S

M

S

M

S

M

S

Необходимость в новом NoSQL

Выбор нового NoSQL решения

- MongoDB- CouchDB- Cassandra- HBase- HyperTable

- KyotoTycoon

KyotoTycoonОсновные отличия от TokyoTyrant:

- Консистентность данных при падении- Выше скорость- Меньшие накладные расходы на объём

- HTTP протокол вместо MEMCACHE- Расширенный интерфейс (HTTP), свои

функции, lua скрипты, плагины

Результаты тестов (random r/w)1 000 000 значений

- 150 000 записей/сек- 250 000 чтений/сек

1 000 000 000 значений- 15 000 записей/сек- 25 000 чтений/сек

Последовательная запись- при попытке записать 30 000 000 значений, производительность упала до 250 op/s

LevelDb

Алгоритмы1. SSTable: Sorted String Table

Особенности- ключи отсортированы- неизменяемые файлы

File key1 value1 key2 value2 ...

АлгоритмыSSTable: Sorted String Table

возможности:- быстрое последовательное чтение- быстрое случайное чтение при

использовании индексаIndex

key1 offset1

key2 offset2

...

SSTable: Sorted String Table- Для быстрой записи используются SSTable в оперативной памяти (назовём их MemTable)

- При чтении сначала проверяются индексы MemTable, а затем SSTable

Алгоритмы: LSM-tree

Тестовые данные

- 100M записей - объём базы- 100 байт - размер одной записи- 11 Гб - размер несжатых данных- 6.3 Гб - размер сжатых данных- 1 Гб - размер кеша- 16% - cache hit при случайном чтении

Результаты тестирования на 100М

Kyoto Tree 5 235 10 665 17 830 65 603

Kyoto Hash 35 368 28 437 24 500 668 896

LevelDB 104 373 15 331 473 484 2 652 519

Сетевой демон LevelDB

Что было реализовано- сетевое взаимодействие через tcp по

протоколу json-rpc с поддержкой асинхронных запросов

- репликация мастер-слейв

Сетевой демон LevelDB

Дополнительный функционал- inc_add- update_packed- get_range (по-умолчанию идут на slave)

Результаты

Запросы:- 4700 get/s (0.6ms) - 1600 update_packed/s (0.8ms) - 500 inc_add/s (0.7ms)

Размер базы:200 000 000 записей - в production.(2 000 000 000 - тестируется).

LevelDB: среднее время ответа во время слияния поддеревьев

GET запросы, от 0.5 мс до 1.4 мс

Утилизация диска во время слияния поддеревьевПоднимается до 25% (раз в 10 минут) и продолжается в течение 5 минут

Мониторинг

- Zabbix для железа- BTP для профилирования из PHPhttps://github.com/mambaru/btp-daemon

Итоги

MySQL TokyoTyrant

KyotoTycoon

LevelDB

Memcache

Спасибо за внимание!

Компания «Мамба»

Ананьев Дмитрий

[email protected]

4. Ссылки на используемые решения1) memcachedb http://memcachedb.org/2) tokyotyrant http://fallabs.com/tokyotyrant/3) brutis http://code.google.com/p/brutis/4) kyototycoon http://fallabs.com/kyototycoon/5) kyotocabinet http://fallabs.com/kyotocabinet/6) leveldb project http://code.google.com/p/leveldb/7) leveldb benchmarks http://leveldb.googlecode.com/svn/trunk/doc/benchmark.html8) SSTable and Log Structured Storage: LevelDB by Ilya Grigorik, 2012

http://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/9) The Log-Structured Merge-Tree (LSM-Tree) by Patrick O'Neil, 1996

http://nosqlsummer.org/paper/lsm-tree10) btp https://github.com/mambaru/btp-daemon11) zabbix http://www.zabbix.com/

Приложение: Тестирование производительности: 10M/kyoto./db_bench_tree_db --benchmarks=fillseq,fillrandom,readrandom,readseq --num=10000000 --cache_size=536870912

Kyoto Cabinet: version 1.2.76, lib ver 16, lib rev 13

Date: Tue Oct 16 12:12:59 2012

CPU: 8 * Intel(R) Xeon(R) CPU E5450 @ 3.00GHz

CPUCache: 6144 KB

Keys: 16 bytes each

Values: 100 bytes each (50 bytes after compression)

Entries: 10000000

RawSize: 1106.3 MB (estimated)

FileSize: 629.4 MB (estimated)

------------------------------------------------

fillseq : 5.667 micros/op; 19.5 MB/s - 176 460 op/s

fillrandom : 14.995 micros/op; 7.4 MB/s - 66 688 op/s

readrandom : 12.553 micros/op; - 79 662 op/s

readseq : 2.527 micros/op; 43.8 MB/s - 395 726 op/s

Приложение: Тестирование производительности: 10M/leveldb./db_bench --benchmarks=fillseq,fillrandom,readrandom,readseq --num=10000000 --bloom_bits=16 --write_buffer_size=536870912 --cache_size=536870912

LevelDB: version 1.6

Date: Tue Oct 16 15:46:23 2012

CPU: 8 * Intel(R) Xeon(R) CPU E5450 @ 3.00GHz

CPUCache: 6144 KB

Keys: 16 bytes each

Values: 100 bytes each (50 bytes after compression)

Entries: 10000000

RawSize: 1106.3 MB (estimated)

FileSize: 629.4 MB (estimated)

------------------------------------------------

fillseq : 2.062 micros/op; 53.6 MB/s - 484 966 op/s

fillrandom : 6.938 micros/op; 15.9 MB/s - 144 133 op/s

readrandom : 11.694 micros/op; - 85 513 op/s

readseq : 0.460 micros/op; 240.7 MB/s - 2 173 913 op/s

Приложение: Тестирование производительности: 100M/kyoto./db_bench_tree_db --benchmarks=fillseq,fillrandom,readrandom,readseq --num=100000000 --cache_size=1073741824

Kyoto Cabinet: version 1.2.76, lib ver 16, lib rev 13

Date: Thu Oct 18 03:37:24 2012

CPU: 8 * Intel(R) Xeon(R) CPU E5450 @ 3.00GHz

CPUCache: 6144 KB

Keys: 16 bytes each

Values: 100 bytes each (50 bytes after compression)

Entries: 100000000

RawSize: 11062.6 MB (estimated)

FileSize: 6294.3 MB (estimated)

------------------------------------------------

fillseq : 56.085 micros/op; 2.0 MB/s - 17 830 op/s

fillrandom : 191.021 micros/op; 0.6 MB/s - 5 235 op/s

readrandom : 93.764 micros/op; - 10 665 op/s

readseq : 15.243 micros/op; 7.3 MB/s - 65 603 op/s

Приложение: Тестирование производительности: 100M/leveldb./db_bench --benchmarks=fillseq,fillrandom,readrandom,readseq --num=100000000 --bloom_bits=16 --write_buffer_size=536870912 --cache_size=536870912 --threads=1

LevelDB: version 1.6

Date: Wed Oct 17 12:52:53 2012

CPU: 8 * Intel(R) Xeon(R) CPU E5450 @ 3.00GHz

CPUCache: 6144 KB

Keys: 16 bytes each

Values: 100 bytes each (50 bytes after compression)

Entries: 100000000

RawSize: 11062.6 MB (estimated)

FileSize: 6294.3 MB (estimated)

------------------------------------------------

fillseq : 2.112 micros/op; 52.4 MB/s - 473 484 op/s

fillrandom : 9.581 micros/op; 11.5 MB/s - 104 373 op/s

readrandom : 65.224 micros/op; - 15 331 op/s

readseq : 0.377 micros/op; 293.5 MB/s - 2 652 519 op/s

Приложение: Тестирование производительности: 100M/kch./db_bench_hash_db --benchmarks=fillseq,fillrandom,readrandom,readseq --num=100000000 --cache_size=1073741824

Kyoto Cabinet: version 1.2.76, lib ver 16, lib rev 13

Date: Wed Oct 17 15:39:47 2012

CPU: 8 * Intel(R) Xeon(R) CPU E5450 @ 3.00GHz

CPUCache: 6144 KB

Keys: 16 bytes each

Values: 100 bytes each (50 bytes after compression)

Entries: 100000000

RawSize: 11062.6 MB (estimated)

FileSize: 6294.3 MB (estimated)

------------------------------------------------

fillseq : 40.816 micros/op; 2.7 MB/s - 24 500 op/s

fillrandom : 28.274 micros/op; 3.9 MB/s - 35 368 op/s

readrandom : 35.165 micros/op; - 28 437 op/s

readseq : 1.495 micros/op; 74.0 MB/s - 668 896 op/s

Приложение: Тестирование производительности: 100M-8b/ldb./db_bench --benchmarks=fillseq,fillrandom,readrandom,readseq --num=100000000 --bloom_bits=16 --write_buffer_size=536870912 --cache_size=536870912 --threads=1 --value_size=8

LevelDB: version 1.6

Date: Wed Oct 17 12:06:13 2012

CPU: 8 * Intel(R) Xeon(R) CPU E5450 @ 3.00GHz

CPUCache: 6144 KB

Keys: 16 bytes each

Values: 8 bytes each (4 bytes after compression)

Entries: 100000000

RawSize: 2288.8 MB (estimated)

FileSize: 1907.3 MB (estimated)

------------------------------------------------

fillseq : 1.841 micros/op; 12.4 MB/s - 543 183 op/s

fillrandom : 6.920 micros/op; 3.3 MB/s - 144 508 op/s

readrandom : 16.701 micros/op; - 59 876 op/s

readseq : 0.257 micros/op; 89.1 MB/s - 3 891 050 op/s

Приложение: Тестирование производительности: 100M-8b/kch./db_bench_hash_db --benchmarks=fillseq,fillrandom,readrandom,readseq --num=100000000 --cache_size=1073741824 --value_size=8

Kyoto Cabinet: version 1.2.76, lib ver 16, lib rev 13

Date: Thu Oct 18 01:28:12 2012

CPU: 8 * Intel(R) Xeon(R) CPU E5450 @ 3.00GHz

CPUCache: 6144 KB

Keys: 16 bytes each

Values: 8 bytes each (4 bytes after compression)

Entries: 100000000

RawSize: 2288.8 MB (estimated)

FileSize: 1907.3 MB (estimated)

------------------------------------------------

fillseq : 30.118 micros/op; 0.8 MB/s - 33 202 op/s

fillrandom : 18.121 micros/op; 1.3 MB/s - 55 184 op/s

readrandom : 28.170 micros/op; - 35 498 op/s

readseq : 0.777 micros/op; 29.5 MB/s - 1 287 001 op/s

Приложение: Тестирование производительности: 100M-8b/kct./db_bench_tree_db --benchmarks=fillseq,fillrandom,readrandom,readseq --num=100000000 --cache_size=1073741824 --value_size=8

Kyoto Cabinet: version 1.2.76, lib ver 16, lib rev 13

Date: Thu Oct 18 13:34:22 2012

CPU: 8 * Intel(R) Xeon(R) CPU E5450 @ 3.00GHz

CPUCache: 6144 KB

Keys: 16 bytes each

Values: 8 bytes each (4 bytes after compression)

Entries: 100000000

RawSize: 2288.8 MB (estimated)

FileSize: 1907.3 MB (estimated)

------------------------------------------------

fillseq : 7.837 micros/op; 2.9 MB/s - 127 599 op/s

fillrandom : 28.302 micros/op; 0.8 MB/s - 35 333 op/s

readrandom : 25.374 micros/op; - 39 410 op/s

readseq : 1.837 micros/op; 12.5 MB/s - 544 365 op/s

Приложение: используемое железо

CPU: 2 * Xeon 3.0Ghz 6 coresRAM: 128GbHDD: RAID1 SAS (15Krpm) 300Gb

Приложние: оптимизация TokyoTyrant под высокую нагрузку

Параметры запуска TokyoTyrant- поддержка файлов больше 4 Гб (opts=l)- dbtype = hash table (*.tch)

- hash подходит для простого key/value- быстрее, чем btree (*.tcb)

- включена асинхронная запись на диск

Приложние: оптимизация Kyoto- Tycoon под высокую нагрузку

- Число потоков = число ядер - 1 (-th 11)- Hash table (*.kch)- Поддержка файлов больше 4 Гб (#opts=l)- Количество значений (#bnum=1000000000)- Кеш в ОЗУ (#msiz=10g)

Приложние: Оптимизация LevelDB под высокую нагрузку

Параметры оптимизации под высокую нагрузку:- число открытых файлов: 9 785 419 (fs.file-max = 9785419)- количество потоков:10 (--threads_tcp=10)- размер буфера записи: 128Мб (--buffer=128)- размер кеша: 40Гб (--memory=40960)