масштабирование баз данных
common sense
Евгений ШишкинDBA, wargaming.net
eshishki@gmail.com
— We define a DBMS as a complete software system used to define, create, manage, update and query a database.
© Gartner
БД общего назначения, OldSQL: MySQL, PostgreSQL
Специализированные, NewSQL: VoltDB, Vertica, Clustrix
NoSQL: HBase, Cassandra, CouchDB, Aerospark, MongoDB
Scalability is a function
Мы хотим добавить ресурсов и работать быстрее или обрабатывать больше.
- Amdahl's law
-
Gustafson-Barsis' Law
Neil J. Gunther's Universal Scalability Law
Amdahl's law
У нас есть алгоритм, который однопоточно работает за время T1.
Мы хотим добавить P процессоров и решить задачу быстрее.
Какое увеличение производительности S мы можем получить?
«В случае, когда задача разделяется на несколько частей, суммарное время её выполнения на параллельной системе не может быть меньше времени выполнения самого длинного фрагмента»
Amdahl's law
Ускорение ограничено той частью работы, которая не параллелизуется.
Например, если сериализованная часть алгоритма составляет только 0.1%, при 2048 процессорах ускорение будет только в 672 раза.
Gustafson-Barsis' Law
…speedup should be measured by scaling the problem to the number of processors, not by fixing the problem size.
— John Gustafson
В реальности, добившись нужного времени ответа системы, нас всё устраивает. И мы уже добавляем мощности под растущий размер, а не для сокращения латенси.
Gustafson-Barsis' Law
Если объем данных увеличивается вместе с увеличением числа процессоров, а сериализовання часть растет медленно или фиксирована, ускорение растет пропорционально росту ресурсов.
Я ничего не понял
Разница в том, хотите ли вы ускорения при той же нагрузке или того же времени ответа при увеличении нагрузки.
В реальной жизни больше применим закон Gustafson.
Но, если вам надо добиться более быстрой работы алгоритма при тех же данных, руководствуйтесь законом Амдала.
Так какая же база масштабируется лучше?
Масштабировать надо не базу, а сервис.
Бессмысленно рассматривать базу данных в отрыве от профиля нагрузки и приложения.
Масштабирование это специализация.
Базы данных общего назначения в общем случае не масштабируются.
UNIVERSAL SCALABILITY LAW
Cost of sharing resources
Diminishing returns from contention Negative returns from incoherency
|
|
|
|
|
Типичные профили нагрузки
- oltp
-
short-request processing
- web
- olap/dwh
oltp
-
буква T это транзакции - забыли nosql сразу же
- можно набить любимую базу данных до отказа памятью и ssd, но это будет печально и неэффективно
- как нам сделать 500k TPS на одном сервере? никак
- пошардили? добро пожаловать в дивный мир алгоритмов распределенного коммита
Почему всё так плохо работает? Вот redis же делает 200к на одном ядре!
OLTP
Прорывной ресерч H-Store http://hstore.cs.brown.edu/
Готовый продукт VoltDB
-
main memory database -> no buffer pool management
-
каждому cpu свой кусочек памяти и однопоточное выполнение -> нет локов
- вся работа в хранимых процедурах и куча ресерча ->
2pc иногда не нужен и во время ожидания можно выполнять другие транзакции
Подробнее тут http://hstore.cs.brown.edu/publications/
OLTP
Все основные сложности с распределенными транзакциями.
Рецепт - детерминизм.
Зная наперед в какой последовательности будут выполняться транзакции, у нас нет ожидания. База данных всегда делает полезную работу.
Подробности тут
http://cs.yale.edu/homes/thomson/publications/calvin-sigmod12.pdf
short-request
PK/Index lookup
Такая нагрузка масштабируется чем угодно.
Не надо быть семи пядей во лбу, чтобы пошардить PK
Речь об эффективности и удобстве.
MySQL делает 200k rps, PostgreSQL 120k rps.
Невероятно, но редкая nosql система покажет такие числа.
Есть Mysql Cluster (NDB, не галера), есть Postgres-xc.
NoSQL, которые AP, работают медленней CP.
WEB
-
short-request + joins + tons of order by + orm
- 95%+ чтения
- почти нет транзакций
- небольшой объем горячих данных
- data skew (zipfian distribution)
Нам хватает одного сервера, пока у него не кончается CPU.
MySQL Cluster, Postgres-xc, Pgpool и прочие шардят только по одному атрибуту.
WEB
Представьте себе табличку с постами
create table thread_posts (
post_id bigint,
thread_id bigint,
user_id bigint,
posted_on timestamp,
contents text,
primary key (thread_id, post_id),
key (user_id, posted_on)
);
И два популярных запроса:
select * from thread_posts where thread_id = 314 order by post_id;
select * from thread_posts where user_id = 546 order by posted_on desc limit 10;
Хочется пошардить и по thread_id, post_id и по user_id, posted_on
Выбирая только одно, далеко не уехать.
WEB
Нам надо:
- отправлять запросы только туда, где лежат наши данные
- избегать распределенных запросов
- балансировать нагрузку
Хороший способ:
- отвязать логическую схему от физической, чтобы шардить по разным атрибутам
- использовать consistent hashing для балансирования данных
- это сделано в Clustrix
WEB
Советики
чтобы избежать запросов на ноды, где данных нет
- lookup таблица
- bloom filter
-
можно шардить по двум атрибутам руками, делая две таблицы
- можно денормализовать, помня про update, delete аномалии
- можно материализовывать данные при записи (push модель) для сверхпопулярных пользователей (лента)
WEB
Если заморочиться
Проблема эффективного распределения данных по нодам это локальность данных и оверхед репликации данных.
Научный подход это положить данные вместе, не по хешу, а те, которые реально запрашиваются вместе.
- Schism: a Workload-Driven Approach to Database Replication and Partitioning
- The Little Engine(s) That Could: Scaling Online Social Networks
OLAP
-
огромный объем данных
- огромные выборки
- куча сортировок и джойнов
- однотипные репорты
- хорошо шардится
- хорошо сжимается
OLAP
Можно:
- пошардить руками
- взять postgres-xc, mysql cluster, любой автоматический шардинг
- и даже можно использовать materialized view (аля push)
- и можно даже что-то денормализовать
OLAP
Нужно:
1. хранить данные в колонках
- сжатие
- векторизованный процессинг
- эффективный доступ к данным
2. оперировать над сжатыми данными в памяти
3. делать row reconstructure только когда это необходимо
4. делать join индексы или prejoin проекции
5. хранить данные уже отсортированными (merge join бесплатный)
OLAP
Все эти "нужно" сделаны в Vertica.
Часть сделана в Cloudera Impala.
Greenplum не умеет column storage.
Oracle не умеет column storage.
NoSQL не умеет column storage.
DB2 и MSSQL умеют, но не MPP.
Половина NewSQL, которые про онлайн аналитику, это просто in memory базы. Очень часто даже без dictionary компрессии и RLE.
SQL vs NOSQL
Представьте себе nosql базу данных, которая
-
умеет secondary indexes
- умеет эффективно выполнять часть запросов у себя
- умеет транзакции
- дает гарантии, когда это необходимо
Боже мой, да это же RDBMS!
Выводы
-
Используйте нужную базу данных для своей нагрузки
- Не масштабируйте базу в отрыве от приложения
- Если вы знаете, как решить свою проблему NoSQL базой, значит вы знаете, как решить проблему и в RDBMS
- Не ленитесь думать и читать