- синхронна реплікація.
- аctive-active мульти-майстер топологія
- читання чи запис на будь-яку ноду кластеру.
- автоматичний контроль членів кластеру: проблемні члени будуть автоматично виключені з діючого кластеру.
- автоматичне (просте) додавання додаткових серверів до кластеру. Зручне масштабування.
- справжня паралельна реплікація, на рівні рядків.
Додам, що звичайна реплікація типу master-master не є синхронною. На активному майстрі всі запити спочатку будуть записані в binlog і лише потім будуть передані на інший пасивний MySQL-майстер (слейв), запити на пасивному сервері можуть виконуватись із значною затримкою. У випадку із Galera запити на кожній ноді виконуються одночасно, або майже одночасно.
MySQL/Galera кластер використовує бібліотеку Galera для реалізації реплікації, що працює через MySQL wsrep API (патчена версія MySQL)
Як я вже згадував Galera допускає запис на будь-яку ноду кластеру, навіть одночасні записи із різних нод в одну таблицю. Все це завдяки алгоритму сертифікації транзакцій:
Приведу приклад налаштування зв'язки haproxy+galera cluster.
Моє тестове середовище виглядає так:
Нода haproxy - це балансувальник, а gnode1, gnode2, gnode3 - ноди galera-кластеру.
Перш за все встановлюємо залежності для подальших установлень:
# apt-get install libaio1 libssl0.9.8 mysql-client libdbd-mysql-perl libdbi-perl
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libmysqlclient18 libnet-daemon-perl libplrpc-perl libterm-readkey-perl mysql-client-5.5 mysql-client-core-5.5 mysql-common
The following NEW packages will be installed:
libaio1 libdbd-mysql-perl libdbi-perl libmysqlclient18 libnet-daemon-perl libplrpc-perl libssl0.9.8 libterm-readkey-perl mysql-client mysql-client-5.5 mysql-client-core-5.5 mysql-common
0 upgraded, 12 newly installed, 0 to remove and 0 not upgraded.
Need to get 13.2 MB of archives.
After this operation, 46.7 MB of additional disk space will be used.
Do you want to continue [Y/n]?
Завантажуємо і встановлюємо galera та патчений mysql із wresp api:
# wget https://launchpad.net/codership-mysql/5.6/5.6.14-25.1/+download/mysql-server-wsrep-5.6.14-25.1-amd64.deb
# wget https://launchpad.net/galera/3.x/25.3.1/+download/galera-25.3.1-amd64.deb
# dpkg -i galera-25.3.1-amd64.deb mysql-server-wsrep-5.6.14-25.1-amd64.deb
Для завантаження останніх версій чи версій для RedHat-based дистрибутивів варто скористатись цими посиланнями:
https://launchpad.net/galera
https://launchpad.net/codership-mysql
https://launchpad.net/codership-maria
Після установки треба створити директорію для логів (схоже, це баг скачаної версії від Сodership):
# mkdir -pv /var/log/mysql
# chown mysql:mysql -R /var/log/mysql
Ще необхідно перевірити опцію 'bind-address' на кожному інстансі mysql, і прибрати її чи дозволити всі конекти.
Все вищесказане необхідно повторити для всіх машин майбутнього galera-кластеру.
Переходимо до конфігурації кластера. Правимо /etc/mysql/conf.d/wsrep.cnf на першому хосту gnode1 :
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://"
wsrep_sst_method=rsync_wan
wsrep_node_address=192.168.1.51
wsrep_provider - адреса бібліотеки, що забезпечує логіку роботи кластеру.
wsrep_cluster_address - адреса кластеру. Для його запуску спочатку параметр необхідно встановити в "gcomm://", проте в перспективі його необхідно замінити на список серверів, що входять до кластеру, щось на кшталт "gcomm://node1,node2,node3".
wsrep_node_address - ip-адреса інтерфейсу, котрий має слухати інстанс. Якщо не задати цей параметр - буде слухатись перший мережевий інтерфейс.
wsrep_sst_method - спосіб, використовуючи який буде відбуватись копія даних, у випадку, коли буде підключено додатковий сервер кластеру чи після довгого даунтайму одного із існуючих серверів. wsrep_sst_method може бути реалізований за допомогою rsync/rsync_wan (найшвидший варіант, дефолтне значення параметру), mysqldump (найповільніший) і xtrabackup. У випадку використання останніх двох варіантів - слід вказади також логін/пароль доступу до бази (параметр wsrep_sst_auth). Значення "wsrep_sst_method=xtrabackup" радить Percona http://www.percona.com/doc/percona-xtradb-cluster/5.5/howtos/ubuntu_howto.html як варіант, що не блокує донора на відміну двох інших.
Також корисна опція, про яку необхідно знати - це wsrep_sst_donor=node_name/ip. Описує хост, що буде використовуватись задля повного копіювання стану кластера, інакше хост-донор буде обиратись випадковим чином.
Про інші параметри можна прочитати тут.
На gnode2 та gnode3 нодах кластеру /etc/mysql/conf.d/wsrep.cnf має виглядати відповідно наступним чином:
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://192.168.1.51,192.168.1.52,192.168.1.53"
wsrep_sst_method=rsync_wan
wsrep_node_address=192.168.1.52
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://192.168.1.51,192.168.1.52,192.168.1.53"
wsrep_sst_method=rsync_wan
wsrep_node_address=192.168.1.53
Перезапускаємо mysql на всіх нодах кластеру.
Нарешті на першому сервері кластеру gnode1 замінюємо значення параметру wsrep_cluster_address="gcomm://" на wsrep_cluster_address="gcomm://192.168.1.51,192.168.1.52,192.168.1.53" і знову перезапускаємо mysql. Не лишайте заданий параметр пустим, адже інакше після кожного рестарту буде заново ініціалізуватись кластер!
Деякі статті пропонують в wsrep_cluster_address описувати лише один IP, інші - всі IP серверів, що будуть входити до кластеру. Як я розумію, різниці в цьому немає.
Перевіряємо стан кластеру переглядом змінних в mysql:
Тестуємо роботу кластеру: створимо базу та таблицю і заповнимо її даними:
mysql@gnode1> CREATE DATABASE `my_db`;
mysql@gnode2> use `my_db`;
mysql@gnode3> CREATE TABLE
`users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` CHAR(30) NOT NULL,
`age` SMALLINT(6) NOT NULL,
PRIMARY KEY(`id`)
);
mysql@gnode1> INSERT INTO my_db.users (`name`, `age`) VALUES
('John', 12),
('David', 18),
('Sasha', 16),
('Andrew', 20);
mysql@gnode2> SELECT * FROM my_db.users;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | John | 12 |
| 5 | David | 18 |
| 8 | Sasha | 16 |
| 11 | Andrew | 20 |
+----+--------+-----+
4 rows in set (0.00 sec)
Звертаю увагу, що mysql-інструкції для наявності були введені на різних серверах кластеру, що демонструє роботу реплікації.
Як я вже згадав, Galera дозволяє запис на будь-яку ноду кластеру причому навіть в одну таблицю, тому після його налаштування необхідно задуматись, як буде відбуватись балансування навантаження. Тут вже все залежить від файнтазії і потреб. Наприклад, я опишу варіант із Haproxy, проте можна також спробувати GLB (Galera Load Balancer daemon) чи MySQL Proxy та ін.
Спочатку додамо скрипт, що перевірятиме стан ноди в кластері, на основі якого haproxy прийматиме рішення щодо балансування. Ідея скрипта взята звідси і заснована вона на перевірці стану ноди в кластері. Сервер кластеру буде вважатись готовим до з'єднань, якщо змінна wsrep_local_state буде мати значення 4 (Synced). Опис станів гарно зображений тут.
Встановимо суперсервер xinetd на кожну із нод кластеру:
# sudo aptitude install xinetd
І скопіюємо скрипт такого вигляду:
# vim /etc/xinetd.d/mysqlchk
# default: on
# description: mysqlchk
service mysqlchk
{
# this is a config for xinetd, place it in /etc/xinetd.d/
disable = no
flags = REUSE
socket_type = stream
port = 9200
wait = no
user = nobody
server = /usr/bin/clustercheck
log_on_failure += USERID
only_from = 192.168.1.50
# recommended to put the IPs that need
# to connect exclusively (security purposes)
per_source = UNLIMITED
}
192.168.1.50 - IP-адреса ноди із майбутньою інсталяцією Haproxy. Заразервуємо tcp-порт 9200 (або інший, якщо цей зайнятий):
# vim /etc/services
mysqlchk 9200/tcp # mysqlchk
xinetd при зверненні на порт 9200 буде викликати перевірку, що реалізується скриптом /usr/bin/clustercheck (звісно, що його необхідно попередньо створити):
# vim /usr/bin/clustercheck
#!/bin/bash
MYSQL_HOST=localhost
MYSQL_USERNAME=clustercheckuser
MYSQL_PASSWORD=clustercheckpassword!
WSSREP_STATUS=$(/usr/bin/mysql --host=$MYSQL_HOST --user=$MYSQL_USERNAME --password=$MYSQL_PASSWORD -e "show status like 'wsrep_local_state';" | awk '{if (NR!=1){print $2}}' 2>/dev/null)
#
# Check the galera cluster consistent on node, your solution still allow connect to node even if cluster is desynced but mysql hear on 3306
#
if [ "$WSSREP_STATUS" == "4" ]
then
# mysql is fine, return http 200
/bin/echo -e "HTTP/1.1 200 OK\r\n"
/bin/echo -e "Content-Type: Content-Type: text/plain\r\n"
/bin/echo -e "\r\n"
/bin/echo -e "MySQL is running.\r\n"
/bin/echo -e "\r\n"
else
# mysql is fine, return http 503
/bin/echo -e "HTTP/1.1 503 Service Unavailable\r\n"
/bin/echo -e "Content-Type: Content-Type: text/plain\r\n"
/bin/echo -e "\r\n"
/bin/echo -e "MySQL is *down*.\r\n"
/bin/echo -e "\r\n"
fi
Додаємо права на запуск скрипту clustercheck створюємо додаткового read-only користувача для mysql та перезапускаємо xinetd:
# chmod +x /usr/bin/clustercheck
mysql> grant process on *.* to 'clustercheckuser'@'localhost' identified by 'clustercheckpassword!';
# service xinetd restart
Повторюсь, що додати вищезгаданий скрипт необхідно на кожну ноду galera-кластеру.
Наразі протестуємо роботу скрипту із майбутньої haproxy-ноди (ip ноди 192.168.1.50):
# telnet 192.168.1.53 9200
Trying 192.168.1.53...
Connected to 192.168.1.53.
Escape character is '^]'.
HTTP/1.1 200 OK
Content-Type: Content-Type: text/plain
MySQL is running.
Connection closed by foreign host.
Все добре, отже скрипт було додано вірно.
Налаштовуємо сам Haproxy. Встановлюємо його:
# apt-get install haproxy
Створюємо новий конфігураційний файл:
# mv /etc/haproxy/haproxy.cfg{,.original}
# vim /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 1024
user haproxy
group haproxy
daemon
#debug
#quiet
defaults
log global
mode http
retries 3
option redispatch dontlognull tcplog
maxconn 1024
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen mysql_cluster 0.0.0.0:3306
mode tcp
balance roundrobin
option httpchk
server gnode1 192.168.1.51:3306 check port 9200 inter 12000 rise 3 fall 3
server gnode2 192.168.1.52:3306 check port 9200 inter 12000 rise 3 fall 3
server gnode3 192.168.1.53:3306 check port 9200 inter 12000 rise 3 fall 3
roundrobin - один із найпростіших методів балансування і заключається він в тому, що кожен запит буде адресуватись кожній наступній ноді по порядку. Трішки більше про алгоритми балансування можна почитати тут.
Haproxy буде надсилати запит кожній із описаних нод, попередньо перевіривши http-код, який вона повертатиме на 9200 порту. Якщо код повернення буде 503 - нода буде виключена з пулу.
Перезапускаємо Haproxy і перевіряємо його роботу:
# mysql -uipeacocks-h192.168.1.50 -e "show variables like 'wsrep_node_name' ;"
+-----------------+--------+
| Variable_name | Value |
+-----------------+--------+
| wsrep_node_name | gnode1 |
+-----------------+--------+
# mysql -uipeacocks -h192.168.1.50 -e "show variables like 'wsrep_node_name' ;"
+-----------------+--------+
| Variable_name | Value |
+-----------------+--------+
| wsrep_node_name | gnode2 |
+-----------------+--------+
# mysql -uipeacocks -h192.168.1.50 -e "show variables like 'wsrep_node_name' ;"
+-----------------+--------+
| Variable_name | Value |
+-----------------+--------+
| wsrep_node_name | gnode3 |
+-----------------+--------+
root@haproxy:/etc/haproxy#
Зміна значень wsrep_node_name вказує на правильну роботу балансування запитів.
Звісно, що не слід забувати, що будь-яка технологія має свої недоліки.
Посилання:
Haproxy
http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
https://www.digitalocean.com/community/articles/how-to-use-haproxy-to-set-up-http-load-balancing-on-an-ubuntu-vps
http://habrahabr.ru/post/198448/
Galera
http://www.codership.com/wiki/doku.php?id=galera_wiki
http://www.percona.com/doc/percona-xtradb-cluster/5.5/howtos/ubuntu_howto.html
http://www.percona.com/doc/percona-xtradb-cluster/5.5/index.html
http://www.mysqlperformanceblog.com/2012/06/20/percona-xtradb-cluster-reference-architecture-with-haproxy/
http://www.sebastien-han.fr/blog/2012/04/01/mysql-multi-master-replication-with-galera/
http://getasysadmin.com/2013/03/how-to-setup-galera-3-node-cluster-on-ubuntu-12-04/
http://www.slideshare.net/henrikingo/introduction-to-galera
http://www.slideshare.net/Severalnines/galera-cluster-for-mysql-introduction-slides
http://planet.mysql.com/entry/?id=282416
Немає коментарів:
Дописати коментар