Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Opensource СУБД глазами обычного программиста

Opensource СУБД глазами обычного программиста

Попытался "быстренько" пробежаться по всем СУБД с которыми работал за 20 лет и постараться вложить слушателям мысль что СУБД надо выбирать под нагрузку
и что для СУБД надо знать "алгоритмы" и "эксплуатацию"
Видео тут https://www.youtube.com/watch?v=_je9o0Y03rs

Eugene Klimov

February 05, 2018
Tweet

More Decks by Eugene Klimov

Other Decks in Programming

Transcript

  1. С какими системами я работал OLTP SQL – MySQL, PostgreSQL,

    MSSQL, Firebird OLAP – MS OLAP (мало) Колоночные – Vertica, Clickhouse NoSQL – Redis (много), MongoDb (мало), Tarantool (очень мало)
  2. Что должен знать «обычный» программист про используемые СУБД Алгоритмы •Как

    БД «пишет», «хранит» и «читает» данные? •Под какой тип нагрузки оптимизирована БД? •Как обрабатывается конкурентный доступ к данным?
  3. Что должен знать «обычный» программист про используемые СУБД Эксплуатация •

    Насколько легко эту БД «мониторить» и «отлаживать»? • Насколько легко эту БД «обновлять»? • Насколько легко изменять «схему данных» в данной БД? • Насколько стабильны драйверы БД в вашем языке? • Как сделать горизонтальное масштабирование?
  4. Как БД «пишет», «хранит» и «читает» данные? MySQL, PostgreSQL –

    нагрузка OLTP • Запись mem buffer -> transaction log (innodblog, WAL) -> table space (innodbdata, base) • Хранение - «страницы» в них «строки (tuples)» (целиком) отдельные страницы для «индексов» отдельные страницы для «жирных столбцов» (BLOB, JSON, any extended storage) • Чтение - постранично в память, cache в памяти «для горячих данных» MySQL - innodb buffer pool + O_DIRECT Postgres – shared buffers + кеш средствами OS сортирует и фильтрует в одном ядре (почти всегда ;)
  5. Как БД «пишет», «хранит» и «читает» данные? Clickhouse – нагрузка

    OLAP • Запись «пишет пачками по XXX записей» сразу на диск входные данные в «большие» (1M на столбец) буфера в памяти и потом в каждый столбец отдельно, без transaction log • Хранение каждый столбец отдельно и сжато (zstd), нет дельта-кодирования для чисел (скоро будет), данные разбиты по «партициям» и «отсортированы по первичному ключу» (легче фильтровать), «новые данные» сливаются со старыми в фоновом режиме • Чтение - большими кусками последовательно, кеширует средствами OS, сортировка и группировка много ядер (потоки)
  6. Как БД «пишет», «хранит» и «читает» данные? Redis – in-memory

    OLTP • Запись каждая команда изменяющая данные (кроме PUBSUB) сразу в память и в AOF файл (если включен) • Чтение - Глобальная «хеш» таблица «читает» только из памяти • Хранение «хранит» AOF файл, либо > Fork -> Copy on write -> RDB файл • Есть disk based аналоги - http://ssdb.io/, https://github.com/yinqiwen/ardb
  7. Как БД «пишет», «хранит» и «читает» данные? MongoDb – OLTP

    schema less • Запись сначала в буфер в памяти -> паралельно WAL + Document Storage (сжатие) • Хранение «страницы» в них версии документов + «вторичные индексы» • Чтение - кеш в памяти (в памяти тоже сжатие) + файловый кеш OS
  8. Как обрабатывается конкурентный доступ к данным? MySQL – thread per

    connect (+отдельный accept thread) + storage thread pool PostgreSQL – process per connect (+ auto vacuum) ClickHouse – thread pool per connect Redis – single thread to all connection Mongodb – thread per connect
  9. Насколько легко эту БД «мониторить» и «отлаживать»? «Мониторить» легко в

    принципе всех, инструментов много Лично мой выбор это Prometheus Mongo + MySQL https://www.percona.com/software/database-tools/percona-monitoring-and- management PostgreSQL http://dalibo.github.io/powa/ Clickhouse https://github.com/f1yegor/clickhouse_exporter Redis https://github.com/oliver006/redis_exporter «Отлаживать» уже гораздо сложнее, но инструменты тоже есть УЧИТЕ EXPLAIN!!! MySQL Performance Schema PostgreSQL pg_stat_activity, pg_stat_statement Redis https://github.com/facebookarchive/redis-faina https://github.com/gamenet/redis-memory-analyzer Больше всего не хватает возможности через драйвер вставить место в коде где идет «вызов запроса»
  10. Насколько легко эту БД «обновлять»? Обновляться «сложно», но можно ;)

    Самое сложное обновлять все БД без «downtime» и без «dump/restore» да еще и желательно на одной машине MySQL – логическая репликация + mysql_upgrade PostgreSQL – pglogical + pg_upgrade Clickhouse – apt-get upgrade Redis – apt-get upgrade MongoDb – после 3.x версии apt-get upgrade сначала для secondary, потом primary нод, без ReplicaSet
  11. Насколько легко изменять «схему данных» в БД? • MySQL –

    pt-online-schema-change • PostgreSQL – CREATE INDEX CONCURENTLY + ALTER TABLE бесплатен для DEFAULT NULL • Redis – схему ключей надо менять руками • Clickhouse – ALTER TABLE бесплатен, но ограничен по функционалу • Mongodb – schema less из коробки, но схему документов все равно надо «дизайнить»
  12. Насколько стабильны драйверы БД в Python? Чтобы оценить обычно я

    иду в github для соответсвующего драйвера и смотрю issues и history В python с драйверами все хорошо ;) С багами в них тоже ;) • MySQL – MySQLdb, aiomysql • PostreSQL – psycodb2, aiopg • Clickhouse – clickhouse-driver, aioch • Redis – драйверов вагон ;) • MongoDb – pymongo
  13. Как сделать горизонтальное масштабирование? На самом деле ответ 42 или

    k8s ;) • MySQL – http://github.com/youtube/vitess/ • PostgreSQL – https://github.com/zalando/patroni • Clickhouse https://github.com/count0ru/k8s-clickhouse • Redis - https://github.com/sobotklp/kubernetes-redis-cluster • MongoDb – http://k8smongodb.net
  14. Грабли на которые наступал я - MySQL • row based

    репликация + mysql_upgrade + xtrabackup • Single Thread MySQL Replication – LAG • «сломанная репликация» при ротации binlog • GROUP BY упирающийся в одно ядро • Включайте innodb_file_per_table • Осторожнее с innodb_flush_log_at_trx_commit • Осторожнее с sort_buffer • Поймите что такое data cardinality и не пытайтесь мучить индекс ;)
  15. Грабли на которые наступал я - PostgreSQL • Ломается Streaming

    Replication – max_wal_size и replication slots • Autovacuum vs JSONB размером в 1Mb • Берегите pg_xlog также как base ;) • Wal-e + swift – восстановление в один поток • pgbouncer pause – «не савсем pause» • Patroni гибче чем repmgr • «Длинный SELECT» на standby - max_standby_streaming_delay один на всех • Учитесь правильно считать размер shared_buffers • GROUP BY в один поток
  16. Грабли на которые я наступал - Redis • Не допускайте

    ситуации когда «все ломятся в один ключ» • Не пытайтесь хранить больше 2-5kb на ключ • На 32G и выше лучше 4 ноды по 8Gb чем 1 по 32G • Пользуйтесь KEYS только в самом крайнем случае • Смотрите «сложность алгоритмов» в документации • PUBSUB – не очень эффективен по памяти, не пытайтесь через него гонять данные (чат), только id и не пиками • AOF может ломаться и это надо отдельно мониторить • Twemproxy и Codis – стоит присмотреться
  17. Грабли на которые я наступал в Clickhouse • Не работает

    с zetcd ;) https://github.com/yandex/ClickHouse/issues/777 • «Большие буфера» на вставку https://github.com/yandex/ClickHouse/issues/868 • Репликация «асинхронная», данные до некоторых реплик могут доехать не сразу • Float32, Float64 – это не numeric с фиксированной точностью https://github.com/yandex/ClickHouse/issues/1665
  18. Как выбрать СУБД? Прежде всего поймите какой у вас тип

    нагрузки в приложении! Могут быть разные типы нагрузки в разных частях приложения. Значит нужны РАЗНЫЕ СУБД! Ответьте на вопросы: Чего больше? Чтения или записи? При чтении данные должны быть актуальны? При чтении данные группируются? Сортируются? Фильтруются? Сколько данных читается за один запрос? Сколько данных пишется за один запрос? Как долго нам хватит диска по размеру? и т.д. и т.п.
  19. ORM vs Plain SQL • за «Object Mapping» приходится платить

    • IMHO Raw SQL просто надо сделать “prepared” и вынести в классы моделей
  20. Логика в Базе данных • В SQL сложную логику писать

    «не очень» и надо научиться «обновлять stored процедуры» • Но вот есть tarantool и там через Lua очень хорошо реализован hot reload lua кода • Для «чтения» есть Materialized View и Temporary Tables, но это «дорого» и может быть по Space и Write