run-mysql-on-SSDs_centos_优化_002;Percona-XtraDB-Cluster
...
http://heylinux.com/archives/2785.html
Percona XtraDB Cluster 功能测试
参考资料:
http://www.mysqlperformanceblog.com/2013/09/23/percona-xtradb-cluster-setting-simple-cluster/
背景介绍:
在我们的生产环境,目前还采用的是单节点的Mater对应多个Slave节点;为了避免Master单点故障,需要尝试其它方案;
类似于通过Keepalived(VIP)或MySQL-Proxy等的方式,应用的比较多,如MySQL MMM;
由于线上采用了Percona Server,因为Manager更推荐采用 Percona 官方的Auto-Failover方式或者XtraDB Cluster的方式,Auto-Failover方式我在上一篇文章中已经讲过了。
因此,本章节主要讲解XtraDB Cluster的功能测试情况。
环境介绍:
servers: demoenv-trial-1 demoenv-trial-2 demoenv-trial-3
1. 安装 Percona Server,在所有服务器上:
$ sudo yum install http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
$ sudo yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install Percona-Server-shared-compat
$ sudo yum install Percona-Server-server-55 Percona-Server-client-55
2. 配置 /etc/my.cnf,在所有服务器上:
$ sudo vim /etc/my.cnf
01 |
[mysqld] |
02 |
# basic settings |
03 |
datadir = /opt/mysql/data |
04 |
tmpdir = /opt/mysql/tmp |
05 |
socket = /opt/mysql/run/mysqld.sock |
06 |
port = 3306 |
07 |
pid- file = /opt/mysql/run/mysqld.pid |
08 |
09 |
skip-external-locking |
10 |
max_allowed_packet = 16M |
11 |
12 |
# innodb settings |
13 |
default-storage-engine = INNODB |
14 |
innodb_file_per_table = 1 |
15 |
log-bin = /opt/mysql/binlogs/bin-log-mysqld |
16 |
log-bin-index = /opt/mysql/binlogs/bin-log-mysqld.index |
17 |
innodb_data_home_dir = /opt/mysql/data |
18 |
innodb_data_file_path = ibdata1:10M:autoextend |
19 |
innodb_log_group_home_dir = /opt/mysql/data |
20 |
binlog- do -db = testdb |
21 |
22 |
# server id |
23 |
server- id =1 |
24 |
25 |
# other settings |
26 |
[mysqld_safe] |
27 |
log-error = /opt/mysql/log/mysqld.log |
28 |
pid- file = /opt/mysql/run/mysqld.pid |
29 |
open -files-limit = 8192 |
30 |
31 |
[mysqlhotcopy] |
32 |
interactive-timeout |
33 |
34 |
[client] |
35 |
port = 3306 |
36 |
socket = /opt/mysql/run/mysqld.sock |
37 |
default-character- set = utf8 |
3. 创建所需目录,在所有服务器上:
$ sudo mkdir -p /opt/mysql/{data,tmp,run,binlogs,log}
$ sudo chown mysql:mysql /opt/mysql/{data,tmp,run,binlogs,log}
4. 初始化数据库,在所有服务器上:
$ sudo -i
# su - mysql
$ mysql_install_db --user=mysql --datadir=/opt/mysql/data/
$ exit
# exit
$ sudo /etc/init.d/mysql start
5. 删除原有软件包,在所有服务器上:
因为XtraDB Cluster的软件包与原有软件包冲突:
1 |
Error: Percona-XtraDB-Cluster-client conflicts with Percona-Server-client-55-5.5.34-rel32.0.591.rhel6.x86_64 |
2 |
Error: Percona-XtraDB-Cluster-server conflicts with Percona-Server-server-55-5.5.34-rel32.0.591.rhel6.x86_64 |
3 |
Error: Percona-XtraDB-Cluster-shared conflicts with Percona-Server-shared-55-5.5.34-rel32.0.591.rhel6.x86_64 |
$ sudo /etc/init.d/mysql stop
$ sudo rpm -qa | grep Percona-Server | grep -v compat | xargs sudo rpm -e --nodeps
6. 配置 /etc/my.cnf,添加 XtraDB Cluster 的支持,在所有服务器上:
注意,每台服务器需要将 wsrep_node_address 设置为本机的IP地址或主机名。
$ sudo vim /etc/my.cnf
01 |
[mysqld] |
02 |
# basic settings |
03 |
datadir = /opt/mysql/data |
04 |
tmpdir = /opt/mysql/tmp |
05 |
socket = /opt/mysql/run/mysqld.sock |
06 |
port = 3306 |
07 |
pid- file = /opt/mysql/run/mysqld.pid |
08 |
09 |
# innodb settings |
10 |
default-storage-engine = INNODB |
11 |
innodb_file_per_table = 1 |
12 |
log-bin = /opt/mysql/binlogs/bin-log-mysqld |
13 |
log-bin-index = /opt/mysql/binlogs/bin-log-mysqld.index |
14 |
innodb_data_home_dir = /opt/mysql/data |
15 |
innodb_data_file_path = ibdata1:10M:autoextend |
16 |
innodb_log_group_home_dir = /opt/mysql/data |
17 |
binlog- do -db = testdb |
18 |
19 |
# xtradb cluster settings |
20 |
binlog_format = ROW |
21 |
wsrep_cluster_name = mycluster |
22 |
wsrep_cluster_address = gcomm://demoenv-trial-1,demoenv-trial-2,demoenv-trial-3 |
23 |
wsrep_node_address = demoenv-trial-1 |
24 |
wsrep_provider = /usr/lib64/libgalera_smm.so |
25 |
wsrep_sst_method = xtrabackup |
26 |
wsrep_sst_auth = sst:secret |
27 |
innodb_locks_unsafe_for_binlog = 1 |
28 |
innodb_autoinc_lock_mode = 2 |
29 |
30 |
# server id |
31 |
server- id =1 |
32 |
33 |
# other settings |
34 |
[mysqld_safe] |
35 |
log-error = /opt/mysql/log/mysqld.log |
36 |
pid- file = /opt/mysql/run/mysqld.pid |
37 |
open -files-limit = 8192 |
38 |
39 |
[mysqlhotcopy] |
40 |
interactive-timeout |
41 |
42 |
[client] |
43 |
port = 3306 |
44 |
socket = /opt/mysql/run/mysqld.sock |
45 |
default-character- set = utf8 |
7. 安装 XtraDB Cluster,在所有服务器上:
$ sudo yum install Percona-Server-shared-compat
$ sudo yum install Percona-XtraDB-Cluster-server Percona-XtraDB-Cluster-client
8. 初始化第一个Node:
[dong.guo@demoenv-trial-1 ~]$ sudo service mysql bootstrap-pxc
1 |
Bootstrapping PXC (Percona XtraDB Cluster)Starting MySQL (Percona XtraDB Cluster).. SUCCESS! |
[dong.guo@demoenv-trial-1 ~]$ mysql -uroot
01 |
mysql> show global status like 'wsrep%' ; |
02 |
+----------------------------+--------------------------------------+ |
03 |
| Variable_name | Value | |
04 |
+----------------------------+--------------------------------------+ |
05 |
| wsrep_local_state_uuid | 5bff0df7-4e1d-11e3-82a1-2288fc08ae68 | |
06 |
| wsrep_protocol_version | 4 | |
07 |
| wsrep_last_committed | 0 | |
08 |
| wsrep_replicated | 0 | |
09 |
| wsrep_replicated_bytes | 0 | |
10 |
| wsrep_received | 2 | |
11 |
| wsrep_received_bytes | 146 | |
12 |
| wsrep_local_commits | 0 | |
13 |
| wsrep_local_cert_failures | 0 | |
14 |
| wsrep_local_bf_aborts | 0 | |
15 |
| wsrep_local_replays | 0 | |
16 |
| wsrep_local_send_queue | 0 | |
17 |
| wsrep_local_send_queue_avg | 0.000000 | |
18 |
| wsrep_local_recv_queue | 0 | |
19 |
| wsrep_local_recv_queue_avg | 0.000000 | |
20 |
| wsrep_flow_control_paused | 0.000000 | |
21 |
| wsrep_flow_control_sent | 0 | |
22 |
| wsrep_flow_control_recv | 0 | |
23 |
| wsrep_cert_deps_distance | 0.000000 | |
24 |
| wsrep_apply_oooe | 0.000000 | |
25 |
| wsrep_apply_oool | 0.000000 | |
26 |
| wsrep_apply_window | 0.000000 | |
27 |
| wsrep_commit_oooe | 0.000000 | |
28 |
| wsrep_commit_oool | 0.000000 | |
29 |
| wsrep_commit_window | 0.000000 | |
30 |
| wsrep_local_state | 4 | |
31 |
| wsrep_local_state_comment | Synced | |
32 |
| wsrep_cert_index_size | 0 | |
33 |
| wsrep_causal_reads | 0 | |
34 |
| wsrep_incoming_addresses | demoenv-trial-1:3306 | |
35 |
| wsrep_cluster_conf_id | 1 | |
36 |
| wsrep_cluster_size | 1 | |
37 |
| wsrep_cluster_state_uuid | 5bff0df7-4e1d-11e3-82a1-2288fc08ae68 | |
38 |
| wsrep_cluster_status | Primary | |
39 |
| wsrep_connected | ON | |
40 |
| wsrep_local_index | 0 | |
41 |
| wsrep_provider_name | Galera | |
42 |
| wsrep_provider_vendor | Codership Oy (info@codership.com) | |
43 |
| wsrep_provider_version | 2.8(r162) | |
44 |
| wsrep_ready | ON | |
45 |
+----------------------------+--------------------------------------+ |
参数 "wsrep_cluster_size" 为 1,因为目前Cluster中只有一个Node。
01 |
mysql> show databases; |
02 |
+--------------------+ |
03 |
| Database | |
04 |
+--------------------+ |
05 |
| information_schema | |
06 |
| mysql | |
07 |
| performance_schema | |
08 |
| test | |
09 |
+--------------------+ |
10 |
11 |
mysql> create database testdb; |
12 |
mysql> use testdb; |
13 |
Database changed |
14 |
mysql> CREATE TABLE `hostgroup` ( |
15 |
-> `hostgroup_id` tinyint(4) NOT NULL AUTO_INCREMENT, |
16 |
-> `hostgroup_name` char(20) DEFAULT NULL, |
17 |
-> `hostgroup_next` tinyint(4) NOT NULL, |
18 |
-> `colo_name` char(4) NOT NULL, |
19 |
-> PRIMARY KEY (`hostgroup_id`) |
20 |
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; |
21 |
22 |
mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'sst' @ 'localhost' IDENTIFIED BY 'secret' ; |
9. 添加新的 Node 到Cluster中:
[dong.guo@demoenv-trial-2 etc]$ sudo service mysql start
1 |
Starting MySQL (Percona XtraDB Cluster)....SST in progress, setting sleep higher |
2 |
.. SUCCESS! |
[dong.guo@demoenv-trial-2 etc]$ mysql -uroot
01 |
mysql> show databases; |
02 |
+--------------------+ |
03 |
| Database | |
04 |
+--------------------+ |
05 |
| information_schema | |
06 |
| mysql | |
07 |
| performance_schema | |
08 |
| test | |
09 |
| testdb | |
10 |
+--------------------+ |
11 |
12 |
mysql> use testdb; |
13 |
mysql> show tables; |
14 |
+------------------+ |
15 |
| Tables_in_testdb | |
16 |
+------------------+ |
17 |
| hostgroup | |
18 |
+------------------+ |
19 |
20 |
mysql> use mysql; |
21 |
mysql> select User,Password,Host,Grant_priv from mysql.user; |
22 |
+------+-------------------------------------------+-----------------+------------+ |
23 |
| User | Password | Host | Grant_priv | |
24 |
+------+-------------------------------------------+-----------------+------------+ |
25 |
| root | | localhost | Y | |
26 |
| root | | demoenv-trial-1 | Y | |
27 |
| root | | 127.0.0.1 | Y | |
28 |
| root | | ::1 | Y | |
29 |
| | | localhost | N | |
30 |
| | | demoenv-trial-1 | N | |
31 |
| sst | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | localhost | N | |
32 |
+------+-------------------------------------------+-----------------+------------+ |
可以发现 "binlog-do-db = testdb" 并未生效,新的节点同步了第一个节点的所有数据;
同理,server-id也就没有什么用了;
查看Cluster的状态:
01 |
mysql> show global status like 'wsrep%' ; |
02 |
+----------------------------+-------------------------------------------+ |
03 |
| Variable_name | Value | |
04 |
+----------------------------+-------------------------------------------+ |
05 |
| wsrep_local_state_uuid | 5bff0df7-4e1d-11e3-82a1-2288fc08ae68 | |
06 |
| wsrep_protocol_version | 4 | |
07 |
| wsrep_last_committed | 3 | |
08 |
| wsrep_replicated | 3 | |
09 |
| wsrep_replicated_bytes | 831 | |
10 |
| wsrep_received | 6 | |
11 |
| wsrep_received_bytes | 435 | |
12 |
| wsrep_local_commits | 0 | |
13 |
| wsrep_local_cert_failures | 0 | |
14 |
| wsrep_local_bf_aborts | 0 | |
15 |
| wsrep_local_replays | 0 | |
16 |
| wsrep_local_send_queue | 0 | |
17 |
| wsrep_local_send_queue_avg | 0.000000 | |
18 |
| wsrep_local_recv_queue | 0 | |
19 |
| wsrep_local_recv_queue_avg | 0.000000 | |
20 |
| wsrep_flow_control_paused | 0.000000 | |
21 |
| wsrep_flow_control_sent | 0 | |
22 |
| wsrep_flow_control_recv | 0 | |
23 |
| wsrep_cert_deps_distance | 0.000000 | |
24 |
| wsrep_apply_oooe | 0.000000 | |
25 |
| wsrep_apply_oool | 0.000000 | |
26 |
| wsrep_apply_window | 0.000000 | |
27 |
| wsrep_commit_oooe | 0.000000 | |
28 |
| wsrep_commit_oool | 0.000000 | |
29 |
| wsrep_commit_window | 0.000000 | |
30 |
| wsrep_local_state | 4 | |
31 |
| wsrep_local_state_comment | Synced | |
32 |
| wsrep_cert_index_size | 0 | |
33 |
| wsrep_causal_reads | 0 | |
34 |
| wsrep_incoming_addresses | demoenv-trial-2:3306,demoenv-trial-1:3306 | |
35 |
| wsrep_cluster_conf_id | 2 | |
36 |
| wsrep_cluster_size | 2 | |
37 |
| wsrep_cluster_state_uuid | 5bff0df7-4e1d-11e3-82a1-2288fc08ae68 | |
38 |
| wsrep_cluster_status | Primary | |
39 |
| wsrep_connected | ON | |
40 |
| wsrep_local_index | 1 | |
41 |
| wsrep_provider_name | Galera | |
42 |
| wsrep_provider_vendor | Codership Oy (info@codership.com) | |
43 |
| wsrep_provider_version | 2.8(r162) | |
44 |
| wsrep_ready | ON | |
45 |
+----------------------------+-------------------------------------------+ |
参数 "wsrep_cluster_size" 变为了 2。
下面,就可以按照同样的步骤,添加更多的节点到Cluster中了,在这个测试环境中,我们一共有3个Node。
10. 测试Cluster功能:
[dong.guo@demoenv-trial-2 ~]$ mysql -uroot
01 |
mysql> drop user '' @localhost; |
02 |
mysql> drop user '' @ 'demoenv-trial-1' ; |
03 |
mysql> drop user root@ 'demoenv-trial-1' ; |
04 |
mysql> drop user root@ '::1' ; |
05 |
mysql> select User,Password,Host,Grant_priv from mysql.user; |
06 |
+------+-------------------------------------------+-----------------+------------+ |
07 |
| User | Password | Host | Grant_priv | |
08 |
+------+-------------------------------------------+-----------------+------------+ |
09 |
| root | | localhost | Y | |
10 |
| root | | 127.0.0.1 | Y | |
11 |
| sst | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | localhost | N | |
12 |
+------+-------------------------------------------+-----------------+------------+ |
[dong.guo@demoenv-trial-1 ~]$ mysql -uroot
1 |
mysql> select User,Password,Host,Grant_priv from mysql.user; |
2 |
+------+-------------------------------------------+-----------------+------------+ |
3 |
| User | Password | Host | Grant_priv | |
4 |
+------+-------------------------------------------+-----------------+------------+ |
5 |
| root | | localhost | Y | |
6 |
| root | | 127.0.0.1 | Y | |
7 |
| sst | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | localhost | N | |
8 |
+------+-------------------------------------------+-----------------+------------+ |
数据自动同步了,在 XtraDB Cluster 中,没有主从的概念;
它是一个Multi-Master的同步方案,支持在任意Node上写入数据,其它Node自动同步;
测试如果一个Node失效的情况:
[dong.guo@demoenv-trial-1 ~]$ sudo killall -9 mysqld
[dong.guo@demoenv-trial-2 ~]$ mysql -uroot
01 |
mysql> show global status like 'wsrep%' ; |
02 |
+----------------------------+-------------------------------------------+ |
03 |
| Variable_name | Value | |
04 |
+----------------------------+-------------------------------------------+ |
05 |
| wsrep_local_state_uuid | 5bff0df7-4e1d-11e3-82a1-2288fc08ae68 | |
06 |
| wsrep_protocol_version | 4 | |
07 |
| wsrep_last_committed | 7 | |
08 |
| wsrep_replicated | 2 | |
09 |
| wsrep_replicated_bytes | 328 | |
10 |
| wsrep_received | 10 | |
11 |
| wsrep_received_bytes | 1121 | |
12 |
| wsrep_local_commits | 0 | |
13 |
| wsrep_local_cert_failures | 0 | |
14 |
| wsrep_local_bf_aborts | 0 | |
15 |
| wsrep_local_replays | 0 | |
16 |
| wsrep_local_send_queue | 0 | |
17 |
| wsrep_local_send_queue_avg | 0.000000 | |
18 |
| wsrep_local_recv_queue | 0 | |
19 |
| wsrep_local_recv_queue_avg | 0.000000 | |
20 |
| wsrep_flow_control_paused | 0.000000 | |
21 |
| wsrep_flow_control_sent | 0 | |
22 |
| wsrep_flow_control_recv | 0 | |
23 |
| wsrep_cert_deps_distance | 0.000000 | |
24 |
| wsrep_apply_oooe | 0.000000 | |
25 |
| wsrep_apply_oool | 0.000000 | |
26 |
| wsrep_apply_window | 1.000000 | |
27 |
| wsrep_commit_oooe | 0.000000 | |
28 |
| wsrep_commit_oool | 0.000000 | |
29 |
| wsrep_commit_window | 1.000000 | |
30 |
| wsrep_local_state | 4 | |
31 |
| wsrep_local_state_comment | Synced | |
32 |
| wsrep_cert_index_size | 0 | |
33 |
| wsrep_causal_reads | 0 | |
34 |
| wsrep_incoming_addresses | demoenv-trial-3:3306,demoenv-trial-2:3306 | |
35 |
| wsrep_cluster_conf_id | 4 | |
36 |
| wsrep_cluster_size | 2 | |
37 |
| wsrep_cluster_state_uuid | 5bff0df7-4e1d-11e3-82a1-2288fc08ae68 | |
38 |
| wsrep_cluster_status | Primary | |
39 |
| wsrep_connected | ON | |
40 |
| wsrep_local_index | 1 | |
41 |
| wsrep_provider_name | Galera | |
42 |
| wsrep_provider_vendor | Codership Oy (info@codership.com) | |
43 |
| wsrep_provider_version | 2.8(r162) | |
44 |
| wsrep_ready | ON | |
45 |
+----------------------------+-------------------------------------------+ |
参数 "wsrep_cluster_size" 变为了 2,并且 "demoenv-trial-1" 被移出了 Cluster 列表 "wsrep_incoming_addresses"。
测试写入数据:
1 |
mysql> use testdb; |
2 |
mysql> INSERT INTO hostgroup (hostgroup_name,hostgroup_next,colo_name) VALUES ( "adse" , "2" , "awse" ); |
[dong.guo@demoenv-trial-3 ~]$ mysql -uroot
1 |
mysql> use testdb; |
2 |
mysql> select * from hostgroup where hostgroup_name = "adse" ; |
3 |
+--------------+----------------+----------------+-----------+ |
4 |
| hostgroup_id | hostgroup_name | hostgroup_next | colo_name | |
5 |
+--------------+----------------+----------------+-----------+ |
6 |
| 2 | adse | 2 | awse | |
7 |
+--------------+----------------+----------------+-----------+ |
可以看到 "demoenv-trial-1" 已经恢复。
[dong.guo@demoenv-trial-1 ~]$ sudo rm -f /opt/mysql/run/mysqld.pid
[dong.guo@demoenv-trial-1 ~]$ sudo rm -f /var/lock/subsys/mysql
[dong.guo@demoenv-trial-1 ~]$ sudo /etc/init.d/mysql start
1 |
Starting MySQL (Percona XtraDB Cluster).......SST in progress, setting sleep higher |
2 |
.. SUCCESS! |
[dong.guo@demoenv-trial-1 ~]$ mysql -uroot
01 |
mysql> use testdb; |
02 |
mysql> select User,Password,Host,Grant_priv from mysql.user; |
03 |
+------+-------------------------------------------+-----------+------------+ |
04 |
| User | Password | Host | Grant_priv | |
05 |
+------+-------------------------------------------+-----------+------------+ |
06 |
| root | | localhost | Y | |
07 |
| root | | 127.0.0.1 | Y | |
08 |
| sst | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | localhost | N | |
09 |
+------+-------------------------------------------+-----------+------------+ |
10 |
11 |
mysql> GRANT USAGE ON *.* TO 'clustercheck' @ 'localhost' IDENTIFIED BY 'password' ; |
[dong.guo@demoenv-trial-1 ~]$ /usr/bin/clustercheck clustercheck password 0;
1 |
HTTP/1.1 200 OK |
2 |
Content-Type: text/plain |
3 |
Connection: close |
4 |
Content-Length: 40 |
5 |
Percona XtraDB Cluster Node is synced. |
"demoenv-trial-1" 的同步状态正常。
11. 以下是对 "Percona XtraDB Cluster" 功能测试的总结:
它和 Percona-Server-server-55 是兼容的,可以共用数据文件,但是软件包是冲突的,必须删除原有的软件包之后再安装新的软件包;
它没有 master 和 slave 的概念,而是 multi-master 方式的同步,支持在任意节点上写入数据,同时它能确保写入时不产生一致性冲突问题;
它没有通过binlog方式来同步,而是xtrabackup的方式,因为每个节点都是彼此的镜像,像参数 "binlog-do-db" 这类的就没有什么用了;
它在高可用方面明显要比master-slave方式好。
在Percona-XtraDB-Cluster-2里面很容易实现了haproxy代理,功能虽然实现,但是考虑并不是周全的;在client配置haproxy, 有2个可能的配置,首先配置轮询,那意味着你将连接并且写操作到集群所有节点,这个很容易实现,但是在事务提交时存在乐观锁,如果你写冲突,回滚可能发生;第二个配置,你可以配置haproxy,将写写入一个节点,因此应用程序不必准备意想不到的回滚;大多数时候,第一配置是一个很好的选择,但无论如何,一个好的应用行为不处理回滚是不健康的。所以继续优化配置
进一步优化配置文件:cat /etc/haproxy/haproxy.cfg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#———————————————————————
# Global settings
#———————————————————————
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the ‘-r’ option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local0
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#———————————————————————
# common defaults that all the ‘listen’ and ‘backend’ sections will
# use if not designated in their block
#———————————————————————
defaults
#mode http
mode tcp
log global
#option httplog
option tcplog
option dontlognull
#option http-server-close
#option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#———————————————————————
# main frontend which proxys to the backends
#———————————————————————
frontend yqd-front
bind *:3307
mode tcp
default_backend yqd-back
frontend stats-front
bind *:8080
mode http
default_backend stats-back
frontend yqd-onenode-front
bind *:3306
mode tcp
default_backend yqd-onenode-back
#———————————————————————
# static backend for serving up images, stylesheets and such
#———————————————————————
backend yqd-back
mode tcp
balance leastconn
option httpchk
server n1 192.168.1.224:3306 check port 9200 inter 12000 rise 3 fall 3
server n2 192.168.1.230:3306 check port 9200 inter 12000 rise 3 fall 3
server n3 192.168.1.252:3306 check port 9200 inter 12000 rise 3 fall 3
backend stats-back
mode http
balance roundrobin
stats uri /haproxy/stats
stats auth yqdstats:123456
#———————————————————————
# round robin balancing between the various backends
#———————————————————————
backend yqd-onenode-back
mode tcp
balance leastconn
option httpchk
server n1 192.168.1.224:3306 check port 9200 inter 12000 rise 3 fall 3
server n2 192.168.1.230:3306 check port 9200 inter 12000 rise 3 fall 3 backup
server n3 192.168.1.252:3306 check port 9200 inter 12000 rise 3 fall 3 backup
|
在这段配置文件中,定义了三个前后端, static是haproxy的状态页,其他的为cluster所使用,mysql侦听3306和3307端口,当为3306端口时,调用后端yqd-onenode-back,也就是只有 192.168.1.224可被使用(仅一台),如果192.168.1.224挂了,那你可以使用另外一台服务器,反正一个时间内只有一台服务器被使用;当为3307端口时,调用后端yqd-back,此时有三台服务器可以被使用;比如应用程序要写入数据库时,可以让应用程序指定端口,使用某一台服务器,当查询时,可以三台同时查!这样就可以很好的防止事务回滚了!
安装xinetd(如果没有安装的话)在每个节点/etc/xinetd.d目录下会有这么一个文件mysqlchk,其内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 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 = 0.0.0.0/0
# recommended to put the IPs that need
# to connect exclusively (security purposes)
per_source = UNLIMITED
}
|
每个节点(haproxy在内)在/etc/services.增加:
1
|
mysqlchk 9200/tcp # mysqlchk
|
进入cluster中的任何一台机器,为检测用户添加密码
1
2
3
4
5
|
mysql> grant process on *.* to 'haproxy_check'@'localhost' identified by 'haproxy_check';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
|
修改每个节点clustercheck里面的检测用户和密码
将:
1
2
|
MYSQL_USERNAME="${1-clustercheckuser}"
MYSQL_PASSWORD="${2-clustercheckpassword!}"
|
更改为:
1
2
|
MYSQL_USERNAME="${1-haproxy_check}"
MYSQL_PASSWORD="${2-haproxy_check}"
|
启动xinetd
1
2
|
[root@percona-node3 ~]# /etc/init.d/xinetd start
Starting xinetd: [ OK ]
|
每个节点检测(包括haproxy):
1
2
3
4
5
6
7
|
[root@percona-node3 ~]# clustercheck
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: close
Content-Length: 40
Percona XtraDB Cluster Node is synced.
|
启动haproxy:
1
2
|
[root@localhost vhosts]# /etc/init.d/haproxy start
Starting haproxy: [ OK ]
|
几周前,我将一些独立的 MySQL 服务器(其中一部分是主节点,一部分是独立主机)移植到一个三节点的 Percona XtraDB Cluster 中。 最简单的方法就是配置每个节点成为其中某个产品服务器的异步从节点。 |
![]() 红薯
|
准备从节点(在每个从节点上执行) : for each production server 恢复dump文件到将用于专用从节点的服务器 在InnoDB中转换表 配置和启动当前节点 在其他节点上执行SST 在当前例子中我们需要循环3次,这会花费一些时间。但是如果超过3个节点,怎么办呢? |
![]() IdleMan
|
所以我决定用一下MariaDB 10的多主复制功能Multi-source replication (补充一下MariaDB和多主复制: MariaDB基于事务的Maria存储引擎,替换了MySQL的MyISAM存储引擎,它使用了Percona的 XtraDB,InnoDB的变体,分支的开发者希望提供访问即将到来的MySQL 5.4 InnoDB性能。这个版本还包括了 PrimeBase XT (PBXT) 和 FederatedX 存储引擎。 Multi-source replication means that one server has many masters from which it replicates. This is a new feature in MariaDB 10.0 release. 你可以把你的数据分在很多个主数据库上,然后通过这个功能备份到一个从数据库上。这对分析数据是非常有用的。 ) MariaDB 10的多主复制功能没有提供任何数据冲突的解决办法,这样做是因为每个server独自处理不同的schema,互不影响,所以不同的master库间也不会产生数据冲突。这里所提的案例就是这种情况。 (注释:我到现在都觉得schema的中文翻译很奇怪,所以常见的term还是不要翻译好了,你懂) |
![]() 王薇
|
感谢MariaDB团队开发的这个特性。
|
本篇文章紀錄安裝 Percona XtraDB Cluster (簡稱 PXC) 及搭配 HAProxy 做分散流量系統,其實在業界已經很常看到 HAProxy + MySQL Cluster Database 解決方案,HAProxy 幫您解決負載平衡,並且偵測系統是否存活,管理者也就不用擔心 MySQL 服務是否會掛掉。本篇會著重於 HAProxy 設定部份,並且紀錄每一步安裝步驟。之前本作者寫過一篇 Galera Cluster for MySQL Multi-master Replication,也可以參考。今天測試系統都會以 CentOS 為主,各位讀者可以直接開 Amazone EC2 來測試,測試完成再關閉即可。
安裝 Percona XtraDB Cluster
我們會使用官方 Percona 及 EPEL repositories 進行軟體安裝,底下是 Yum 安裝步驟
$ yum -y install Percona-XtraDB-Cluster-server Percona-XtraDB-Cluster-client Percona-Server-shared-compat percona-xtrabackup
如果系統已經有安裝過 MariaDB + Galera,請務必先移除套件
完成安裝 PXC 套件後,接著設定 my.cnf
設定檔
[mysqld] server_id=1 wsrep_provider=/usr/lib64/libgalera_smm.so wsrep_cluster_address="gcomm://" wsrep_sst_auth=username:password wsrep_provider_options="gcache.size=4G" wsrep_cluster_name=Percona wsrep_sst_method=xtrabackup wsrep_node_name=db_01 wsrep_slave_threads=4 log_slave_updates innodb_locks_unsafe_for_binlog=1 innodb_autoinc_lock_mode=2
再開啟第 2 台或第 3 台 PXC 服務的時候,務必確認第 1 台已經正確開啟成功。上面設定檔是針對第 1 台做設定,之後新增 Node,請務必修改 wsrep_cluster_address
填上你想要 Join 的 Cluster Server IP Address,另外每台的 server_id
及 wsrep_node_name
也會不同,請務必注意
第 2 台設定值
server_id=2 wsrep_cluster_address=gcomm://192.168.1.100 # replace this with the IP of your first node wsrep_node_name=db_02
第 3 台設定值
server_id=2 wsrep_cluster_address=gcomm://192.168.1.100 # replace this with the IP of your first node wsrep_node_name=db_03
根據 State Snapshot Transfer (簡稱 SST),我們使用 Xtrabackup
,當新的 Node 連上時,就會開始複製資料到新的 Node 上,成功複製完成,可以看到底下 Log 訊息
140117 11:56:05 [Note] WSREP: Flow-control interval: [28, 28] 140117 11:56:05 [Note] WSREP: Shifting OPEN -> PRIMARY (TO: 678691) 140117 11:56:05 [Note] WSREP: State transfer required: Group state: 28e87291-da41-11e2-0800-34a03cad54a7:678691 Local state: 28e87291-da41-11e2-0800-34a03cad54a7:678684 140117 11:56:05 [Note] WSREP: New cluster view: global state: 28e87291-da41-11e2-0800-34a03cad54a7:678691, view# 33: Primary, number of nodes: 3, my index: 1, protocol version 2 140117 11:56:05 [Warning] WSREP: Gap in state sequence. Need state transfer. 140117 11:56:07 [Note] WSREP: Running: 'wsrep_sst_xtrabackup --role 'joiner' --address '122.146.119.102' --auth 'username:password' --datadir '/var/lib/mysql/' --defaults-file '/etc/my.cnf' --parent '965'' WSREP_SST: [INFO] Streaming with tar (20140117 11:56:07.517) WSREP_SST: [INFO] Using socat as streamer (20140117 11:56:07.519) WSREP_SST: [INFO] Evaluating socat -u TCP-LISTEN:4444,reuseaddr stdio | tar xfi - --recursive-unlink -h; RC=( ${PIPESTATUS[@]} ) (20140117 11:56:07.531) 140117 11:56:07 [Note] WSREP: Prepared SST request: xtrabackup|122.146.119.102:4444/xtrabackup_sst 140117 11:56:07 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification. 140117 11:56:07 [Note] WSREP: Assign initial position for certification: 678691, protocol version: 2 140117 11:56:07 [Note] WSREP: Prepared IST receiver, listening at: tcp://122.146.119.102:4568 140117 11:56:07 [Note] WSREP: Node 1 (db_01) requested state transfer from '*any*'. Selected 0 (db_02)(SYNCED) as donor. 140117 11:56:07 [Note] WSREP: Shifting PRIMARY -> JOINER (TO: 678692) 140117 11:57:36 [Note] WSREP: Synchronized with group, ready for connections 140117 11:57:36 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification. 140117 11:57:36 [Note] WSREP: 1 (db_02): State transfer from 0 (db_01) complete. 140117 11:57:36 [Note] WSREP: Member 1 (db_02) synced with group.
最後我們可以透過 MySQL Status 來看看是否有建立成功
mysql> show global status like 'wsrep_cluster_size'; +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | wsrep_cluster_size | 3 | +--------------------+-------+ 1 row in set (0.00 sec)
看到 wsrep_cluster_size
出現正確的 Server 數量,就代表設定成功。
設定 HAProxy 負載平衡
上述完成了 3 台 Cluster 設定,接著所有的 Application 服務都需要直接跟此 Cluster 溝通,為了完成此需求,我們必須將 HAProxy 安裝在其中一台伺服器來做負載平衡,今天會介紹兩種設定方式,第一種是採用 round robin 方式,意思就是說所有的 Application 都可以連上並且寫入資料到三台機器,這狀況其實沒有錯誤,但是如果同時寫入三台機器,難免會出現 optimistic locking 而產生 rollback,如果可以確定不會產生 conflict,其實這方案是不錯的。第2種設定方式就是只寫入單一 Node,但是可以讀取三台機器,也就是 insert
, update
都是在同一台 Node 完成,所以 Application 不用擔心會產生 rollback 情形。第1種設定在大部份的狀況底下都是可以運作很好的,所以其實也不用擔心。
底下是 /etc/haproxy/haproxy.cfg
設定
frontend stats-front bind *:8080 mode http default_backend stats-back frontend pxc-front bind *:3307 mode tcp default_backend pxc-back frontend pxc-onenode-front bind *:3308 mode tcp default_backend pxc-onenode-back backend stats-back mode http balance roundrobin stats uri /haproxy/stats stats auth username:password backend pxc-back mode tcp balance leastconn option httpchk server c1 192.168.1.100:3306 check port 9200 inter 12000 rise 3 fall 3 server c2 192.168.1.101:3306 check port 9200 inter 12000 rise 3 fall 3 server c3 192.168.1.102:3306 check port 9200 inter 12000 rise 3 fall 3 backend pxc-onenode-back mode tcp balance leastconn option httpchk server c1 192.168.1.100:3306 check port 9200 inter 12000 rise 3 fall 3 server c2 192.168.1.101:3306 check port 9200 inter 12000 rise 3 fall 3 backup server c3 192.168.1.102:3306 check port 9200 inter 12000 rise 3 fall 3 backup
從上述設定,可以看到我們定義了 3 個 frontend-backend
,其中 stats-front
是 HAProxy Status Page,另外兩組則是針對 PXC 設定。看到此設定,可以知道系統會 Listen 3307 及 3308 兩個 port,其中 3308 會讓 App 使用一台 PXC Node 而已,此設定可以避免因為 optimistic locking
而產生 rollbacks,如果 Node 掛點,則會啟動其他 Node。然而如果是連接 3307 port,系統會直接對3台 node 寫入或讀取,我們使用 leastconn
取代 round robin
,這代表著 HAProxy 會偵測所有機器,並且取得現在連線數目最少的 Node 來給下一個連線。最後 stats-front
是顯示 HAProxy 偵測及連線狀態,請務必設定帳號密碼。
完成設定,如何偵測 MySQL Server 是否存活,靠著就是 9200 port,透過 Http check 方式,讓 HAProxy 知道 PXC 狀態,安裝完 PXC 後,可以發現多了 clustercheck
指令,我們必須先給 clustercheckuser
使用者帳號密碼
# Grant privileges required: $ GRANT PROCESS ON *.* TO 'clustercheckuser'@'localhost' IDENTIFIED BY 'clustercheckpassword!';
此 clustercheck
指令會在 Local 執行 SHOW STATUS LIKE 'wsrep_local_state'
MySQL 指令,回傳值為 200
或 503
,指令確定成功執行,最後步驟就是透過 xinetd
產生 9200 port 的服務。底下先安裝 xinetd
服務
$ yum -y install xinetd
產生 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 = 0.0.0.0/0 # recommended to put the IPs that need # to connect exclusively (security purposes) per_source = UNLIMITED }
上面步驟全部成功,請打開 URL 輸入 HAProxy Status 頁面,看到底下狀態,就是代表設定成功
http://my.oschina.net/anthonyyau/blog/276775
环境情况:
系统:CentOS release 6.4 (Final),2.6.32-358.el6.x86_64
PXC版本:二进制版本,5.5.37-35.0-25.10 Percona XtraDB Cluster binary (GPL) 5.5.37-25.10, Revision 756, wsrep_25.10.r3985
集群节点:
在每个节点安装PXC:
1
2
|
tar -xvf Percona-XtraDB-Cluster-5.5.37-rel35.0-25.10.756.Linux.x86_64. tar .gz -C /opt ln -s /opt/Percona-XtraDB-Cluster-5 .5.37-rel35.0-25.10.756.Linux.x86_64 /opt/PXC |
配置节点mariadb01:
简单my.cnf配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
[mysqld] datadir= /opt/PXC/data binlog_format=ROW #存储引擎设置为innodb,myisam仅仅测试支持 default-storage-engine=innodb #指定innodb 自增长列锁模式,2为交叉锁模式, 多个语句能同时执行 innodb_autoinc_lock_mode=2 innodb_locks_unsafe_for_binlog=1 query_cache_size=0 query_cache_type=0 bind-address=0.0.0.0 #指定Galera库文件,PXC自带该库文件,mariadb galera需要安装galera wsrep_provider= /opt/PXC/lib/libgalera_smm .so wsrep_cluster_name= "my_wsrep_cluster" #指定集群每个节点的连接地址 wsrep_cluster_address= "gcomm://10.0.60.104,10.0.60.105,10.0.60.106" wsrep_slave_threads=1 wsrep_certify_nonPK=1 wsrep_max_ws_rows=131072 wsrep_max_ws_size=1073741824 wsrep_debug=1 wsrep_convert_LOCK_to_trx=0 wsrep_retry_autocommit=1 wsrep_auto_increment_control=1 wsrep_drupal_282555_workaround=0 wsrep_causal_reads=0 wsrep_notify_cmd= #指定SST方式,支持rsync(最快,需要锁表),mysqldump和xtrabackup,从5.5.33-23.7.6起支持xtrabackup-v2 wsrep_sst_method=xtrabackup-v2 #SST的认证方式 wsrep_sst_auth=sstuser:sstuser |
启动mariadb01节点:
1
|
. /bin/mysqld_safe --defaults- file =my.cnf --wsrep-cluster-address= "gcomm://" & |
创建SST用户和进行相应的授权:
1
2
3
|
DELETE FROM mysql. user WHERE user = '' ; GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'sstuser' @ 'localhost' IDENTIFIED BY 'sstuser' ;; FLUSH PRIVILEGES ; |
配置节点mariadb02:
mysql> \! cat /opt/PXC/my.cnf |grep -v ^#|grep -v ^$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
[mysqld] datadir= /opt/PXC/data binlog_format=ROW default-storage-engine=innodb innodb_autoinc_lock_mode=2 innodb_locks_unsafe_for_binlog=1 query_cache_size=0 query_cache_type=0 bind-address=0.0.0.0 wsrep_provider= /opt/PXC/lib/libgalera_smm .so wsrep_cluster_name= "my_wsrep_cluster" wsrep_cluster_address= "gcomm://10.0.60.104,10.0.60.105,10.0.60.106" wsrep_slave_threads=1 wsrep_certify_nonPK=1 wsrep_max_ws_rows=131072 wsrep_max_ws_size=1073741824 wsrep_debug=0 wsrep_convert_LOCK_to_trx=0 wsrep_retry_autocommit=1 wsrep_auto_increment_control=1 wsrep_drupal_282555_workaround=0 wsrep_causal_reads=0 wsrep_notify_cmd= wsrep_sst_method=xtrabackup-v2 wsrep_sst_auth=sstuser:sstuser |
启动mariadb02节点:
1
|
. /bin/mysqld_safe --defaults- file =my.cnf & |
配置节点mariadb03:
mysql> \! cat /opt/PXC/my.cnf |grep -v ^#|grep -v ^$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[mysqld] binlog_format=ROW default-storage-engine=innodb innodb_autoinc_lock_mode=2 innodb_locks_unsafe_for_binlog=1 query_cache_size=0 query_cache_type=0 bind-address=0.0.0.0 wsrep_provider= /opt/PXC/lib/libgalera_smm .so wsrep_cluster_name= "my_wsrep_cluster" wsrep_cluster_address= "gcomm://10.0.60.104,10.0.60.105,10.0.60.106" wsrep_slave_threads=1 wsrep_certify_nonPK=1 wsrep_max_ws_rows=131072 wsrep_max_ws_size=1073741824 wsrep_debug=0 wsrep_convert_LOCK_to_trx=0 wsrep_retry_autocommit=1 wsrep_auto_increment_control=1 wsrep_drupal_282555_workaround=0 wsrep_causal_reads=0 wsrep_notify_cmd= wsrep_sst_method=xtrabackup wsrep_sst_auth=sstuser:sstuser |
启动mariadb03节点:
1
|
. /bin/mysqld_safe --defaults- file =my.cnf & |
检查状态:
mariadb01>show status like 'wsrep%';
+----------------------------+----------------------------------------------------+
| Variable_name | Value |
+----------------------------+----------------------------------------------------+
| wsrep_local_state_uuid | 961de113-ed93-11e3-95a0-934e3df4463f |
| wsrep_protocol_version | 4 |
| wsrep_last_committed | 8 |
| wsrep_replicated | 1 |
| wsrep_replicated_bytes | 180 |
| wsrep_received | 5 |
| wsrep_received_bytes | 798 |
| wsrep_local_commits | 1 |
| wsrep_local_cert_failures | 0 |
| wsrep_local_replays | 0 |
| wsrep_local_send_queue | 0 |
| wsrep_local_send_queue_avg | 0.000000 |
| wsrep_local_recv_queue | 0 |
| wsrep_local_recv_queue_avg | 0.000000 |
| wsrep_flow_control_paused | 0.000000 |
| wsrep_flow_control_sent | 0 |
| wsrep_flow_control_recv | 0 |
| wsrep_cert_deps_distance | 1.000000 |
| wsrep_apply_oooe | 0.000000 |
| wsrep_apply_oool | 0.000000 |
| wsrep_apply_window | 0.000000 |
| wsrep_commit_oooe | 0.000000 |
| wsrep_commit_oool | 0.000000 |
| wsrep_commit_window | 0.000000 |
| wsrep_local_state | 4 |
| wsrep_local_state_comment | Synced |
| wsrep_cert_index_size | 4 |
| wsrep_causal_reads | 0 |
| wsrep_incoming_addresses | 10.0.60.104:3306,10.0.60.105:3306,10.0.60.106:3306 |
| wsrep_cluster_conf_id | 3 |
| wsrep_cluster_size | 3 |
| wsrep_cluster_state_uuid | 961de113-ed93-11e3-95a0-934e3df4463f |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
| wsrep_local_bf_aborts | 0 |
| wsrep_local_index | 0 |
| wsrep_provider_name | Galera |
| wsrep_provider_vendor | Codership Oy <info@codership.com> |
| wsrep_provider_version | 2.10(r175) |
| wsrep_ready | ON |
+----------------------------+----------------------------------------------------+
40 rows in set (0.00 sec)
http://kaifly.blog.51cto.com/3209616/1574640
Percona XtraDB Cluster(下文简称PXC集群)提供了MySQL高可用的一种实现方法。PXC集群以节点组成(推荐至少3节点,后面会讨论两节点的情况),每个节点都是基于常规的 MySQL/Percona Server,意味着你可以从集群中分离出某节点单独使用。集群中每个节点都包含完整的数据。
PXC集群主要由两部分组成:Percona Server with XtraDB和Write Set Replication patches(使用了Galera library,一个通用的用于事务型应用的同步、多主复制插件)。
PXC的特性和优点:
1、同步复制
2、支持多主复制
3、支持并行复制
4、作为高可用方案,相比其他方案其结构和实施相对简单明了
PXC的局限和劣势:
1、 当前版本(5.6.20)的复制只支持InnoDB引擎,其他存储引擎的更改不复制。然而,DDL(Data Definition Language) 语句在statement级别被复制,并且,对mysql.*表的更改会基于此被复制。例如CREATE USER...语句会被复制,但是 INSERT INTO mysql.user...语句则不会。(也可以通过wsrep_replicate_myisam参数开启myisam引擎的 复制,但这是一个实验性的参数)。
2、 由于PXC集群内部一致性控制的机制,事务有可能被终止,原因如下:集群允许在两个节点上通知执行操作同一行的两个事务,但是只有一个能执行成功,另一个 会被终止,同时集群会给被终止的客户端返回死锁错误(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)).
3、写入效率取决于节点中最弱的一台,因为PXC集群采用的是强一致性原则,一个更改操作在所有节点都成功才算执行成功。
下面从安装部署和功能和性能测试三个方面开始PXC之旅。
安装部署
实验环境:三台server(硬件配置相同),信息如下:
node
#1
hostname: percona1
IP: 192.168.1.35
node
#2
hostname: percona2
IP: 192.168.1.36
node
#3
hostname: percona3
IP: 192.168.1.37
注意:
Firewall has been set up to allow connecting to ports 3306, 4444,4567 and 4568
SELinux isdisabled如果不关闭SELinux,启动其他(node1之外)节点时,错误日志里会记录“
[ERROR]
WSREP:Permission denied”
一.在三台server安装Percona-XtraDB-Cluster-56
1.安装epel源 yum install http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
(包含比较全比较新的软件源。最关键的是包含PreconaXtraDB Cluster所依赖的socat软件)
将其中baseurl行的注释去掉,同时将mirror行注释
2、安装Precona XtraDB Cluster所需要的扩展包,以防在后期配置时候报错
shell> yuminstall -y cmake gcc gcc-c++ libaio libaio-devel automake autoconf bzr bisonlibtool ncurses5-devel boost
3.安装配置Precona 官方yum源
yum install http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
4.安装socat
socat is a relay for bidirectional data transfer between two independentdata channels. (Socat是一个在两个独立数据的双向传输之间起到中继作用的软件)
配置好epel源之后,可直接执行 yum install socat*
若无法yum安装socat,则按照以下步骤编译安装
wget http://www.dest-unreach.org/socat/download/socat-1.7.2.4.tar.gz
tar zxvf socat-1.7.2.4.tar.gz
./configure
Make && make install
5.安装perl组件(xtrabackup需要的组件)
yum install perl-DBD-MySQL perl-DBI perl-Time-HiRes
6.安装Percona-XtraDB-Cluster及其相关组件
二.初始化Percona-XtraDB-Cluster集群
在任意节点(一般为node1)上执行集群的初始化操作
创建/etc/my.cnf,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[mysqld] datadir= /var/lib/mysql user=mysql # Path to Galeralibrary wsrep_provider= /usr/lib64/libgalera_smm .so # Cluster connectionURL contains the IPs of node#1, node#2 and node#3----所有节点的ip #第一次启动node1节点时,此处不写各节点IP,需写成下面一行配置 wsrep_cluster_address=gcomm: // #第一次启动node1(初始化集群)完成后,此处需要改成下面一行配置 #wsrep_cluster_address=gcomm://192.168.1.35,192.168.1.36,192.168.1.37 # In order for Galerato work correctly binlog format should be ROW binlog_format=ROW # MyISAM storageengine has only experimental support default_storage_engine=InnoDB # This changes howInnoDB autoincrement locks are managed and is a requirement for Galera innodb_autoinc_lock_mode=2 # Node #1 address----本机ip wsrep_node_address=192.168.1.35 # SST method----节点间同步的方式 wsrep_sst_method=xtrabackup-v2 # Cluster name wsrep_cluster_name=my_centos_cluster # Authentication forSST method----来做节点间数据同步的账号密码 wsrep_sst_auth= "sstuser:s3cret" |
(其他mysql相关参数绝大多数也可以直接在配置文件里添加)
注意:第一次启动node1(初始化集群)时,配置文件里wsrep_cluster_address=gcomm:// 不需加上各节点IP,否则其他节点会无法启动;当初始化完成后,需将此处修改为加上各节点IP
然后再修改配置文件my.cnf将wsrep_cluster_address=gcomm:// 行改为 wsrep_cluster_address=gcomm://192.168.1.35,192.168.1.36,192.168.1.37
然后,执行service mysqlrestart 至此,集群初始化完成,并且node1启动
设置mysql root密码
mysql@percona1>UPDATE mysql.user SET password=PASSWORD("Passw0rd") whereuser=’root’;
mysql@percona1>FLUSH PRIVILEGES;
设置用于复制的账户密码
mysql@percona1>GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO ’sstuser’@’localhost’identified by ‘s3cret’;
三.配置node2、node3并启动
将node1的/etc/my.cnf内容拷贝至node2和node3,并修改其中wsrep_node_address=192.168.1.35
改为本机ip。
然后启动node2、node3 。执行servicemysql start
注意:node2、node3会从node1同步账号设置的更改
配置成功以后如果集群内所有节点实例均关闭(crash)后,再启动时都需要选择一个存有最新正 确数据的节点作为主节点,执 行 /etc/init.d/mysql bootstrap-pxc 启动; 然后再启动他节点。
写入效率初测
测试方法为
1.将三个节点分别作为单独的server导入一个sql文件,执行三次取时间平均值
time mysql -uroot -pxxx system < /system.sql
平均时间约为6m20s
2.开启完整集群,在三个节点分别执行一遍导入操作,取三次执行时间平均值
平均时间约为7m50s
经过初步测试写性能PXC集群相比单server下降约12%。
参考官方文档一些可以调优的参数:
1. Variable wsrep_slave_threads :复制线程的数量,galera支持真正的并行复制,适当增大此值可以在复制时获得更好的吞吐量,如果更改此值后遇到复制的某些问题,尝试将此值改回1,查看是否解决。(默认1)
2. wsrep_provider_options="gcache.size=512M",调节galera的缓存大小,或许对减少IO有帮助
3. variable gcache.mem_size
4. variable gcache.size 此参数定义作为‘IST增量同步’的内容源的galera.cache文件的大小。此文件设置的大些以便节点重新加入集群式更有可能采用IST而非SST。(默认128M)
5. variable gcs.fc_master_slave 此变量指定集群中是否只有一个master节点
6. variable pc.weight This variable specifies thenode weight that’sgoing to be used for Weighted Quorumcalculations. Default Value 1
7. innodb_flush_log_at_trx_commit
为0时:log buffer 每秒向logfile 刷新一次,同时log file 每秒执行一次所记录语句,以使数据持久化。
为1时:默认值。每次事务提交后,log buffer向log file 刷新一次,同时log file 执行一次数据持久化操作。
为2时:每次事务提交后,log buffer向log file 刷新一次,但是从log file 向磁盘做数据持久化的操作是每秒执行一次
将此值改为0后,插入全量测试数据的时间有了质的飞越
Hapeoxy代理
上文主要介绍了PXC集群本身的内容,PXC作为一个集群,需要前端配以代理服务器,做负载均衡,才能真正实现其高可用的价值。Percona官方推荐用haproxy作为前端代理,下面介绍一下haproxy的简要配置:
个人感觉haproxy配置上比lvs相对简单,但功能并不逊色,我试验环境的haproxy配置文件如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#--------------------------------------------------------------------- # Example configuration for a possibleweb application. See the # full configuration options online. # http://haproxy.1wt.eu/download/1.4/doc/configuration.txt #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global # to have these messages end up in /var/log/haproxy.log you will # need to: # 1) configure syslog to accept network log events. This is done # by adding the '-r' option tothe SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like thefollowing can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local0 log 127.0.0.1 local1 notice chroot /var/lib/haproxy pidfile /var/run/haproxy .pid maxconn 4000 user haproxy group haproxy daemon # turn on stats unix socket stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults mode http log global option tcplog option dontlognull # option http-server-close # option forwardfor except127.0.0.0/8 option redispatch retries 3 maxconn 2000 timeout connect 5s timeout client 50s timeout server 50s # timeout http-keep-alive 10s timeout check 10s listen mysql-cluster 0.0.0.0:3306 mode tcp balance roundrobin server node1 192.168.1.35:3306 check server node2 192.168.1.36:3306 check server node3 192.168.1.37:3306 check # 建议首先设置haproxy的监控界面,便于直观的观察后端节点是否在线 listen status 192.168.1.34:8080 stats enable stats uri /status stats auth admin:xxxx stats realm (haproxy\ statistic) |
环境:
- [root@pxc23 ~]# uname -r
- 2.6.39-400.17.1.el6uek.x86_64
192.168.56.21
192.168.56.22
192.168.56.23
1、下载:
http://www.percona.com/redir/downloads/Percona-XtraDB-Cluster/LATEST/binary/tarball/Percona-XtraDB-Cluster-5.5.39-rel36.0-25.11.828.Linux.x86_64.tar.gz2、解压
tar -xzvf Percona-XtraDB-Cluster-5.5.39-rel36.0-25.11.828.Linux.x86_64.tar.gz -C /usr/localln -sf /usr/local/Percona-XtraDB-Cluster-5.5.39-rel36.0-25.11.828.Linux.x86_64 /usr/local/mysql
3、检测依赖包
[root@oel64 tmp]# ldd /usr/local/mysql/bin/mysqldlinux-vdso.so.1 => (0x00007fff2d1ff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x000000395f200000)
libaio.so.1 => /lib64/libaio.so.1 (0x000000395ea00000)
libz.so.1 => /lib64/libz.so.1 (0x000000395fa00000)
librt.so.1 => /lib64/librt.so.1 (0x000000395fe00000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x0000003961e00000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f75a20be000)
libssl.so.6 => not found
libcrypto.so.6 => not found
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003963600000)
libm.so.6 => /lib64/libm.so.6 (0x000000395f600000)
libc.so.6 => /lib64/libc.so.6 (0x000000395ee00000)
/lib64/ld-linux-x86-64.so.2 (0x000000395e600000)
libfreebl3.so => /lib64/libfreebl3.so (0x0000003961a00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003962e00000)
安装依赖包
[root@oel64 tmp]# locate libssl.so libcrypto.so.10/usr/lib64/.libcrypto.so.10.hmac
/usr/lib64/.libssl.so.1.0.0.hmac
/usr/lib64/.libssl.so.10.hmac
/usr/lib64/libcrypto.so.10
/usr/lib64/libssl.so.1.0.0
/usr/lib64/libssl.so.10
已有更高的版本,直接建个软链就可以了
ln -s /usr/lib64/libcrypto.so.10 /usr/lib64/libcrypto.so.6
ln -s /usr/lib64/libssl.so.10 /usr/lib64/libssl.so.6
4、用户
groupadd -r -g 306 mysql #-r表示是伪用户,只是用来运行mysql程序,不能登录系统useradd -g 306 -r -u 306 mysql
5、path
[root@OELX64 mysql]# cat ~/.bash_profile... ...
PATH=/usr/local/mysql/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
export PATH
6、my.cnf
下面参数,测试机用,正式环境请测试验正后再用
cat /etc/my.cnf
- [client]
- socket = /tmp/user_3306.sock
- user = mysql
- port = 3306
- [mysql]
- #prompt="\\u@\\h:\\p [\\d]> "
- prompt="\\p>"
- #pager="less -i -n -S"
- #tee=/home/mysql/query.log
- no-auto-rehash
- [mysqld]
- #misc
- user = mysql
- basedir = /usr/local/mysql
- datadir = /data/mysql/user_3306/data
- tmpdir = /data/mysql/user_3306/tmp
- port = 3306
- socket = /tmp/user_3306.sock
- server_id = 213306
- lower_case_table_names = 1
- #timeout
- interactive_timeout = 300
- wait_timeout = 300
- #character set
- character-set-server = utf8
- open_files_limit = 65535
- max_connections = 100
- max_connect_errors = 100000
- #logs
- log-output = file
- slow_query_log = 1
- slow_query_log_file = slow.log
- log-error = error.log
- log_warnings = 2
- pid-file = mysql.pid
- long_query_time = 1
- #log-slow-admin-statements = 1
- #log-queries-not-using-indexes = 1
- log-slow-slave-statements = 1
- #binlog
- binlog_format = row
- log-bin = mysql-bin
- binlog_cache_size = 1M
- max_binlog_size = 200M
- max_binlog_cache_size = 2G
- sync_binlog = 0
- expire_logs_days = 10
- #relay log
- skip_slave_start = 1
- max_relay_log_size = 500M
- relay_log_purge = 1
- relay_log_recovery = 1
- log_slave_updates = 1
- #slave-skip-errors=1032,1053,1062
- #buffers & cache
- table_open_cache = 2048
- table_definition_cache = 2048
- table_open_cache = 2048
- max_heap_table_size = 96M
- sort_buffer_size = 2M
- join_buffer_size = 2M
- thread_cache_size = 256
- query_cache_size = 0
- query_cache_type = 0
- query_cache_limit = 256K
- query_cache_min_res_unit = 512
- thread_stack = 192K
- tmp_table_size = 96M
- key_buffer_size = 8M
- read_buffer_size = 2M
- read_rnd_buffer_size = 16M
- bulk_insert_buffer_size = 32M
- #myisam
- myisam_sort_buffer_size = 128M
- myisam_max_sort_file_size = 10G
- myisam_repair_threads = 1
- #innodb
- innodb_buffer_pool_size = 100M
- innodb_buffer_pool_instances = 1
- innodb_data_file_path = ibdata1:100M:autoextend
- innodb_flush_log_at_trx_commit = 2
- innodb_log_buffer_size = 64M
- innodb_log_file_size = 256M
- innodb_log_files_in_group = 3
- innodb_max_dirty_pages_pct = 90
- innodb_file_per_table = 1
- innodb_rollback_on_timeout
- innodb_status_file = 1
- innodb_io_capacity = 2000
- transaction_isolation = READ-COMMITTED
- innodb_flush_method = O_DIRECT
- #pxc
- default_storage_engine=Innodb
- innodb_locks_unsafe_for_binlog=1
- innodb_autoinc_lock_mode=2
- wsrep_cluster_name=pxc_jz #cluster的名字
- wsrep_cluster_address=gcomm://192.168.56.21,192.168.56.22,192.168.56.23 #cluster 中的节点ip
- wsrep_node_address=192.168.56.21 #cluster当前节点的 ip
- wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so
- #wsrep_sst_method=rsync
- wsrep_sst_method=xtrabackup
- wsrep_sst_auth=sst:26856649
- sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
wsrep_node_address=192.168.56.21 #cluster当前节点的 ip
不同的机子,改上面这两个参数
7、建库
rm /data/mysql/user_3306/ -rfmkdir /data/mysql/user_3306/data -p
mkdir /data/mysql/user_3306/logs -p
mkdir /data/mysql/user_3306/tmp -p
chown -R mysql:mysql /data/mysql/*
cd /data/mysql/user_3306/data/
openssl genrsa -out private_key.pem 1024
openssl rsa -in private_key.pem -pubout > public_key.pem
chmod 444 public_key.pem
chmod 444 private_key.pem
chown mysql:mysql public_key.pem
chown mysql:mysql private_key.pem
cd /usr/local/mysql
# 必须在mysql目录下执行
scripts/mysql_install_db --user=mysql --defaults-file=/etc/my.cnf
cp /usr/local/mysql/support-files/mysql.server /data/mysql/user_3306/
chown -R mysql:mysql /data/mysql/*
cd /data/mysql/user_3306/
启动时要注意第一个节点:
./mysql.server bootstrap-pxc
其它节点
./mysql.server start
安装完成,去测试同步吧
删除节点
直接停掉一个就可以了,比如停掉23之后
- user_3306.sock>show status like 'wsrep_incoming_addresses';
- +--------------------------+---------------------------------------+
- | Variable_name | Value |
- +--------------------------+---------------------------------------+
- | wsrep_incoming_addresses | 192.168.56.22:3306,192.168.56.21:3306 |
- +--------------------------+---------------------------------------+
- 1 row in set (0.00 sec)
如果以后不用23,其它节点可以更改/etc/my.cnf中的参数
- [root@pxc21 user_3306]# cat /etc/my.cnf | grep 23
- wsrep_cluster_address=gcomm://192.168.56.21,192.168.56.22,192.168.56.23 #cluster 中的节点i
去掉里面的192.168.56.23,不需要重启21和22
增加节点
要确认各机子中安装了xtrabackup和socat
yum install percona-xtrabackup-2.2.6-5042.el6.x86_64.rpm
yum install socat-1.7.2.4-1.el6.rf.x86_64.rpm
不然会报错(当pxc中的一台主机停止后重新与其它主机同步时也需要这两个工具)
WSREP_SST: [ERROR] innobackupex not in path: /usr/sbin:/sbin:/usr/local/Percona-XtraDB-Cluster-5.5.39-rel36.0-25.11.828.Linux.x86_64//bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/Percona-XtraDB-Cluster-5.5.39-rel36.0-25.11.828.Linux.x86_64/bin (20150314 00:29:50.433)
WSREP_SST: [ERROR] socat not found in path: /usr/sbin:/sbin:/usr/local/Percona-XtraDB-Cluster-5.5.39-rel36.0-25.11.828.Linux.x86_64//bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/Percona-XtraDB-Cluster-5.5.39-rel36.0-25.11.828.Linux.x86_64/bin (20150314 00:36:42.763)
以上工具都有了后,直接更改新机的my.cnf,并启动就可以了
- [root@oel64 user_3306]# cat /etc/my.cnf | grep 22
- wsrep_cluster_address=gcomm://192.168.56.21,192.168.56.22,192.168.56.24 #cluster 中的节点ip
会自动把21与22的数据复制过来,包括用户
启动后可以看到参数变了
- user_3306.sock>show status like 'wsrep_incoming_addresses';
- +--------------------------+----------------------------------------------------------+
- | Variable_name | Value |
- +--------------------------+----------------------------------------------------------+
- | wsrep_incoming_addresses | 192.168.56.24:3306,192.168.56.22:3306,192.168.56.21:3306 |
- +--------------------------+----------------------------------------------------------+
- 1 row in set (0.00 sec)
登录24检查里面的数据,可以看到21与22里的数据在24也有了
【编者按】 PagerDuty是一家新兴的互联网创业公司,它是一款能够在服务器出问题是发送提醒的产品,包括屏幕显示、电话呼叫、短信通知、电邮通知等。目前AdMob、37Signals、StackOverflow、Instagram等均采用了<ahref="http: pagerduty.com="" "="">PagerDuty作为消息通知以及突发事件处理工具。本文作者Doug Barth分享了PagerDuty是如何成功地把现有系统MySQL迁移至XtraDB集群,以及在这一过程中遇到的利与弊。
<ahref="http: pagerduty.com="" "="">
在半年前,PagerDuty公司成功地把现有系统从MySQL迁移至XtraDB集群,并在其上运行亚马逊EC2。
旧系统配置分析
从配置上看,这是一个非常典型的MySQL环境:
- 一对Percona服务器负责对一个DRBD卷进行数据写入。
- 以主副EBS双机对DRBD卷进行备份。
- 设立两个同步复制数据库,当主服务器出现问题时,能把业务系统无缝转移到次服务器。
- 配置一系列异步复制机,以应对重大灾难、紧急备份、突发变更维护。
存在的问题
兢兢业业的旧系统服务多年后,面对日益突出的可靠性问题,开始显现出力不从心了。此外,每次进行主服务器切换,无疑于是一场悲剧:要进行DRBD主机切换,首先得在主服务器上中断MySQL,脱机DRBD卷,把从服务器状态变更为主服务器,重新载入DRBD,最后重启MySQL。而这一整套过程会导致服务中断,因为MySQL在由中断到重启的过程中,我们设置了一个冷却缓冲池,在系统服务重回正轨前这个冷却机制需要时间预热。
我们尝试通过Percona的缓冲池恢复(buffer-pool-restore)功能来减少中断时间,但这相对于我们体型庞大的缓冲池来说如同蚍蜉撼树。同时该功能会增加额外的系统资源开销。还有个问题是,一旦发生意外的主服务器切换,异步从服务器将停止运作,必须手动重启。
拥抱XtraDB集群的原因
XtraDB集群的特色:相校于之前的双机系统,集群中采用的是三机同时运作,两两进行同步备份。因此连接切换时间大为减少。
支持多主服务器同时在线,每个主服务器拥有一个热缓冲池。异步从服务器可以选择任何节点作为主机,节点间的转移不会中断备份复制进程。
自动化的节点机制与我们目前的自动化系统配合良好。配置新节点后,我们只需提交一个节点地址,新节点将会自动收到一个数据备份集,同步数据后会加载到主服务器群中。
前期准备
将XtraDB集群接入现行系统,需要进行一定的前期准备。部分是简单的MySQL微调,其余的是一些基础化的操作。
在MySQL上的操作:
- 确保只在InnoDB数据表中设置主键。
- 确保不使用query cache(查询缓存),由于cluster不支持。
- 复制方式由基于语句的方式变更为基于行的方式。
除上述MySQL端的操作,为了能在DRBD服务器上进行独立的测试,应用系统端需要进行如下的变更:
- 采用分布式锁机制,由于MySQL采用的是从本地到集群节点的,例如:执行SELECT FOR UPDATE语句。
- 用Zookeeper锁替换MySQL锁。
- 为了检验所有写入的数据能在所有节点上进行数据同步,我们对作业逻辑作出变更,以大量小规模数据处理代替一次性大规模数据处理。
模式变更的选择
在XtraDB集群中进行模式变动是牵一发而动全身的。在集群有两种实现方式,一种是total order isolation (TOI,总序分离式),另外一种是rolling schema upgrade (RSU,滚动模式升级)。
在RSU模式下,允许单独地对节点进行更新。当执行DDL语句时,按序同步各个节点,执行完毕后再重新加入集群。但是这个功能会招致不稳定性,同时数据的大量刷新动作引起的系统问题是不可避免的,由于RSU需要等待DDL语句执行完毕才能进行缓存刷新。
相比之下,TOI的更新操作是一次性同步所有节点,阻断集群通信直到更新完成。我们衡量一番后,决定采用TOI模式。由于系统中断时间较短,所以这次没有对集群进行阻断。
迁移过程
首先,我们在现系统中建立一个集群作为现DRBD数据库的一个从属。当该从属数据库接收到所有写入操作时,我们可以进行压力测试,看看它的承载能力如何;同时会进行相关数据收集和分析。
在进行一系列相关基准测试后,我们发现了两点技术细节是能够帮助实现迁移前后的系统性能趋于一致:
- 把innodb_flush_log_at_trx_commit的值设为0或2,可以获得最优写入性能。由于所有变更都是被复制到3个节点的,即使出现失效情况都不会出现数据丢失情况。
- innodb_log_file_size的值需要设置成较大数值,我们将其设置为1GB。
进行一番测试后,XtraDB集群的各项指标令人满意,我们接下来开始着手进行实际切换。
首先把所有测试环境下的配置进行备份。因为一旦cluster出现宕机,我们可以快速恢复其至一个单一节点cluster。我们编写了具体的操作程序以及进行了相关压力测试。
在对现有系统的两个DRBD服务器进行从属服务器设置后,我们还设置了其余服务器的从属设置(例如:灾难恢复,备份等)。一切就绪后,我们执行了一次常规的从属升级操作把系统切换到新环境中。
切换前后的架构变化如下图所示:
切换后的优点分析
对正在运行的cluster进行重启和更新时,成功避免了之前造成的通信中断影响。成功以TOI模式(pt-online-schema-change)进行模式变更。写入冲突处理能力得到优化提升。当发现一个冲突后,XtraDB Cluster会返回一个死锁错误信息,在以TOI模式执行DDL语句时同样可触发该错误信息返回。之后,冲突错误会导致应用程序服务器返回一个503错误,而我们的负载平衡层设置会捕获该错误,随后会尝试在另外的服务器上重新递交写入请求。
切换后的缺点分析
部分cluster的关键状态计数器是按状态改变的,例如在执行显示全局状态指令后(SHOW GLOBAL STATUS),其值会重设为0。这样会造成很难根据计数器来进行重要的状态监控,例如流控制,因为其值的频繁变更会造成无法准确监控系统的状态(在使用XtraDB Cluster 5.6的Galera 3.x系统中,该问题已得到解决)。当一写入操作冲突发生时,MySQL动态记录适配器会忽略来自交互语句抛出的异常。
对于系统冷却预热问题仍待进一步改进。目前,我们的应用程序服务器是连接到一个本地的HAproxy实例,该实例会把自身的连接数据发送给一个cluster节点。在执行计划维护任务时,我们只能缓慢地把数据推入另一个节点,以在其能完全承载整个系统负荷前进行缓冲池的预热。在将来,我们会按计划完全转变为多主机环境设置,以确保所有节点都有一个就绪的缓冲池。
英文出自: Highscalability
HAProxy是一款提供高可用性、负载均衡以及基于TCP和HTTP应用的代理软件,HAProxy是完全免费的、借助HAProxy可以快速并且可靠的提供基于TCP和HTTP应用的代理解决方案。HAProxy适用于那些负载较大的web站点,这些站点通常又需要会话保持或七层处理。 HAProxy可以支持数以万计的并发连接,并且HAProxy的运行模式使得它可以很简单安全的整合进架构中,同时可以保护web服务器不被暴露到网络上。
注意此篇博文是基于(PXC安装)的。PXC的安装就不在重复,
环境规划
服务器IP | 节点名称 |
192.168.255.143 | node143(pxc) |
192.168.255.144 | node144(pxc) |
192.168.255.145 | node145(pxc) |
192.168.255.146 | node146(haproxy) |
在node146节点上的操作
1.yum install -y haproxy
2.vim /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
uid 99
gid 99
daemon
#quiet
defaults
log global
mode http
option tcplog
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
frontend pxc-front
bind *:3306
mode tcp
default_backend pxc-back
frontend statas-front
bind *:8088
mode http
default_backend stats-back
backend pxc-back
mode tcp
balance leastconn
option httpchk
server node1 192.168.255.143:3306 check port 9200 inter 12000 rise 3 fall 3 #9200用于检测
server node2 192.168.255.144:3306 check port 9200 inter 12000 rise 3 fall 3
server node2 192.168.255.145:3306 check port 9200 inter 12000 rise 3 fall 3
backend stats-back
mode http
balance roundrobin
stats uri /haproxy/stats
stats auth pxcstats:test
3.查看监听端口:netstat -lntup | grep ha
在cluster节点上的操作:
1.完后输入后台http://192.168.255.146:8088/haproxy/stats(用户名、密码在配置文件中)
则haproxy节点安装成功。
在cluster节点上的操作
1.clustercheck调整
a.改用户名以及mysql命令的全路径(vim /usr/local/mysql/bin/clustercheck)
MYSQL_USERNAME="pxc-monitor"
MYSQL_PASSWORD=""
MYSQL_CMDLINE="/usr/local/mysql/bin/mysql
b.运行/usr/local/mysql/bin/clustercheck 出现200表示clustercheck验证成功
2.xinetd配置
a.yum install -y xinetd.x86_64
b.cp /usr/local/mysql/xinetd.d/mysqlchk /etc/xinetd.d/
d.vim /etc/xinetd.d/mysqlchk 将server的改为/usr/local/mysql/bin/clustercheck (server=/usr/local/mysql/bin/clustercheck)
e.改权限 chmod +x mysqlchk
f.vim /etc/services 在最后新增一行 mysqlchk 9200/tcp # mysqlchk
g.service xinetd start/restart
f.查看一下是否启动成功netstat -tlnup | grep 9200
3.在各个节点之间依次访问:
curl http://192.168.255.143:9200/
curl http://192.168.255.144:9200/
curl http://192.168.255.145:9200/
提示Percona XtraDB Cluster Node is synced表示成功
最后在次访问http://192.168.255.146:8088/haproxy/stats
测试一下
a.运行 for i in `seq 1 100`; do /usr/local/mysql/bin/mysql -h 192.168.255.145 -P3306 -utest -ptest -e "select @@hostname;"; done > /tmp/1.txt
b.查看运行的结果cat /tmp/1.txt
表示环境已经成功安装。
注意:
1.在curl http://192.168.255.144:9200/时 出现如图的提示:
解决办法 在192.168.255.144上执行 iptables -F 这是由于防火墙的问题。
2.还是无法转发的话,安装下图所示的方法操作。
http://www.cnblogs.com/gomysql/p/3864970.html
简介
Percona XtraDB Cluster是MySQL高可用性和可扩展性的解决方案,Percona XtraDB Cluster提供的特性如下:
1.同步复制,事务要么在所有节点提交或不提交。
2.多主复制,可以在任意节点进行写操作。
3.在从服务器上并行应用事件,真正意义上的并行复制。
4.节点自动配置。
5.数据一致性,不再是异步复制。
Percona XtraDB Cluster完全兼容MySQL和Percona Server,表现在:
1.数据的兼容性
2.应用程序的兼容性:无需更改应用程序
1.集群是有节点组成的,推荐配置至少3个节点,但是也可以运行在2个节点上。
2.每个节点都是普通的mysql/percona服务器,可以将现有的数据库服务器组成集群,反之,也可以将集群拆分成单独的服务器。
3.每个节点都包含完整的数据副本。
优点如下:
1.当执行一个查询时,在本地节点上执行。因为所有数据都在本地,无需远程访问。
2.无需集中管理。可以在任何时间点失去任何节点,但是集群将照常工作,不受影响。
3.良好的读负载扩展,任意节点都可以查询。
缺点如下:
1.加入新节点,开销大。需要复制完整的数据。
2.不能有效的解决写缩放问题,所有的写操作都将发生在所有节点上。
3.有多少个节点就有多少重复的数据。
架构图如下:
(图片来源官网)
Percona XtraDB Cluster与MySQL Replication区别在于:
分布式系统的CAP理论。
C— 一致性,所有节点的数据一致。
A— 可用性,一个或多个节点失效,不影响服务请求。
P— 分区容忍性,节点间的连接失效,仍然可以处理请求。
任何一个分布式系统,需要满足这三个中的两个。
MySQL Replication: 可用性和分区容忍性
Percona XtraDB Cluster: 一致性和可用性
因此MySQL Replication并不保证数据的一致性,而Percona XtraDB Cluster提供数据一致性。
Percona XtraDB Cluster组件:
Percona XtraDB Cluster基于XtraDB的Percona Server以及包含写复制集补丁。使用Galera 2.x library,事务型应用下的通用的多主同步复制插件。
Galera 2.x新特性有:
1.IST(Incremental State Transfer)增量状态传输。对于WAN特别有用。
2.RSU(Rolling Schema Update)旋转更新架构。不会阻止对表进行操作。
局限性
1.目前的复制仅仅支持InnoDB存储引擎。任何写入其他引擎的表,包括mysql.*表将不会复制。但是DDL语句会被复制的,因此创建用户将会被复制,但是insert into mysql.user…将不会被复制的。
2.DELETE操作不支持没有主键的表。没有主键的表在不同的节点顺序将不同,如果执行SELECT…LIMIT… 将出现不同的结果集。
3.在多主环境下LOCK/UNLOCK TABLES不支持。以及锁函数GET_LOCK(), RELEASE_LOCK()…
4.查询日志不能保存在表中。如果开启查询日志,只能保存到文件中。
5.允许最大的事务大小由wsrep_max_ws_rows和wsrep_max_ws_size定义。任何大型操作将被拒绝。如大型的LOAD DATA操作。
6.由于集群是乐观的并发控制,事务commit可能在该阶段中止。如果有两个事务向在集群中不同的节点向同一行写入并提交,失败的节点将中止。对于集群级别的中止,集群返回死锁错误代码(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)).
7.XA事务不支持,由于在提交上可能回滚。
8.整个集群的写入吞吐量是由最弱的节点限制,如果有一个节点变得缓慢,那么整个集群将是缓慢的。为了稳定的高性能要求,所有的节点应使用统一的硬件。
9.集群节点建议最少3个。2个也可以运行,但是官方不推荐这么做,因为3个节点是为了预防脑裂。
10.如果DDL语句有问题将破坏集群。建议使用pt-online-schema-change操作DDL。
通过以上的简单了解,相信大家已经有了初步认识,更加深入的内容,推荐童鞋们阅读官方文档。下面我们进行环境的搭建与测试。测试机器信息如下:
注意:Percona-XtraDB-Cluster在启动以后会额外启动端口来进行状态检测,所以请开放相应的端口,默认是4567端口。我测试环境关闭了iptables。
node1 192.168.0.100 node2 192.168.0.101 node3 192.168.0.102
1.安装软件依赖包(添加repl源,再安装依赖,3台server操作一样。)
[root@node1 ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@node1 ~]# yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes socat nc -y
2.安装xtrabackup(PXC同步数据需要用到,为什么使用xtrabackup?自己查询官方文档)
[root@node1 ~]# wget -q http://www.percona.com/downloads/XtraBackup/LATEST/binary/redhat/6/x86_64/percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm [root@node1 ~]# rpm -ivh percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm
3.下载安装Percona-XtraDB-Cluster
[root@node1 ~]# wget http://www.percona.com/downloads/Percona-XtraDB-Cluster-56/LATEST/binary/tarball/Percona-XtraDB-Cluster-5.6.19-rel67.0-25.6.824.Linux.x86_64.tar.gz
[root@node1 ~]# tar xf Percona-XtraDB-Cluster-5.6.19-rel67.0-25.6.824.Linux.x86_64.tar.gz -C /usr/local/ [root@node1 ~]# cd /usr/local/ [root@node1 local]# ln -s Percona-XtraDB-Cluster-5.6.19-rel67.0-25.6.824.Linux.x86_64/ mysql [root@node1 local]# cd mysql [root@node1 mysql]# groupadd mysql [root@node1 mysql]# useradd -r -g mysql mysql [root@node1 mysql]# chown -R mysql . [root@node1 mysql]# chgrp -R mysql . [root@node1 mysql]# cp support-files/my-default.cnf /etc/my.cnf [root@node1 mysql]# mkdir -p /data/mysql [root@node1 mysql]# chown -R mysql.mysql /data/mysql/ [root@node1 mysql]# ./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/
[root@node1 mysql]# chown -R root . [root@node1 mysql]# cp support-files/mysql.server /etc/init.d/mysql [root@node1 mysql]# chmod 755 /etc/init.d/mysql
修改my.cnf配置文件如下:
[root@node1 mysql]# grep dir /etc/my.cnf basedir = /usr/local/mysql datadir = /data/mysql [root@node1 mysql]#
并在[mysqld]段落添如下参数:
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so #库文件 wsrep_cluster_address=gcomm://192.168.0.100,192.168.0.101,192.168.0.102 #节点中所有ip wsrep_node_address=192.168.0.100 #节点的ip wsrep_slave_threads=2 #开启的复制线程数,cpu核数*2 binlog_format=ROW #binlog格式必须为row default_storage_engine=InnoDB #暂时不支持其他存储引擎,只支持innodb,当然可以支持myisam,需要另外参数打开 innodb_autoinc_lock_mode=2 #自增锁的优化 wsrep_cluster_name=pxc-yayun #集群名字 wsrep_sst_auth=sst:yayun #sst模式需要的用户名和密码 wsrep_sst_method=xtrabackup-v2 #采用什么方式复制数据。还支持mysqldump,rsync
启动,进行授权操作,对于第一个节点必须以特殊方式启动,如下:
[root@node1 mysql]# /etc/init.d/mysql --help Usage: mysql {start|stop|restart|restart-bootstrap|reload|force-reload|status|bootstrap-pxc} [ MySQL (Percona XtraDB Cluster) options ] [root@node1 mysql]# /etc/init.d/mysql bootstrap-pxc Bootstrapping PXC (Percona XtraDB Cluster)Starting MySQL (P[ OK ]traDB Cluster)......... [root@node1 mysql]#
进行查看,可以发现启动两个端口
[root@node1 ~]# netstat -nltp | grep mysqld tcp 0 0 0.0.0.0:4567 0.0.0.0:* LISTEN 2964/mysqld tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 2964/mysqld [root@node1 ~]#
进行授权,推荐使用grant方式
mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON * . * TO 'sst'@'localhost' IDENTIFIED BY 'yayun'; Query OK, 0 rows affected (0.03 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.03 sec) mysql>
到这里我们的第一个节点就搞定了,剩下的两个节点配置稍微不同,安装方式都是一样的,不再重复。
node2的配置如下:
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so wsrep_cluster_address=gcomm://192.168.0.100,192.168.0.101,192.168.0.102 wsrep_node_address=192.168.0.101 wsrep_slave_threads=2 binlog_format=ROW default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 wsrep_cluster_name=pxc-yayun wsrep_sst_auth=sst:yayun wsrep_sst_method=xtrabackup-v2
node3的配置如下:
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so wsrep_cluster_address=gcomm://192.168.0.100,192.168.0.101,192.168.0.102 wsrep_node_address=192.168.0.102 wsrep_slave_threads=2 binlog_format=ROW default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 wsrep_cluster_name=pxc-yayun wsrep_sst_auth=sst:yayun wsrep_sst_method=xtrabackup-v2
node2,node3节点都配置完成以后,我们启动,对于第2,3个节点启动和我们普通的MySQL启动方式一样。
node2启动:
[root@node2 ~]# /etc/init.d/mysql start MySQL (Percona XtraDB Cluster) is not running, but lock fil[FAILED]lock/subsys/mysql) exists Starting MySQL (Percona XtraDB Cluster)...............State transfer in progress, setting sleep higher ............. [ OK ] [root@node2 ~]#
日志输出如下:
[root@node2 mysql]# tail -n 20 node2.err 2014-07-25 10:44:29 33172 [Note] InnoDB: Percona XtraDB (http://www.percona.com) 5.6.19-67.0 started; log sequence number 1626646 2014-07-25 10:44:29 33172 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 997242b1-13a5-11e4-aa74-000c29fedc91. 2014-07-25 10:44:29 33172 [Note] RSA private key file not found: /data/mysql//private_key.pem. Some authentication plugins will not work. 2014-07-25 10:44:29 33172 [Note] RSA public key file not found: /data/mysql//public_key.pem. Some authentication plugins will not work. 2014-07-25 10:44:29 33172 [Note] Server hostname (bind-address): '*'; port: 3306 2014-07-25 10:44:29 33172 [Note] IPv6 is available. 2014-07-25 10:44:29 33172 [Note] - '::' resolves to '::'; 2014-07-25 10:44:29 33172 [Note] Server socket created on IP: '::'. 2014-07-25 10:44:29 33172 [Note] Event Scheduler: Loaded 0 events 2014-07-25 10:44:29 33172 [Note] WSREP: Signalling provider to continue. 2014-07-25 10:44:29 33172 [Note] WSREP: inited wsrep sidno 1 2014-07-25 10:44:29 33172 [Note] WSREP: SST received: 2dc360e7-135f-11e4-a4e9-126b1471680b:1 2014-07-25 10:44:29 33172 [Note] /usr/local/mysql/bin/mysqld: ready for connections. Version: '5.6.19-67.0-25.6' socket: '/tmp/mysql.sock' port: 3306 Percona XtraDB Cluster binary (GPL) 5.6.19-25.6, Revision 824, wsrep_25.6.r4111 2014-07-25 10:44:30 33172 [Note] WSREP: 1.0 (node2): State transfer from 0.0 (node1) complete. 2014-07-25 10:44:30 33172 [Note] WSREP: Shifting JOINER -> JOINED (TO: 1) 2014-07-25 10:44:30 33172 [Note] WSREP: Member 1.0 (node2) synced with group. 2014-07-25 10:44:30 33172 [Note] WSREP: Shifting JOINED -> SYNCED (TO: 1) 2014-07-25 10:44:30 33172 [Note] WSREP: Synchronized with group, ready for connections 2014-07-25 10:44:30 33172 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification. [root@node2 mysql]#
node3启动:
[root@node3 ~]# /etc/init.d/mysql start MySQL (Percona XtraDB Cluster) is not running, but lock fil[FAILED]lock/subsys/mysql) exists Starting MySQL (Percona XtraDB Cluster)....................................State transfer in progress, setting sleep higher ..... [ OK ] [root@node3 ~]#
日志输出如下:
[root@node3 mysql]# tail -n 20 node3.err 2014-07-25 10:49:26 38949 [Note] InnoDB: Percona XtraDB (http://www.percona.com) 5.6.19-67.0 started; log sequence number 1626646 2014-07-25 10:49:26 38949 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 4ad6df19-13a6-11e4-aae1-000c29d894d0. 2014-07-25 10:49:27 38949 [Note] RSA private key file not found: /data/mysql//private_key.pem. Some authentication plugins will not work. 2014-07-25 10:49:27 38949 [Note] RSA public key file not found: /data/mysql//public_key.pem. Some authentication plugins will not work. 2014-07-25 10:49:27 38949 [Note] Server hostname (bind-address): '*'; port: 3306 2014-07-25 10:49:27 38949 [Note] IPv6 is available. 2014-07-25 10:49:27 38949 [Note] - '::' resolves to '::'; 2014-07-25 10:49:27 38949 [Note] Server socket created on IP: '::'. 2014-07-25 10:49:27 38949 [Note] Event Scheduler: Loaded 0 events 2014-07-25 10:49:27 38949 [Note] WSREP: Signalling provider to continue. 2014-07-25 10:49:27 38949 [Note] WSREP: inited wsrep sidno 1 2014-07-25 10:49:27 38949 [Note] WSREP: SST received: 2dc360e7-135f-11e4-a4e9-126b1471680b:1 2014-07-25 10:49:27 38949 [Note] /usr/local/mysql/bin/mysqld: ready for connections. Version: '5.6.19-67.0-25.6' socket: '/tmp/mysql.sock' port: 3306 Percona XtraDB Cluster binary (GPL) 5.6.19-25.6, Revision 824, wsrep_25.6.r4111 2014-07-25 10:49:28 38949 [Note] WSREP: 0.0 (node3): State transfer from 1.0 (node1) complete. 2014-07-25 10:49:28 38949 [Note] WSREP: Shifting JOINER -> JOINED (TO: 1) 2014-07-25 10:49:28 38949 [Note] WSREP: Member 0.0 (node3) synced with group. 2014-07-25 10:49:28 38949 [Note] WSREP: Shifting JOINED -> SYNCED (TO: 1) 2014-07-25 10:49:28 38949 [Note] WSREP: Synchronized with group, ready for connections 2014-07-25 10:49:28 38949 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification. [root@node3 mysql]#
如果启动失败,日志里面也会有提示的,通常启动失败的原因有如下:
(1)配置文件错误
(2)防火墙没有开放相应的端口,比如默认的4567端口
(3)忘记进行授权账号
(4)xtrabackup没有安装或者安装有问题
下面我们进行相关的测试,比如在node节点创建表,插入数据,看另外两个节点是否有数据。
node1节点创建表t1,插入数据,在另外两个节点也可以看见:
mysql> create database yayun; Query OK, 1 row affected (0.02 sec) mysql> use yayun Database changed mysql> create table t1 ( id int,name char(20)) engine=innodb; Query OK, 0 rows affected (0.03 sec) mysql> insert into t1 select 1,'yayun'; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> select * from t1; +------+-------+ | id | name | +------+-------+ | 1 | yayun | +------+-------+ 1 row in set (0.00 sec) mysql>
node2节点:
mysql> select * from yayun.t1; +------+-------+ | id | name | +------+-------+ | 1 | yayun | +------+-------+ 1 row in set (0.00 sec) mysql>
node3节点:
mysql> select * from yayun.t1; +------+-------+ | id | name | +------+-------+ | 1 | yayun | +------+-------+ 1 row in set (0.00 sec) mysql>
到这里搭建就基本结束了。3个节点同时支持write/read操作。更加详细的介绍以及细节建议大家参考官方文档。
总结:
Percona XtraDB Cluster现在已经有企业在使用了,我这里只是简单的搭建以及测试,如果线上需要使用我们还需要进行相关压力测试。比如使用sysbench,或者tpcc-mysql。
通常我们单独使用Percona XtraDB Cluster也没有任何问题的,如果使用通过结合harproxy,或者lvs+keepalived的方式来使用会更加的完美。前面说到的那些局限性通常我们很少能够触发到,所以使用Percona XtraDB Cluster来实现高可用是非常不错的选择。后续我会进行一个压力测试对比。
参考资料:
http://www.percona.com/doc/percona-xtradb-cluster/5.6/intro.html
http://www.percona.com/doc/percona-xtradb-cluster/5.6/howtos/cenots_howto.html
....