Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)

1,419 views

Published on

Порой в процессе развития высоконагруженного проекта наступает момент, когда необходимо масштабирование. Возможно, ваш проект впервые упёрся в производительность железа (и таким образом перешёл в разряд высоконагруженных); возможно, это уже не первое масштабирование — не важно. Какие же проблемы могут возникнуть?

Во-первых, если вы увеличиваете количество бэкенд-серверов, и, соответственно, количество рабочих процессов, то с ростом количества одновременных клиентских подключений вырастают и накладные расходы на базах данных.
Во-вторых, достаточно быстро может кончиться ресурс in-memory баз данных. Потребуется создать (либо увеличить) кластер, а это каждый раз влечёт за собой необходимость модифицировать логику приложения.
В-третьих, чем больше серверов, тем больше вероятность, что один из них выйдет из строя. Поэтому неплохо задуматься о том, как обеспечить отказоустойчивость, а это, опять же, потребует модифицировать логику приложения.

В этом докладе я расскажу, как и какими инструментами можно легко решить все вышеперечисленные проблемы: уменьшить накладные расходы от большого количества подключений к базам данных, создать/модифицировать кластер БД прозрачно для приложения, а также прозрачно добавить устойчивость к падениям серверов БД.

План доклада:
- Введение. Методы масштабирования БД: репликация, шардирование.
- Создаём шардированные кластеры in-memory БД прозрачно для приложений: Twemproxy, Redis-proxy, Mcrouter.
- Уменьшаем накладные расходы от большого количества одновременных подключений на PostgreSQL с помощью PgBouncer.
- Создаём шардированный кластер PostgreSQL с помощью PL/Proxy.
- Добавляем прозрачную для приложения отказо�

Published in: Engineering
  • Be the first to comment

Кластеры баз данных делаем сложные вещи просто / Андрей Тихонов (Avito)

  1. 1. Кластеры баз данных: делаем сложные вещи просто Сиське! Андрей Тихонов atikhonov@avito.ru Avito.ru DevOps
  2. 2. Содержание ● Как начинается Highload? (6 слайдов) ● Балансируем нагрузку на Backend (2 слайда) ● Методы масштабирования БД (3 слайда) ● Создаём кластер Redis/Memcached/Tarantool (12 слайдов) ● Создаём кластер PostgreSQL (9 слайдов) 2/36
  3. 3. Немножко статистики Avito ● 1M+ запросов в минуту к Backend ● 1Gb/s+ исходящий трафик (не считая картинки) ● 100K+ запросов в секунду на nginx-балансеры ● Терабайты или миллиарды картинок 3/36
  4. 4. Как начинается Highload? Web-server Backend Database 4/36
  5. 5. Как начинается Highload? Web-server Backend Database Cache 5/36
  6. 6. Как начинается Highload? Web-server Backend * Database Cache 6/36
  7. 7. Как начинается Highload? Web-server Backend * Database CacheStorage Queue 7/36
  8. 8. Как начинается Highload? Web-server * Backend * Database * Cache *Storage * Queue * 8/36
  9. 9. Как начинается Highload? 9/36 Как работает Avito:
  10. 10. Балансируем нагрузку на Backend 10/36 nginx.conf: ... location / { proxy_pass http://backend.local; } ...
  11. 11. Балансируем нагрузку на Backend 11/36 nginx.conf: ... upstream backend { server backend01.local:80; server backend02.local:80; server backend03.local:80; } ... location / { proxy_pass http://backend; } ...
  12. 12. Методы масштабирования БД 12/36 Backend Database Read Write
  13. 13. Методы масштабирования БД: репликация 13/36 Backend Read Write MasterSlave Read Replication *репликация Master-Master здесь не рассматривается
  14. 14. Методы масштабирования БД: шардирование 14/36 Backend Read Write Shard02Shard01 Read Write
  15. 15. Создаём кластер Redis/Memcached/Tarantool 15/36 Проблемы: ● Установление подключения – долгая операция ● Срок жизни подключения – не дольше, чем работает скрипт ● Больше подключений – больше накладных расходов на сервере
  16. 16. Создаём кластер Redis/Memcached/Tarantool 16/36 Решаем проблемы с помощью Twemproxy: ● Прозрачно проксирует на уровне протокола Memcached/Redis/Tarantool* ● Держит постоянное подключение к серверу ● Устанавливает мало подключений к серверу, через них мультиплексирует много клиентских подключений * нужен патч
  17. 17. Создаём кластер Redis/Memcached/Tarantool 17/36 twemproxy-redis-single.yml: alpha: listen: 127.0.0.1:22121 redis: true auto_eject_hosts: true server_retry_timeout: 2000 server_failure_limit: 2 server_connections 1 servers: - 127.0.0.1:6379:1
  18. 18. Создаём кластер Redis/Memcached/Tarantool 18/36 Шардируем с помощью Twemproxy: ● Автоматическое шардирование ● Поддерживает стойкое хэширование ● Автоматически конвейеризует запросы и ответы
  19. 19. Создаём кластер Redis/Memcached/Tarantool 19/36 twemproxy-redis-shard.yml: beta: listen: 127.0.0.1:22122 redis: true distribution: ketama hash: fnv1a_64 auto_eject_hosts: false server_retry_timeout: 500 server_connections 1 servers: - 127.0.0.1:6381:1 server1 - 127.0.0.1:6382:1 server2
  20. 20. Создаём кластер Redis/Memcached/Tarantool 20/36 Добавляем отказоустойчивость Redis-кластера с помощью MSR, Sentinel и HAProxy: ● Master-Slave Replication средствами Redis ● Автоматическое переключение в случае отказа мастера с помощью Redis Sentinel ● Прозрачное для клиента переключение с помощью HAProxy
  21. 21. Создаём кластер Redis/Memcached/Tarantool 21/36 Master-Slave Replication средствами Redis: redis.conf (slave side): slaveof 192.168.10.1
  22. 22. Создаём кластер Redis/Memcached/Tarantool 22/36 Redis Sentinel ● Мониторит состояние всех нод кластера ● Уведомляет об ошибках ● Автоматически промотирует slave до master в случае падения master ● Выступает в качестве провайдера конфигурации
  23. 23. Создаём кластер Redis/Memcached/Tarantool 23/36 Redis Sentinel redis-sentinel.conf: sentinel monitor cluster01 192.168.10.1 6379 2 sentinel down-after-milliseconds cluster01 60000 sentinel failover-timeout cluster01 180000 sentinel parallel-syncs cluster01 1
  24. 24. Создаём кластер Redis/Memcached/Tarantool 24/36 HAProxy ● TCP-прокси ● Балансирует нагрузку разными алгоритмами – Round-robin, least connections, first available, param* hash ● Primary/backup группы backend-серверов ● Различные способы проверки доступности серверов – TCP connect, protocol* check, TCP send-expect
  25. 25. Создаём кластер Redis/Memcached/Tarantool 25/36 HAProxy haproxy-redis.conf: listen redis-cluster bind *:16379 mode tcp option tcpka option tcplog option tcp-check balance roundrobin server redis01 192.168.10.1:6379 check port 6379 check inter 2s server redis02 192.168.10.2:6379 check port 6379 check inter 2s tcp-check send PINGrn tcp-check expect string +PONG tcp-check send info replicationrn tcp-check expect string role:master tcp-check send QUITrn tcp-check expect string +OK
  26. 26. Создаём кластер Redis/Memcached/Tarantool 26/36
  27. 27. Создаём кластер PostgreSQL 27/36 Проблемы: ● Одно подключение – один процесс, создание процесса – дорогостоящая операция ● Больше подключений – больше накладных расходов на сервере ● План запросов и т. п. кэшируется внутри процесса, новое подключение – пустой кэш ● Срок жизни подключения – не дольше, чем работает скрипт
  28. 28. Создаём кластер PostgreSQL 28/36 Решаем проблемы с помощью PgBouncer: ● Прозрачно проксирует на уровне протокола PgSQL ● Держит постоянное подключение к серверу ● Мультиплексирует клиентские подключения в трёх режимах: session, transaction, statement pooling ● Выполняет запросы до и после подключения
  29. 29. Создаём кластер PostgreSQL 29/36 Решаем проблемы с помощью PgBouncer: pgbouncer.ini: [databases] main = host=db-main pool_size=5 connect_query= 'select prepare_statements_and_stuff()' [pgbouncer] listen_port = 6432 listen_addr = * pool_mode = transaction max_client_conn = 1024
  30. 30. Создаём кластер PostgreSQL 30/36 Синхронная и асинхронная репликация Синхронная: ● Мастер ждёт, пока все слейвы получат данные ● Надёжная, но медленная Асинхронная: ● Мастер отправляет данные в очередь и не ждёт ● Быстрая, но ненадёжная, теряет ACID, так как слейвы отстают
  31. 31. Создаём кластер PostgreSQL 31/36 Физическая и логическая репликация Физическая: ● Полная копия всех данных ● Загружает I/O Логическая: ● Можно выбирать, какие данные копировать ● Загружает CPU
  32. 32. Создаём кластер PostgreSQL 32/36 Создаём MSR-кластер 1 master, 1 slave: ● Распределяем нагрузку на чтение ● Нет отказоустойчивости 1 master, 2+ slave: ● Можем выдержать падение мастера
  33. 33. Создаём кластер PostgreSQL 33/36 Создаём отдельную реплику для индексации ● Не вымывается кеш на мастере ● С помощью логической репликации копируются только нужные данные ● Данные умещаются в RAM – нет медленного I/O
  34. 34. Создаём кластер PostgreSQL 34/36
  35. 35. Создаём кластер PostgreSQL 35/36 Шардируем с помощью PL/Proxy ● Языковое расширение PostgreSQL ● Устанавливается на одной прокси-ноде ● Вся логика шардирования описывается в хранимых процедурах PostgreSQL ● Можно реализовать поддержку шард с MSR
  36. 36. Подведём итоги 36/36 ● Много кратковременных подключений к серверу – плохо, используем прокси ● Нужна отказоустойчивость – используем Master-Slave Replication, делаем несколько слейвов ● Слейвы должны быть не слабее мастера ● Данные не умещаются на одном сервере – шардируем на несколько серверов ● Все эти подходы можно комбинировать

×