"Кластеры баз данных: делаем сложные вещи просто"...

47
Кластеры баз данных: делаем сложные вещи просто Андрей Тихонов [email protected] Avito.ru DevOps

Upload: avitotech

Post on 06-Jan-2017

233 views

Category:

Internet


2 download

TRANSCRIPT

Кластеры баз данных:делаем сложные вещи просто

Андрей Тихонов[email protected]

Avito.ru DevOps

Содержание

● Как начинается Highload?● Балансируем нагрузку на Backend● Методы масштабирования БД● Создаём кластер Redis/Memcached/Tarantool● Создаём кластер PostgreSQL

2/47

Немножко статистики Avito

● 1M+ запросов в минуту к Backend● 1Gb/s+ исходящий трафик (не считая картинки)● 100K+ запросов в секунду на nginx-балансеры● Терабайты или миллиарды картинок

3/47

Как начинается Highload?

Web-server Backend Database

5/47

Web-server Backend Database

Cache

6/47

Web-server Backend * Database

Cache

7/47

Web-server Backend * Database

CacheStorage Queue

8/47

Web-server * Backend * Database *

Cache *Storage * Queue *

9/47

Как работает Avito:

10/47

Балансируем нагрузку на Backend

12/47

nginx.conf:... location / { proxy_pass http://backend.local; }...

13/47

nginx.conf:...upstream backend { server backend01.local:80; server backend02.local:80; server backend03.local:80;}... location / { proxy_pass http://backend; }...

Методы масштабирования БД

15/47

Backend

Database

Read

Write

16/47

Backend

Read

Write

MasterSlave

Read

Replication

*репликация Master-Master здесь не рассматривается

Репликация Master-Slave

17/47

Backend

Read

Write

Shard02Shard01

Read

Write

Шардирование

Создаём кластер Redis/Memcached/Tarantool

Проблемы

19/47

● Установление подключения – долгая операция● Малый срок жизни подключения● Больше подключений – больше накладных

расходов на сервере

Решаем проблемы с помощью Twemproxy*

20/47

● Прозрачно проксирует на уровне протокола Memcached/Redis/Tarantool**

● Держит постоянное подключение к серверу● Устанавливает мало подключений к серверу

* см. также mcrouter, redis-proxy, redis-resharding-proxy, etc

** нужен патч

21/47

twemproxy-redis-single.yml:

alpha: listen: 127.0.0.1:22121 redis: true servers: - 127.0.0.1:6379:1

Шардируем с помощью Twemproxy

22/47

● Автоматическое шардирование● Поддерживает стойкое хэширование● Автоматически группирует и конвейеризует

запросы и ответы

23/47

twemproxy-redis-shard.yml:

beta: listen: 127.0.0.1:22122 redis: true distribution: ketama hash: murmur servers: - 127.0.0.1:6381:1 server1 - 127.0.0.1:6382:1 server2

Добавляем отказоустойчивость Redis-кластера

24/47

● Master-Slave Replication средствами Redis

Master-Slave Replication средствами Redis

25/47

redis.conf (slave side):

slaveof 192.168.10.1

Добавляем отказоустойчивость Redis-кластера

26/47

● Master-Slave Replication средствами Redis

Добавляем отказоустойчивость Redis-кластера

27/47

● Master-Slave Replication средствами Redis● Автоматическое переключение в случае отказа

мастера с помощью Redis Sentinel

Redis Sentinel

28/47

● Мониторит состояние всех нод кластера● Уведомляет об ошибках● Автоматически промотирует slave до master в случае

падения master● Выступает в качестве провайдера конфигурации

Redis Sentinel

29/47

redis-sentinel.conf:

sentinel monitor cluster01 192.168.10.1 6379 2sentinel down-after-milliseconds cluster01 60000sentinel failover-timeout cluster01 180000sentinel parallel-syncs cluster01 1

Добавляем отказоустойчивость Redis-кластера

30/47

● Master-Slave Replication средствами Redis● Автоматическое переключение в случае отказа

мастера с помощью Redis Sentinel

Добавляем отказоустойчивость Redis-кластера

31/47

● Master-Slave Replication средствами Redis● Автоматическое переключение в случае отказа

мастера с помощью Redis Sentinel● Прозрачное для клиента переключение с помощью

HAProxy

HAProxy

32/47

● TCP-прокси● Балансирует нагрузку разными алгоритмами

– Round-robin, least connections, first available, param* hash● Primary/backup группы backend-серверов● Различные способы проверки доступности серверов

– TCP connect, protocol* check, TCP send-expect

HAProxy

33/47

haproxy-redis.conf:

listen redis-cluster bind *:16379 option tcp-check balance roundrobin

tcp-check send PING\r\n tcp-check expect string +PONG tcp-check send info\ replication\r\n tcp-check expect string role:master tcp-check send QUIT\r\n tcp-check expect string +OK

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

Добавляем отказоустойчивость Redis-кластера

34/47

● Master-Slave Replication средствами Redis● Автоматическое переключение в случае отказа

мастера с помощью Redis Sentinel● Прозрачное для клиента переключение с помощью

HAProxy

35/47

Создаём кластер PostgreSQL

Проблемы

37/47

● Одно подключение – один процесс, создание процесса – дорогостоящая операция

● План запросов и т. п. кэшируется внутри процесса, новое подключение – пустой кэш

● Малый срок жизни подключения● Больше подключений – больше накладных

расходов на сервере

Решаем проблемы с помощью PgBouncer*

38/47

● Прозрачно проксирует на уровне протокола PgSQL

● Держит постоянное подключение к серверу● Выполняет запросы до и после подключения● Мультиплексирует клиентские подключения в

трёх режимах: session, transaction, statement pooling

* см. также PgPool

Решаем проблемы с помощью PgBouncer

39/47

pgbouncer.ini:

[databases]

main = host=db-main pool_size=5 connect_query='select prepare_statements_and_stuff()'

[pgbouncer]

pool_mode = transactionmax_client_conn = 1024

Синхронная и асинхронная репликация

40/47

Синхронная:● Надёжная● Медленная

Асинхронная:● Быстрая● Теряет ACID, так как слейвы отстают

Физическая и логическая репликация

41/47

Физическая:● Полная копия всех данных● Загружает I/O

Логическая:● Можно выбирать, какие данные копировать● Загружает CPU

Создаём MSR-кластер

42/47

1 master, 1 slave:● Распределяем нагрузку на чтение● Нет отказоустойчивости

1 master, 2+ slave:● Можем выдержать падение мастера

Создаём отдельную реплику для индексации

43/47

● Логическая репликация:

– Не вымывается кеш на мастере– Копируются только нужные данные

● Данные умещаются в RAM – нет медленного I/O

44/47

Шардируем с помощью PL/Proxy*

45/47

● Языковое расширение PostgreSQL● Устанавливается на одной прокси-ноде● Вся логика шардирования описывается в

хранимых процедурах PostgreSQL● Можно реализовать поддержку шард с MSR

* см. также Citus

46/47

Подведём итоги

47/47

● Много кратковременных подключений к серверу – плохо, используем прокси

● Нужна отказоустойчивость – используем Master-Slave Replication, делаем несколько слейвов

● Слейвы должны быть не слабее мастера● Данные не умещаются на одном сервере – шардируем на

несколько серверов● Все эти подходы можно комбинировать