SlideShare a Scribd company logo
Когда надо изобретать свой велосипед?
Строим NoSQL хранилище в приемлемые
сроки
Календарев Александр
Программист РБК-Медиа
akalend@mail.ru

2013

dev.it-portfolio.net
О чём доклад
-

о велосипедах
NoSQL
key/value хранилищах
это очень просто
Сделай сам

dev.it-portfolio.net

2
О велосипедах

dev.it-portfolio.net

3
О велосипедах

dev.it-portfolio.net

4
О велосипедах

dev.it-portfolio.net

5
О велосипедах
- Под конкретные условия местности свой
велосипед
- Велосипеды эволюционирует, как впрочем и
все на свете, в том числе системы хранения
данных
- Следовательно, всегда полезно думать над их
улучшением
- Значить, и стоит пытаться изобрести что-то
новое
dev.it-portfolio.net

6
О велосипедах
- Под конкретные условия местности свой
велосипед
- Велосипеды эволюционирует, как впрочем и
все на свете, в том числе системы хранения
данных
- Следовательно, всегда полезно думать над их
улучшением
- Значить, и стоит пытаться изобрести что-то
новое
- Или украсть идею и приспособить под свои
нужды
dev.it-portfolio.net

7
О велосипедах
- Может получиться

dev.it-portfolio.net

8
О велосипедах
- Может получиться
- А может и нет

dev.it-portfolio.net

9
О велосипедах
- Может получиться
- А может и нет
- Это как повезет

dev.it-portfolio.net

10
О велосипедах
- Может получиться
- А может и нет
- Но в любом случае Вы
всегда останетесь в
плюсе:
- получите новый опыт и
знание

dev.it-portfolio.net

11
О чём доклад
-

о велосипедах
NoSQL
key/value хранилищах
это очень просто
Сделай сам

dev.it-portfolio.net

12
NoSQL
- Термин озвучен 1991 Carlo Strozzi
- Carlo Strozzi 1998 представил ”NoSQL
RDBMS, Copyright (C)”, язык запросов 4GL
- 2009 на “Open Source” Конференции
применили этот термин ко всем
хранилищам, не относящимся к RDBMS

dev.it-portfolio.net

13
-

Документно-ориентированные БД
Key/value хранилища
Поколоночные БД
Графовые БД

Подробнее

http://nosql-database.org/

dev.it-portfolio.net

14
Документно-ориентированные
- Данные представлены в виде документов
- Форматы документы:
- XML: BerkeleyXML (XQuery), Sedna, Tamino (XQL)
- JSON/BSON: MondoDb(BSON), CoachDb(JSON)
- msgpack: Kumofs, tarantool 2.0

Рекомендуется использовать для слабо
структурированной информации

dev.it-portfolio.net

15
Key/value хранилища
Key-value хранилища запоминают и
извлекают документы по ключу.
Распределенные хеш-таблицы (DHT)
Пример: Riak, Voldemort, aerospike
Key/value хранилищa
Пример: Redis, Tokyo/Kyoto Tyrant , tarantool
1.5, MemcacheDb
dev.it-portfolio.net

16
Поколоночные БД
- Данные собраны в колонки и представляют
собой хеш таблицы.

dev.it-portfolio.net

17
Поколоночные БД
Преимущества:
- быстрая вставка,
- где документ представляем много колонок
- агрегирующие запросы в разы выше
Примеры: MonetDb, Accumulo, Vertica, Teradata
Недостаток: сложность загрузки данных
Cassandra, Hbase – не имеют поколоночную
модель данных (технология SSTAble)
dev.it-portfolio.net

18
Графовые БД
Данные в виде сетевой модели

Пример: Neo4, InfoGrid, GraphBase, DEX
dev.it-portfolio.net

19
NoSQL сравнение моделей хранения
key/value

RDBMS

документно-ориентированные

поколоночно-ориентированные

dev.it-portfolio.net

20
О чём доклад
-

о велосипедах
NoSQL
key/value хранилищах
это очень просто
Сделай сам

dev.it-portfolio.net

21
Key/Value Хранилище
- Index и Массива данных (bucket)
- Сетевой части
- Вспомогательных Tools :
- Конфигурация
- Репликация
- Мониторинг

dev.it-portfolio.net

22
Index + Bucket

dev.it-portfolio.net

23
Index
- Hash (хеш)
- Теоретически доступ/вставка за пост время: O(a)
- Поиск строго по ключу (операция равно).

- BTree (двоичное дерево)
- Поиск по диапазону
- Теоретически доступ за O(log2(n) ÷ n) или O(h)
- Удаление – очень дорого O(l *log2(n) )
Недостаток: разбалансировка
Разновидности: Btree+, AVL-Tree, RB-tree, 2-3-tree …
dev.it-portfolio.net

24
Hash таблица
f = crc32(key) % n

Хеш-функция:
crc32/64, md5, Jenkins,
Murmur

Масив данных [bucket]
для хранения

dev.it-portfolio.net

25
Hash таблица

Так как объем Банк
данных конечный, то
возможна коллизия:
Sabdra Dee & John
Smeet

dev.it-portfolio.net

26
Hash
Хеш таблицу характеризуют
– Ёмкость bucket
– Разреженность массива
– Длинна элемента массива
f = key % n

коллизия
Key 1

Хеш функция

Длинные
данные

Данные

Key 51

Данные

Key 2

Длинные данные . . . . . .
Длинные Данные часть II

dev.it-portfolio.net

27
О чём доклад
-

о велосипедах
NoSQL
key/value хранилищах
это очень просто , cделай сам

dev.it-portfolio.net

28
Что надо сделать?
- Понять требования
- Изучить существующие решения
- Найти подходящее API:
-

BerkeleyDb
dict, qhash,
Tokyo Cabinet
LevelDb
Sophia
dev.it-portfolio.net

29
Что надо сделать?
-

Понять требования
Изучить существующие решения
Найти подходящее API
Сделать тесты
Выбрать сетевую модель:
-

Однотредовая (corotine)/многотредовая модель
block/nonblock: select, poll, epoll, kqueue
libevent, libev (взять существующие библ.)
Найти готовый кусок кода
dev.it-portfolio.net

30
Что надо сделать?
-

Понять требования
Изучить существующие решения
Найти подходящее API
Сделать тесты
Выбрать сетевую часть
Определиться с протоколом.

dev.it-portfolio.net

31
О проекте
-

Служба знакомств
50 млн. анкет
25 млн. активных
25-90 тыс. сессий

dev.it-portfolio.net

32
О проекте (функциональная часть)
-

Просмотр и поиск анкет
Система сообщений
Голосовалки
Симпатии, Лайки
Сбор статистики
Геосервис : кто рядом.

dev.it-portfolio.net

33
Что хотелось хранить?
-

Результаты голосований
Лайки
Информация о просмотрах (счетчики)
Геоданные

dev.it-portfolio.net

34
Лайки, голосовалки, просмотры
Counter: 1

Alice

Кто : 01

Bob: 01

dev.it-portfolio.net

35
Лайки, голосовалки, просмотры
Counter: 2

Alice

Кто : 01, 02

Bob: 01
Carol : 02

dev.it-portfolio.net

36
Лайки, голосовалки, просмотры
Counter: 3

Alice

Кто : 01, 02, 05

Bob: 01
Carol : 02
Carlos : 05
dev.it-portfolio.net

37
Что хотелось?
- Простую функциональность:
- get(key)
- set(key)
- increment ( key )
- Кандидаты:
redis – можно использовать через Хеши
tarantool – удобный встроенный API (Lua)

dev.it-portfolio.net

38
Что хотелось?
- Простую функциональность;
get/set, Increment ( key1 , key2 )
- Персистентность
если упало, то данные не потерялись

dev.it-portfolio.net

39
Что хотелось?
- Простую функциональность
- Персистентность
- Что-то не сложное и быстрое
- не занимающее много места
- MongoDb такое же сложное, как MySQL

dev.it-portfolio.net

40
Что хотелось?
-

Простую функциональность:
Персистентность
Что-то не сложное
Не memory-only
- вдруг не хватит места:
- redis, tarantool не подходят
- Tokyo Tyrant – сложно реализовать лайки

dev.it-portfolio.net

41
Протокол
- Разработать свой
Преимущества: учтены все особенности

- Взять существующий
Преимущества: не нужно разрабатывать клиенты
Недостатки: необходимо расширение, доработка под
свои особенности

dev.it-portfolio.net

42
Протокол взять существующий
- Бинарный: protobuf, msgpack, memcached-bin,
Apache-thrift, Apache-Avro, BSON,…
компактнее, быстрее, сложнее отладка

- Текстовый: XML, JSON, memcached, redis, …
Проще отладка

Есть утилиты: telnet, nc, memget, redis-cli

dev.it-portfolio.net

43
Протокол memcached
-

GET ˽ [key] rn
SET ˽ [key] ˽ [flag] ˽ [expire] ˽ [bytes] rn
INCR ˽ [key] ˽ [value] ˽ [NOREPLAY] rn
DELETE ˽ [key] ˽ [NOREPLAY] rn
STATS rn
FLUSH_ALLrn

dev.it-portfolio.net

44
Расширяем протокол
- Добавляем новые служебные команды:
- FLUSH ˽ 1rn
- SHOW INIrn
- STAT CLEAR rn

- Расширяем существующие команды через
ключ:
- key: prefix.key[.subkey]
- Вводим понятие относительная адресация /
- Вводим понятие символьный вид #
dev.it-portfolio.net

45
Философия построения хранилища
- Используем понятие «Банк данных»
Банк данных – обособленный массив
данных, место для хранения (bucket)
- Разбиваем данные по функциональности:
лайки, голосования, просмотры
- Каждой сущности по своему банку.
- Номер банка определен префиксом ключа

dev.it-portfolio.net

46
Принцип построения хранилища
Номер банка определен префиксом ключа
Key prefix
32 bit

``

key
32 bit
Банк 1

GET 1.23456

Банк 2

GET 3.23456
GET 2.23456

Банк 3

dev.it-portfolio.net

47
Принцип построения хранилища
Номер банка определен префиксом ключа
Несколько банков могут быть объединены в
одну физическую хеш таблицу
(определяется конфигом)
Достоинство такого распределения:
• уменьшаем нагрузку на каждую хеш таблицу
• Шаг к масштабированию
• Распределение по типу использования

dev.it-portfolio.net

48
Типы банков
-

Бинарные данные
Символьные данные
Счетчики [4 байта]
«Индексные данные» на базе RB-tree
Индексные данные могут быть привязаны к
счетчикам
Привязка осуществляется в конфиге.

dev.it-portfolio.net

49
Реализация счетчика просмотров

Счетчики просмотров:
INCR ˽ 1.5 ˽ 1 rn
ключ анкеты = 5
SET˽ 1.5 ˽ 0 ˽ 0 ˽ 1 rn 0 rn
сброс
50
Реализация лайка
Alice
Bob:01

- Увеличение счетчика Алисы :
INCR ˽ 1.5 ˽ 1 rn
ключ Алисы = 5
- Добавляем в хеш Алисы ключ Боба:
SET ˽ 2.5.1 ˽0˽0˽1rn1rn ключ Боба = 1
dev.it-portfolio.net

51
Реализация лайка
Alice
Bob:01

Однако если расширить протокол:
INCR ˽ 2.5.1/1 ˽ 1 rn
key

Вместо двух обращений – одно.
dev.it-portfolio.net

52
Реализация лайка
- Вариант 1, как сортированный массив.
- Доступ за ln(n), n = 100 – 4 000 ( 7-14 шагов )
- Трудности с алгоритмом Garbage Collector.

- Вариант 2, используем Tree индекс
- Индекс составной 64 bit: key1 `` key2
32 bit

32 bit

- Выборка диапазона Key1 0x00 - Key1 0xFFFFFFFF

dev.it-portfolio.net

53
Расширяем протокол
Вводим понятие символьный вид #
Запомнили в символьном виде:
SET ˽ #1.5 ˽0˽0˽1rn1rn
GET ˽ #1.5 rn вернет символ “1” – 1 байт
GET ˽ 1.5 rn вернет int32: 0x1 – 4 байта
SET ˽ 1.5 ˽0˽0˽1rn1rn
GET ˽ 1.5 rn вернет int32: 0x31

Пригодится в отладке типа index
dev.it-portfolio.net

54
чистка мусора (garbage collector)
Удаленные профили
нужно удалять из хранилища
Требуется перебор всех данных
Делается, блоками, когда
процессор наименее загружен
Вычисляем загрузку сервиса,
Подбираем опытным путем.
dev.it-portfolio.net

55
Проблемы
- Удаленные профили надо чистить
- Постоянно растет память, нужно
сбрасывать кеш, переоткрывать таблицы
- Вывод: Необходим мониторинг

dev.it-portfolio.net

56
Мониторинг
- Команда stats
- Настраиваем rdd
- Рисуем графики

dev.it-portfolio.net

57
Мониторинг
- Память из /proc/self/mstat
- Производительность: кол-во запросов в сек
- Загрузка: отношение времени исполнения к
циклу измерения
- Размер корзины
- Общее кол-во ключей

dev.it-portfolio.net

58
Мониторинг

dev.it-portfolio.net

59
Тестирование
API покрыли тестами Схх http://cxxtest.com
Тестирование производительности:
aналог Apache ab, протокол memcached
https://github.com/akalend/mcstrass

dev.it-portfolio.net

60
Используемые Библиотеки
libev – сетевая однотредовая модель
libtokyocabinet – hashdb & treedb
tcmalloc - Memory pool allocator

dev.it-portfolio.net

61
Рекомендуемые Библиотеки
Сетевые:
libevent2 http://libevent.org/
libev
http://software.schmorp.de/pkg/libev.html

Коротины:
libcoro http://software.schmorp.de/pkg/libcoro.html
pcl
http://xmailserver.org/libpcl.html
libtask http://swtch.com/libtask/

dev.it-portfolio.net

62
Рекомендуемые Библиотеки
Хештаблицы:
Tokyo/Kyoto http://fallabs.com/ [cabinet]
libdict
https://github.com/fmela/libdic
strmap
http://pokristensson.com/strmap.html
sglib
http://sglib.sourceforge.net/
Judy
http://judy.sourceforge.net/
levelDb
http://code.google.com/p/leveldb/
Sophia
http://sphia.org/
uthash http://troydhanson.github.io/uthash/index.html
sunriseDb http://www.sunrisetel.net/software/devtools/sunrise-datadictionary.shtml
dev.it-portfolio.net

63
Рекомендуем почитать
Блог о высоких нагрузках
http://highloadblog.ru/
http://ru.wikipedia.org/wiki/Хеш-таблица
http://ru.wikipedia.org/wiki/B-дерево
Алгоритмы и структуры http://algolist.ru/
Опыт создания key/value хранилищ
СА сент,окт,нояб,дек 2012, март 2013.

dev.it-portfolio.net

64
Вопросы
Q:

Open Source ?

A:

в полной версии нет, не вижу смысла
есть прототип, который можно заточить под
любые нужды вашего проекта
https://github.com/akalend/mymc

dev.it-portfolio.net

65

More Related Content

PDF
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...
PDF
Велосипедостраительство в NoSQL, строим собственное NoSQL хранилище
PPT
Использование Sedna в WEB
PDF
Практика миграции реляционных баз данных в экосистему Hadoop
PDF
Александр Киров — Acronis — ICBDA 2015
PPTX
Александр Сербул —1С-Битрикс — ICBDA 2015
PDF
Где сегодня использовать ElasticSearch
PDF
Построение системы аналитики
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...
Велосипедостраительство в NoSQL, строим собственное NoSQL хранилище
Использование Sedna в WEB
Практика миграции реляционных баз данных в экосистему Hadoop
Александр Киров — Acronis — ICBDA 2015
Александр Сербул —1С-Битрикс — ICBDA 2015
Где сегодня использовать ElasticSearch
Построение системы аналитики

What's hot (20)

PDF
Инфраструктура Big data - от источников до быстрых витрин - версия для МИСиС
PPTX
Андрей Созыкин — ИММ УрО РАН — ICDBA2016
PPT
CodeFest 2012. Сапегин А. — Архитектура сайта Alawar.ru с учетом высоких нагр...
PDF
Выбор NoSQL базы данных для вашего проекта: "Не в свои сани не садись"
PPTX
Машинное обучение в электронной коммерции — практика использования и подводны...
PDF
Реактивный кэш в Android, Андрей Мельников, Rambler&Co, Москва
PPTX
Аналитическая инфраструктура оптимизации рекламной сети (Александр Зайцев)
PDF
Александр Соловьёв, Griddynamics.com
PPTX
BigПочта: как мы строили DataLake в Почте России / Алексей Вовченко (Luxoft)
PDF
Брокер сообщений Kafka в условиях повышенной нагрузки / Артём Выборнов (Rambl...
PPTX
Cервис рекомендаций на виртуальном Hadoop кластере (Роман Зыков)
PDF
Aлександр Зайцев, LifeStreet
PPTX
Lambda architecture для realtime-аналитики — риски и преимущества / Николай Г...
ODP
ClickHouse
PDF
Andrei Kirilenkov. Vertica
PDF
Применение в Enterprise-приложении графовой базы данных Neo4j - Антон Максимо...
PDF
NewSQL: SQL никуда не уходит / Константин Осипов (tarantool.org)
PPTX
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
PDF
High load++2016.highlights (dropbox+clickhouse)
PDF
Short Infrastructure Overview ru hpe Vertica
Инфраструктура Big data - от источников до быстрых витрин - версия для МИСиС
Андрей Созыкин — ИММ УрО РАН — ICDBA2016
CodeFest 2012. Сапегин А. — Архитектура сайта Alawar.ru с учетом высоких нагр...
Выбор NoSQL базы данных для вашего проекта: "Не в свои сани не садись"
Машинное обучение в электронной коммерции — практика использования и подводны...
Реактивный кэш в Android, Андрей Мельников, Rambler&Co, Москва
Аналитическая инфраструктура оптимизации рекламной сети (Александр Зайцев)
Александр Соловьёв, Griddynamics.com
BigПочта: как мы строили DataLake в Почте России / Алексей Вовченко (Luxoft)
Брокер сообщений Kafka в условиях повышенной нагрузки / Артём Выборнов (Rambl...
Cервис рекомендаций на виртуальном Hadoop кластере (Роман Зыков)
Aлександр Зайцев, LifeStreet
Lambda architecture для realtime-аналитики — риски и преимущества / Николай Г...
ClickHouse
Andrei Kirilenkov. Vertica
Применение в Enterprise-приложении графовой базы данных Neo4j - Антон Максимо...
NewSQL: SQL никуда не уходит / Константин Осипов (tarantool.org)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
High load++2016.highlights (dropbox+clickhouse)
Short Infrastructure Overview ru hpe Vertica
Ad

Viewers also liked (9)

PDF
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
PDF
Couchbase, что за зверь и на что способен.
PPTX
NoSQL - World IT Planet, Saint Petersburg 2015
PPT
Алексей Чумаков. Apache Cassandra на реальном проекте
PDF
Вадим Шашенко, 2ГИС
PPTX
MongoDB в продакшен - миф или реальность?
PDF
NoSQL thumbtack experience, Анатолий Никулин
PPTX
Преимущества NoSQL баз данных на примере MongoDB
PPTX
Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
Couchbase, что за зверь и на что способен.
NoSQL - World IT Planet, Saint Petersburg 2015
Алексей Чумаков. Apache Cassandra на реальном проекте
Вадим Шашенко, 2ГИС
MongoDB в продакшен - миф или реальность?
NoSQL thumbtack experience, Анатолий Никулин
Преимущества NoSQL баз данных на примере MongoDB
Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...
Ad

Similar to 16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим NoSQL хранилище в приемлемые сроки", Александр Календарёв (20)

PPTX
Daemons In Web on #devrus
PDF
2 bdw.key
PPTX
clickhouse final presentation covers basics
PPTX
20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...
PDF
Software Analytics in frontend
PPTX
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
PDF
Обзор перспективных баз данных для highload / Юрий Насретдинов
PDF
How to cook a blockchain and not get burned
PPTX
20 апреля, DEV {highload} - конференция о Highload веб-разработке, "Когда сто...
PPTX
Dev {highload}. When you should do your own db.
PDF
Сергей Чистович "Подходы к кешированию на UGC-сервисе"
PPTX
Oracle NoSQL Database
PDF
My Open Source (Sept 2017)
PDF
Наташа Арефьева — Семантика или смерть
PDF
Не все базы данных одинаково полезны
PDF
Выступление Сергея Аверина, Badoo, на High Performance Conference
PPT
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
PDF
Не все базы данных одинаково полезны
PDF
Денис Иванов
PPTX
Little Service in 2h
Daemons In Web on #devrus
2 bdw.key
clickhouse final presentation covers basics
20 апреля, DEV {highload}, "Демоны в большом проекте – проблемы и их решения ...
Software Analytics in frontend
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
Обзор перспективных баз данных для highload / Юрий Насретдинов
How to cook a blockchain and not get burned
20 апреля, DEV {highload} - конференция о Highload веб-разработке, "Когда сто...
Dev {highload}. When you should do your own db.
Сергей Чистович "Подходы к кешированию на UGC-сервисе"
Oracle NoSQL Database
My Open Source (Sept 2017)
Наташа Арефьева — Семантика или смерть
Не все базы данных одинаково полезны
Выступление Сергея Аверина, Badoo, на High Performance Conference
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
Не все базы данных одинаково полезны
Денис Иванов
Little Service in 2h

More from IT-Portfolio (9)

PDF
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Highload...
PPT
20 апреля, DEV {highload} - конференция о Highload веб-разработке, "Несколько...
PDF
20 апреля, DEV {highload} - конференция о Highload веб-разработке, "Шардинг в...
PDF
20 апреля, DEV {highload} - конференция о Highload веб-разработке, "Инженерны...
PPT
13 октября, DEV {web} - конференция о Highload веб-разработке. "Грабли при ма...
PDF
13 октября, DEV {web} - конференция о Highload веб-разработке. "Особенности р...
PDF
13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...
PPTX
13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...
PPT
13 октября, DEV {web} - конференция о Highload веб-разработке. "Архитектура п...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Highload...
20 апреля, DEV {highload} - конференция о Highload веб-разработке, "Несколько...
20 апреля, DEV {highload} - конференция о Highload веб-разработке, "Шардинг в...
20 апреля, DEV {highload} - конференция о Highload веб-разработке, "Инженерны...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Грабли при ма...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Особенности р...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Архитектура п...

16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим NoSQL хранилище в приемлемые сроки", Александр Календарёв

  • 1. Когда надо изобретать свой велосипед? Строим NoSQL хранилище в приемлемые сроки Календарев Александр Программист РБК-Медиа akalend@mail.ru 2013 dev.it-portfolio.net
  • 2. О чём доклад - о велосипедах NoSQL key/value хранилищах это очень просто Сделай сам dev.it-portfolio.net 2
  • 6. О велосипедах - Под конкретные условия местности свой велосипед - Велосипеды эволюционирует, как впрочем и все на свете, в том числе системы хранения данных - Следовательно, всегда полезно думать над их улучшением - Значить, и стоит пытаться изобрести что-то новое dev.it-portfolio.net 6
  • 7. О велосипедах - Под конкретные условия местности свой велосипед - Велосипеды эволюционирует, как впрочем и все на свете, в том числе системы хранения данных - Следовательно, всегда полезно думать над их улучшением - Значить, и стоит пытаться изобрести что-то новое - Или украсть идею и приспособить под свои нужды dev.it-portfolio.net 7
  • 8. О велосипедах - Может получиться dev.it-portfolio.net 8
  • 9. О велосипедах - Может получиться - А может и нет dev.it-portfolio.net 9
  • 10. О велосипедах - Может получиться - А может и нет - Это как повезет dev.it-portfolio.net 10
  • 11. О велосипедах - Может получиться - А может и нет - Но в любом случае Вы всегда останетесь в плюсе: - получите новый опыт и знание dev.it-portfolio.net 11
  • 12. О чём доклад - о велосипедах NoSQL key/value хранилищах это очень просто Сделай сам dev.it-portfolio.net 12
  • 13. NoSQL - Термин озвучен 1991 Carlo Strozzi - Carlo Strozzi 1998 представил ”NoSQL RDBMS, Copyright (C)”, язык запросов 4GL - 2009 на “Open Source” Конференции применили этот термин ко всем хранилищам, не относящимся к RDBMS dev.it-portfolio.net 13
  • 14. - Документно-ориентированные БД Key/value хранилища Поколоночные БД Графовые БД Подробнее http://nosql-database.org/ dev.it-portfolio.net 14
  • 15. Документно-ориентированные - Данные представлены в виде документов - Форматы документы: - XML: BerkeleyXML (XQuery), Sedna, Tamino (XQL) - JSON/BSON: MondoDb(BSON), CoachDb(JSON) - msgpack: Kumofs, tarantool 2.0 Рекомендуется использовать для слабо структурированной информации dev.it-portfolio.net 15
  • 16. Key/value хранилища Key-value хранилища запоминают и извлекают документы по ключу. Распределенные хеш-таблицы (DHT) Пример: Riak, Voldemort, aerospike Key/value хранилищa Пример: Redis, Tokyo/Kyoto Tyrant , tarantool 1.5, MemcacheDb dev.it-portfolio.net 16
  • 17. Поколоночные БД - Данные собраны в колонки и представляют собой хеш таблицы. dev.it-portfolio.net 17
  • 18. Поколоночные БД Преимущества: - быстрая вставка, - где документ представляем много колонок - агрегирующие запросы в разы выше Примеры: MonetDb, Accumulo, Vertica, Teradata Недостаток: сложность загрузки данных Cassandra, Hbase – не имеют поколоночную модель данных (технология SSTAble) dev.it-portfolio.net 18
  • 19. Графовые БД Данные в виде сетевой модели Пример: Neo4, InfoGrid, GraphBase, DEX dev.it-portfolio.net 19
  • 20. NoSQL сравнение моделей хранения key/value RDBMS документно-ориентированные поколоночно-ориентированные dev.it-portfolio.net 20
  • 21. О чём доклад - о велосипедах NoSQL key/value хранилищах это очень просто Сделай сам dev.it-portfolio.net 21
  • 22. Key/Value Хранилище - Index и Массива данных (bucket) - Сетевой части - Вспомогательных Tools : - Конфигурация - Репликация - Мониторинг dev.it-portfolio.net 22
  • 24. Index - Hash (хеш) - Теоретически доступ/вставка за пост время: O(a) - Поиск строго по ключу (операция равно). - BTree (двоичное дерево) - Поиск по диапазону - Теоретически доступ за O(log2(n) ÷ n) или O(h) - Удаление – очень дорого O(l *log2(n) ) Недостаток: разбалансировка Разновидности: Btree+, AVL-Tree, RB-tree, 2-3-tree … dev.it-portfolio.net 24
  • 25. Hash таблица f = crc32(key) % n Хеш-функция: crc32/64, md5, Jenkins, Murmur Масив данных [bucket] для хранения dev.it-portfolio.net 25
  • 26. Hash таблица Так как объем Банк данных конечный, то возможна коллизия: Sabdra Dee & John Smeet dev.it-portfolio.net 26
  • 27. Hash Хеш таблицу характеризуют – Ёмкость bucket – Разреженность массива – Длинна элемента массива f = key % n коллизия Key 1 Хеш функция Длинные данные Данные Key 51 Данные Key 2 Длинные данные . . . . . . Длинные Данные часть II dev.it-portfolio.net 27
  • 28. О чём доклад - о велосипедах NoSQL key/value хранилищах это очень просто , cделай сам dev.it-portfolio.net 28
  • 29. Что надо сделать? - Понять требования - Изучить существующие решения - Найти подходящее API: - BerkeleyDb dict, qhash, Tokyo Cabinet LevelDb Sophia dev.it-portfolio.net 29
  • 30. Что надо сделать? - Понять требования Изучить существующие решения Найти подходящее API Сделать тесты Выбрать сетевую модель: - Однотредовая (corotine)/многотредовая модель block/nonblock: select, poll, epoll, kqueue libevent, libev (взять существующие библ.) Найти готовый кусок кода dev.it-portfolio.net 30
  • 31. Что надо сделать? - Понять требования Изучить существующие решения Найти подходящее API Сделать тесты Выбрать сетевую часть Определиться с протоколом. dev.it-portfolio.net 31
  • 32. О проекте - Служба знакомств 50 млн. анкет 25 млн. активных 25-90 тыс. сессий dev.it-portfolio.net 32
  • 33. О проекте (функциональная часть) - Просмотр и поиск анкет Система сообщений Голосовалки Симпатии, Лайки Сбор статистики Геосервис : кто рядом. dev.it-portfolio.net 33
  • 34. Что хотелось хранить? - Результаты голосований Лайки Информация о просмотрах (счетчики) Геоданные dev.it-portfolio.net 34
  • 35. Лайки, голосовалки, просмотры Counter: 1 Alice Кто : 01 Bob: 01 dev.it-portfolio.net 35
  • 36. Лайки, голосовалки, просмотры Counter: 2 Alice Кто : 01, 02 Bob: 01 Carol : 02 dev.it-portfolio.net 36
  • 37. Лайки, голосовалки, просмотры Counter: 3 Alice Кто : 01, 02, 05 Bob: 01 Carol : 02 Carlos : 05 dev.it-portfolio.net 37
  • 38. Что хотелось? - Простую функциональность: - get(key) - set(key) - increment ( key ) - Кандидаты: redis – можно использовать через Хеши tarantool – удобный встроенный API (Lua) dev.it-portfolio.net 38
  • 39. Что хотелось? - Простую функциональность; get/set, Increment ( key1 , key2 ) - Персистентность если упало, то данные не потерялись dev.it-portfolio.net 39
  • 40. Что хотелось? - Простую функциональность - Персистентность - Что-то не сложное и быстрое - не занимающее много места - MongoDb такое же сложное, как MySQL dev.it-portfolio.net 40
  • 41. Что хотелось? - Простую функциональность: Персистентность Что-то не сложное Не memory-only - вдруг не хватит места: - redis, tarantool не подходят - Tokyo Tyrant – сложно реализовать лайки dev.it-portfolio.net 41
  • 42. Протокол - Разработать свой Преимущества: учтены все особенности - Взять существующий Преимущества: не нужно разрабатывать клиенты Недостатки: необходимо расширение, доработка под свои особенности dev.it-portfolio.net 42
  • 43. Протокол взять существующий - Бинарный: protobuf, msgpack, memcached-bin, Apache-thrift, Apache-Avro, BSON,… компактнее, быстрее, сложнее отладка - Текстовый: XML, JSON, memcached, redis, … Проще отладка Есть утилиты: telnet, nc, memget, redis-cli dev.it-portfolio.net 43
  • 44. Протокол memcached - GET ˽ [key] rn SET ˽ [key] ˽ [flag] ˽ [expire] ˽ [bytes] rn INCR ˽ [key] ˽ [value] ˽ [NOREPLAY] rn DELETE ˽ [key] ˽ [NOREPLAY] rn STATS rn FLUSH_ALLrn dev.it-portfolio.net 44
  • 45. Расширяем протокол - Добавляем новые служебные команды: - FLUSH ˽ 1rn - SHOW INIrn - STAT CLEAR rn - Расширяем существующие команды через ключ: - key: prefix.key[.subkey] - Вводим понятие относительная адресация / - Вводим понятие символьный вид # dev.it-portfolio.net 45
  • 46. Философия построения хранилища - Используем понятие «Банк данных» Банк данных – обособленный массив данных, место для хранения (bucket) - Разбиваем данные по функциональности: лайки, голосования, просмотры - Каждой сущности по своему банку. - Номер банка определен префиксом ключа dev.it-portfolio.net 46
  • 47. Принцип построения хранилища Номер банка определен префиксом ключа Key prefix 32 bit `` key 32 bit Банк 1 GET 1.23456 Банк 2 GET 3.23456 GET 2.23456 Банк 3 dev.it-portfolio.net 47
  • 48. Принцип построения хранилища Номер банка определен префиксом ключа Несколько банков могут быть объединены в одну физическую хеш таблицу (определяется конфигом) Достоинство такого распределения: • уменьшаем нагрузку на каждую хеш таблицу • Шаг к масштабированию • Распределение по типу использования dev.it-portfolio.net 48
  • 49. Типы банков - Бинарные данные Символьные данные Счетчики [4 байта] «Индексные данные» на базе RB-tree Индексные данные могут быть привязаны к счетчикам Привязка осуществляется в конфиге. dev.it-portfolio.net 49
  • 50. Реализация счетчика просмотров Счетчики просмотров: INCR ˽ 1.5 ˽ 1 rn ключ анкеты = 5 SET˽ 1.5 ˽ 0 ˽ 0 ˽ 1 rn 0 rn сброс 50
  • 51. Реализация лайка Alice Bob:01 - Увеличение счетчика Алисы : INCR ˽ 1.5 ˽ 1 rn ключ Алисы = 5 - Добавляем в хеш Алисы ключ Боба: SET ˽ 2.5.1 ˽0˽0˽1rn1rn ключ Боба = 1 dev.it-portfolio.net 51
  • 52. Реализация лайка Alice Bob:01 Однако если расширить протокол: INCR ˽ 2.5.1/1 ˽ 1 rn key Вместо двух обращений – одно. dev.it-portfolio.net 52
  • 53. Реализация лайка - Вариант 1, как сортированный массив. - Доступ за ln(n), n = 100 – 4 000 ( 7-14 шагов ) - Трудности с алгоритмом Garbage Collector. - Вариант 2, используем Tree индекс - Индекс составной 64 bit: key1 `` key2 32 bit 32 bit - Выборка диапазона Key1 0x00 - Key1 0xFFFFFFFF dev.it-portfolio.net 53
  • 54. Расширяем протокол Вводим понятие символьный вид # Запомнили в символьном виде: SET ˽ #1.5 ˽0˽0˽1rn1rn GET ˽ #1.5 rn вернет символ “1” – 1 байт GET ˽ 1.5 rn вернет int32: 0x1 – 4 байта SET ˽ 1.5 ˽0˽0˽1rn1rn GET ˽ 1.5 rn вернет int32: 0x31 Пригодится в отладке типа index dev.it-portfolio.net 54
  • 55. чистка мусора (garbage collector) Удаленные профили нужно удалять из хранилища Требуется перебор всех данных Делается, блоками, когда процессор наименее загружен Вычисляем загрузку сервиса, Подбираем опытным путем. dev.it-portfolio.net 55
  • 56. Проблемы - Удаленные профили надо чистить - Постоянно растет память, нужно сбрасывать кеш, переоткрывать таблицы - Вывод: Необходим мониторинг dev.it-portfolio.net 56
  • 57. Мониторинг - Команда stats - Настраиваем rdd - Рисуем графики dev.it-portfolio.net 57
  • 58. Мониторинг - Память из /proc/self/mstat - Производительность: кол-во запросов в сек - Загрузка: отношение времени исполнения к циклу измерения - Размер корзины - Общее кол-во ключей dev.it-portfolio.net 58
  • 60. Тестирование API покрыли тестами Схх http://cxxtest.com Тестирование производительности: aналог Apache ab, протокол memcached https://github.com/akalend/mcstrass dev.it-portfolio.net 60
  • 61. Используемые Библиотеки libev – сетевая однотредовая модель libtokyocabinet – hashdb & treedb tcmalloc - Memory pool allocator dev.it-portfolio.net 61
  • 62. Рекомендуемые Библиотеки Сетевые: libevent2 http://libevent.org/ libev http://software.schmorp.de/pkg/libev.html Коротины: libcoro http://software.schmorp.de/pkg/libcoro.html pcl http://xmailserver.org/libpcl.html libtask http://swtch.com/libtask/ dev.it-portfolio.net 62
  • 63. Рекомендуемые Библиотеки Хештаблицы: Tokyo/Kyoto http://fallabs.com/ [cabinet] libdict https://github.com/fmela/libdic strmap http://pokristensson.com/strmap.html sglib http://sglib.sourceforge.net/ Judy http://judy.sourceforge.net/ levelDb http://code.google.com/p/leveldb/ Sophia http://sphia.org/ uthash http://troydhanson.github.io/uthash/index.html sunriseDb http://www.sunrisetel.net/software/devtools/sunrise-datadictionary.shtml dev.it-portfolio.net 63
  • 64. Рекомендуем почитать Блог о высоких нагрузках http://highloadblog.ru/ http://ru.wikipedia.org/wiki/Хеш-таблица http://ru.wikipedia.org/wiki/B-дерево Алгоритмы и структуры http://algolist.ru/ Опыт создания key/value хранилищ СА сент,окт,нояб,дек 2012, март 2013. dev.it-portfolio.net 64
  • 65. Вопросы Q: Open Source ? A: в полной версии нет, не вижу смысла есть прототип, который можно заточить под любые нужды вашего проекта https://github.com/akalend/mymc dev.it-portfolio.net 65