MySQL Fabric实验(三)HA与Sharding
2016-01-02 11:21
507 查看
实验步骤:
1. 安装虚拟机
使用VirtualBox安装四个CentOS release 6.4虚拟机,安装Python 2.6或以上版本,关闭iptables和selinux。虚拟机和网卡说明如下表所示。
因为只是出于实验的目的,所以使用root用户安装MySQL和Fabric,下载的软件包分别是mysql-5.7.10-linux-glibc2.5-x86_64.tar和mysql-utilities-1.5.6.tar.gz。实验环境如下图所示。
2. 在全部四个虚拟机上安装MySQL
3. 在fab_connector上安装Fabric
4. 准备配置文件
(1)在fab_connector上准备如下3个配置文件
(2)在fab1上准备如下6个配置文件
(3)在fab2上准备如下6个配置文件
(4)在fab3上准备如下6个配置文件
5. 在fab_connector上启动MySQL
6. 在fab1、fab2、fab3每个虚拟机上启动3个MySQL实例(下面的命令在三个虚拟机上都要执行)
7. 在fab_connector上启动Fabric
8. 在fab_connector上配置HA
9. 在fab_connector上配置Sharding
10. 在fab1上的global-group组上建立测试表
192.168.56.102上3326复制到192.168.56.103上3326(global-group HA组内复制)
192.168.56.102上3326复制到192.168.56.104上3326(global-group HA组内·复制)
192.168.56.102上3326复制到192.168.56.103:3327(global-group向my_group1复制)
192.168.56.102上3326复制到192.168.56.104:3328(global-group向my_group2复制)
192.168.56.103:3327复制到192.168.56.102上3327(my_group1 HA组内复制)
192.168.56.103:3327复制到192.168.56.104上3327(my_group1 HA组内复制)
192.168.56.104:3328复制到192.168.56.102上3328(my_group2 HA组内复制)
192.168.56.104:3328复制到192.168.56.103上3328(my_group2 HA组内复制)
11. 执行Java应用程序,向测试表中插入20条数据,Java程序代码如下。
12. 分别查询9个实例,检查执行结果
在192.168.56.102、192.168.56.103、192.168.56.104上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3326 -e "select * from test.chat_message"
在192.168.56.102、192.168.56.103、192.168.56.104上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3327 -e "select * from test.chat_message"
在192.168.56.102、192.168.56.103、192.168.56.104上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3328 -e "select * from test.chat_message"
从结果可以看到,global-group组中没有数据,my_group1和my_group2组中按Fabric内置的HASH算法分别插入了9条和11条数据,并且复制到了HA组内其它服务器中。
13. 在fab2、fab3两个虚拟机上新各建1个MySQL实例,端口为3329,分别用于测试remove_shard、split_shard
(1)准备配置文件
# 在fab2上准备如下2个配置文件
# cat /etc/my_group_4_init.cnf
[mysqld]
basedir=/root/mysql
datadir=/var/lib/group_4
port=3329
socket=/var/lib/group_4/mysql.sock
plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin
# cat /etc/my_group_4.cnf
[mysqld]
basedir=/root/mysql
datadir=/var/lib/group_4
port=3329
socket=/var/lib/group_4/mysql.sock
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
report-host=fab_group1
report-port=3329
server-id=24
log-bin=fab1a-bin.log
rpl_semi_sync_slave_enabled=1
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 1000
# 在fab3上准备如下2个配置文件
# cat /etc/my_group_4_init.cnf
[mysqld]
basedir=/root/mysql
datadir=/var/lib/group_4
port=3329
socket=/var/lib/group_4/mysql.sock
plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin
# cat /etc/my_group_4.cnf
[mysqld]
basedir=/root/mysql
datadir=/var/lib/group_4
port=3329
socket=/var/lib/group_4/mysql.sock
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
report-host=fab_group2
report-port=3329
server-id=34
log-bin=fab1a-bin.log
rpl_semi_sync_slave_enabled=1
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 1000 (2)启动实例(下面的命令在两个虚拟机上都要执行)
在192.168.56.103上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3327 -e "select * from test.chat_message"
mysql -u root -p -h127.0.0.1 -P3329 -e "select * from test.chat_message"
从结果可以看到,分片1中的数据复制到了my_group3中。move_shard缺省情况下实际上是执行了一次备份还原数据操作,而不是迁移数据,正如Fabric帮助中所描述的:
sharding move_shard shard_id group_id [--update_only] [--synchronous]
Move the shard represented by the shard_id to the destination group.
By default this operation takes a backup, restores it on the
destination group and guarantees that source and destination
groups are synchronized before pointing the shard to the new
group. If users just want to update the state store and skip these
provisioning steps, the update_only parameter must be set to true.
现在my_group1中的数据还在,但其中已经没有分片了。此时插入新的数据,将会插入到my_group2、my_group3中。修改执行Java程序再插入20条新数据,然后查询数据。
在192.168.56.103上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3328 -e "select * from test.chat_message"
mysql -u root -p -h127.0.0.1 -P3329 -e "select * from test.chat_message"
从图中可以看到,my_group3上的分片1中新增了16条数据,my_group2上的分片2中新增了4条数据。
16. 测试split_shard
从图中可以看出,分片2的定义没有了,被分成了分片3和4,分别存在于my_group2和my_group4组中。
在192.168.56.104上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3328 -e "select * from test.chat_message"
mysql -u root -p -h127.0.0.1 -P3329 -e "select * from test.chat_message"
从图中可以看到,原来my_group2上分片2中的15条数据,现在被分布到my_group2和my_group4上,my_group2上有10条数据,my_group4上有5条数据。
当前限制
当前版本的MySQL Fabric有如下限制:
分片对应用并不完全透明。应用不需要知道数据行存储在哪个服务器,也不需要关心数据存储的位置是否改变,但它在访问数据库时需要提供分片键。
所有的事务和查询被限制在分片表的单一分片和非分片表中。例如,多个分片的连接查询是不支持的。
连接器执行路由功能,这避免了基于代理的解决方案带来的额外延迟,但同时意味着需要Fabric连接器,当前支持PHP、Python和Java。
MySQL Fabric 本身并没有失败冗余,失败时需要重启。注意这并不表示是服务器池(HA或分片)的单点故障,因为当MySQL Fabric进程失效时,连接器可以使用本地缓存继续路由操作。
参考:
MySQL Fabric官方文档
http://mysqlhighavailability.com/mysql-fabric-adding-high-availability-and-scaling-to-mysql/
1. 安装虚拟机
使用VirtualBox安装四个CentOS release 6.4虚拟机,安装Python 2.6或以上版本,关闭iptables和selinux。虚拟机和网卡说明如下表所示。
主机名 | 内部网络IP | 说明 |
fab_connector | 192.168.56.101 | 安装Fabric和MySQL,建立一个MySQL实例,使用缺省的3306端口,存储MySQL实例的状态和路由信息 |
fab1 | 192.168.56.102 | 安装MySQL,建立三个MySQL数据库实例,端口分别是3326、3327、3328 |
fab2 | 192.168.56.103 | 安装MySQL,建立三个MySQL数据库实例,端口分别是3326、3327、3328 |
fab3 | 192.168.56.104 | 安装MySQL,建立三个MySQL数据库实例,端口分别是3326、3327、3328 |
虚拟机名称 | 网卡 | 连接方式 | 说明 |
fab_connector | 网卡1 | 网络地址转换(NAT) | 用于虚拟机访问宿主机和外网 |
网卡2 | 桥接网卡(192.168.1.119) | 用于宿主机访问虚拟机 | |
网卡3 | 内部网络 | 用于Fabric组内互联 | |
fab1 | 网卡1 | 网络地址转换(NAT) | 用于虚拟机访问宿主机和外网 |
网卡2 | 内部网络 | 用于Fabric组内互联 | |
fab2 | 网卡1 | 网络地址转换(NAT) | 用于虚拟机访问宿主机和外网 |
网卡2 | 内部网络 | 用于Fabric组内互联 | |
fab3 | 网卡1 | 网络地址转换(NAT) | 用于虚拟机访问宿主机和外网 |
网卡2 | 内部网络 | 用于Fabric组内互联 |
2. 在全部四个虚拟机上安装MySQL
cd /root tar xvf mysql-5.7.10-linux-glibc2.5-x86_64.tar tar zxvf mysql-5.7.10-linux-glibc2.5-x86_64.tar.gz ln -s mysql-5.6.13-linux-glibc2.5-x86_64 mysql groupadd mysql useradd -r -g mysql mysql chown -R mysql .
3. 在fab_connector上安装Fabric
cd /root tar zxvf mysql-utilities-1.5.6.tar.gz cd mysql-utilities-1.5.6 sudo python setup.py install
4. 准备配置文件
(1)在fab_connector上准备如下3个配置文件
[root@fab_connector ~]# cat /etc/my_fabric_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/mysql port=3306 socket=/var/lib/mysql/mysql.sock [root@fab_connector ~]# cat /etc/my_fabric.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 port=3306 report-host=fab_connector report-port=3306 server-id=1 log-bin=fab-bin.log [root@fab_connector ~]# cat /etc/mysql/fabric.cfg [DEFAULT] prefix = sysconfdir = /etc logdir = /var/log [statistics] prune_time = 3600 [logging] url = file:///var/log/fabric.log level = INFO [storage] auth_plugin = mysql_native_password database = fabric user = fabric address = localhost:3306 connection_delay = 1 connection_timeout = 6 password = secret connection_attempts = 6 [failure_tracking] notification_interval = 60 notification_clients = 50 detection_timeout = 1 detection_interval = 6 notifications = 300 detections = 3 failover_interval = 0 prune_time = 3600 [servers] restore_user = fabric unreachable_timeout = 5 backup_password = secret backup_user = fabric user = fabric restore_password = secret password = secret [connector] ttl = 1 [protocol.xmlrpc] disable_authentication = no ssl_cert = realm = MySQL Fabric ssl_key = ssl_ca = threads = 5 user = admin address = 192.168.1.119:32274 password = secret [executor] executors = 5 [sharding] prune_limit = 10000 mysqldump_program = /root/mysql/bin/mysqldump mysqlclient_program = /root/mysql/bin/mysql [protocol.mysql] disable_authentication = no ssl_cert = ssl_key = ssl_ca = user = admin address = 192.168.1.119:32275 password = secret
(2)在fab1上准备如下6个配置文件
[root@fab_global_group ~]# cat /etc/my_group_1_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_1 port=3326 socket=/var/lib/group_1/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_global_group ~]# cat /etc/my_group_2_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_2 port=3327 socket=/var/lib/group_2/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_global_group ~]# cat /etc/my_group_3_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_3 port=3328 socket=/var/lib/group_3/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_global_group ~]# cat /etc/my_group_1.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_1 port=3326 socket=/var/lib/group_1/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_global_group report-port=3326 server-id=11 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000 [root@fab_global_group ~]# cat /etc/my_group_2.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_2 port=3327 socket=/var/lib/group_2/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_global_group report-port=3327 server-id=12 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000 [root@fab_global_group ~]# cat /etc/my_group_3.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_3 port=3328 socket=/var/lib/group_3/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_global_group report-port=3328 server-id=13 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000
(3)在fab2上准备如下6个配置文件
[root@fab_group1 ~]# cat /etc/my_group_1_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_1 port=3326 socket=/var/lib/group_1/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_group1 ~]# cat /etc/my_group_2_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_2 port=3327 socket=/var/lib/group_2/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_group1 ~]# cat /etc/my_group_3_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_3 port=3328 socket=/var/lib/group_3/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_group1 ~]# cat /etc/my_group_1.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_1 port=3326 socket=/var/lib/group_1/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_group1 report-port=3326 server-id=21 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000 [root@fab_group1 ~]# cat /etc/my_group_2.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_2 port=3327 socket=/var/lib/group_2/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_group1 report-port=3327 server-id=22 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000 [root@fab_group1 ~]# cat /etc/my_group_3.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_3 port=3328 socket=/var/lib/group_3/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_group1 report-port=3328 server-id=23 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000
(4)在fab3上准备如下6个配置文件
[root@fab_group2 ~]# cat /etc/my_group_1_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_1 port=3326 socket=/var/lib/group_1/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_group2 ~]# cat /etc/my_group_2_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_2 port=3327 socket=/var/lib/group_2/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_group2 ~]# cat /etc/my_group_3_init.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_3 port=3328 socket=/var/lib/group_3/mysql.sock plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin [root@fab_group2 ~]# cat /etc/my_group_1.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_1 port=3326 socket=/var/lib/group_1/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_group2 report-port=3326 server-id=31 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000 [root@fab_group2 ~]# cat /etc/my_group_2.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_2 port=3327 socket=/var/lib/group_2/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_group2 report-port=3327 server-id=32 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000 [root@fab_group2 ~]# cat /etc/my_group_3.cnf [mysqld] basedir=/root/mysql datadir=/var/lib/group_3 port=3328 socket=/var/lib/group_3/mysql.sock binlog-format=ROW log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE sync-master-info=1 report-host=fab_group2 report-port=3328 server-id=33 log-bin=fab1a-bin.log rpl_semi_sync_slave_enabled=1 rpl_semi_sync_master_enabled = 1 rpl_semi_sync_master_timeout = 1000
5. 在fab_connector上启动MySQL
mysqld --defaults-file=/etc/my_fabric_init.cnf --initialize # 记下初始化生成的临时密码 chown -R mysql /var/lib/mysql mysqld --defaults-file=/etc/my_fabric_init.cnf --user=mysql & mysql -u root -p -h127.0.0.1 # 修改初始密码,添加fabric用户 ALTER USER USER() IDENTIFIED BY 'new_password'; CREATE USER 'fabric'@'localhost' IDENTIFIED BY 'secret' GRANT ALL ON fabric.* TO 'fabric'@'localhost'"; # 重启MySQL mysqladmin -u root --protocol=tcp -h127.0.0.1 -p shutdown mysqld --defaults-file=/etc/my_fabric.cnf --user=mysql &
6. 在fab1、fab2、fab3每个虚拟机上启动3个MySQL实例(下面的命令在三个虚拟机上都要执行)
mkdir /var/lib/group_1 mkdir /var/lib/group_2 mkdir /var/lib/group_3 mysqld --defaults-file=/etc/my_group_1_init.cnf --initialize mysqld --defaults-file=/etc/my_group_2_init.cnf --initialize mysqld --defaults-file=/etc/my_group_3_init.cnf --initialize # 记下初始化生成的临时密码 chown -R mysql /var/lib/group_1 chown -R mysql /var/lib/group_2 chown -R mysql /var/lib/group_3 # 修改初始密码,添加fabric用户 mysqld --defaults-file=/etc/my_group_1_init.cnf --user=mysql & mysql -u root -p -h127.0.0.1 -P3326 ALTER USER USER() IDENTIFIED BY 'new_password'; CREATE USER 'fabric'@'%' IDENTIFIED BY 'secret'; GRANT ALL ON *.* TO 'fabric'@'%'; INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; mysqld --defaults-file=/etc/my_group_2_init.cnf --user=mysql & mysql -u root -p -h127.0.0.1 -P3327 ALTER USER USER() IDENTIFIED BY 'new_password'; CREATE USER 'fabric'@'%' IDENTIFIED BY 'secret'; GRANT ALL ON *.* TO 'fabric'@'%'; INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; mysqld --defaults-file=/etc/my_group_3_init.cnf --user=mysql & mysql -u root -p -h127.0.0.1 -P3328 ALTER USER USER() IDENTIFIED BY 'new_password'; CREATE USER 'fabric'@'%' IDENTIFIED BY 'secret'; GRANT ALL ON *.* TO 'fabric'@'%'; INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; # 重启3个MySQL实例 mysqladmin -u root --protocol=tcp -h127.0.0.1 -P3326 -p shutdown mysqladmin -u root --protocol=tcp -h127.0.0.1 -P3327 -p shutdown mysqladmin -u root --protocol=tcp -h127.0.0.1 -P3328 -p shutdown mysqld --defaults-file=/etc/my_group_1.cnf --user=mysql & mysqld --defaults-file=/etc/my_group_2.cnf --user=mysql & mysqld --defaults-file=/etc/my_group_3.cnf --user=mysql & # 查看3个MySQL实例进程 ps -ef | grep mysql
7. 在fab_connector上启动Fabric
# 在状态存储(MySQL数据库实例)中建立Fabric库 mysqlfabric manage setup # 以守护进程方式启动Fabric mysqlfabric manage start --daemonize # 检查fabric进程是否运行 mysqlfabric manage ping
8. 在fab_connector上配置HA
# 建立HA组 mysqlfabric group create global-group mysqlfabric group create my_group1 mysqlfabric group create my_group2 # 在HA组中添加服务器 mysqlfabric group add global-group 192.168.56.102:3326 mysqlfabric group add global-group 192.168.56.103:3326 mysqlfabric group add global-group 192.168.56.104:3326 mysqlfabric group add my_group1 192.168.56.102:3327 mysqlfabric group add my_group1 192.168.56.103:3327 mysqlfabric group add my_group1 192.168.56.104:3327 mysqlfabric group add my_group2 192.168.56.102:3328 mysqlfabric group add my_group2 192.168.56.103:3328 mysqlfabric group add my_group2 192.168.56.104:3328 # 提升主服务器 mysqlfabric group promote global-group --slave_id=192.168.56.102:3326 mysqlfabric group promote my_group1 --slave_id=192.168.56.103:3327 mysqlfabric group promote my_group2 --slave_id=192.168.56.104:3328 # 至此HA特性配置完毕,使用下面的命令检查Fabric配置运行情况 # 查看HA组 mysqlfabric group lookup_groups
# 查看HA组中的服务器 mysqlfabric group lookup_servers global-group
mysqlfabric group lookup_servers my_group1
mysqlfabric group lookup_servers my_group2
# 查看组的健康状况 mysqlfabric group health global-group
mysqlfabric group health my_group1
mysqlfabric group health my_group2
9. 在fab_connector上配置Sharding
# 定义分片映射方法 mysqlfabric sharding create_definition HASH global-group # 添加分片表及其字段 mysqlfabric sharding add_table 1 test.chat_message src_userid # 添加分片 mysqlfabric sharding add_shard 1 "my_group1,my_group2" --state=enabled # 至此Sharding特性配置完毕,使用下面的S命令检查Sharding配置情况 mysql -u root -p -h127.0.0.1 -e "select * from fabric.shard_maps"
mysql -u root -p -h127.0.0.1 -e "select * from fabric.shard_ranges"
mysql -u root -p -h127.0.0.1 -e "select * from fabric.shard_tables"
mysql -u root -p -h127.0.0.1 -e "select * from fabric.shards"
10. 在fab1上的global-group组上建立测试表
mysql -u root -p -h127.0.0.1 -P3326 create database test; use test; CREATE TABLE chat_message ( src_userid bigint(20) NOT NULL PRIMARY KEY );执行完后在fab1、fab2、fab3的9个实例中都已经建好了测试库表。
192.168.56.102上3326复制到192.168.56.103上3326(global-group HA组内复制)
192.168.56.102上3326复制到192.168.56.104上3326(global-group HA组内·复制)
192.168.56.102上3326复制到192.168.56.103:3327(global-group向my_group1复制)
192.168.56.102上3326复制到192.168.56.104:3328(global-group向my_group2复制)
192.168.56.103:3327复制到192.168.56.102上3327(my_group1 HA组内复制)
192.168.56.103:3327复制到192.168.56.104上3327(my_group1 HA组内复制)
192.168.56.104:3328复制到192.168.56.102上3328(my_group2 HA组内复制)
192.168.56.104:3328复制到192.168.56.103上3328(my_group2 HA组内复制)
11. 执行Java应用程序,向测试表中插入20条数据,Java程序代码如下。
import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import org.apache.commons.lang3.RandomStringUtils; import com.mysql.fabric.jdbc.FabricMySQLConnection; public class Main { private static String URL = "jdbc:mysql:fabric://192.168.1.119:32274/test?fabricShardTable=chat_message&fabricUsername=admin&fabri cPassword=secret"; private static String USERNAME = "fabric"; private static String PWD = "secret"; private static int MAX = 20; private static String SQL = "insert into chat_message(src_userid) values(?)"; public static void main(String[] args) throws ClassNotFoundException, SQLException, UnsupportedEncodingException { long start = System.currentTimeMillis(); testInsert(); long end = System.currentTimeMillis(); System.out.println((end - start)); System.out.println(MAX / ((end - start) / 1000)); } private static Connection getConnection() throws SQLException, ClassNotFoundException { Class.forName("com.mysql.fabric.jdbc.FabricMySQLDriver"); Connection con = DriverManager.getConnection(URL,USERNAME,PWD); return con; } private static void testInsert() throws ClassNotFoundException, SQLException { int i = 0; Connection con = getConnection(); con.setAutoCommit(false); while (i < MAX) { FabricMySQLConnection fcon=(FabricMySQLConnection) con; fcon.setShardKey(String.valueOf(i)); PreparedStatement pt = con.prepareStatement(SQL); pt.setLong(1, i); pt.executeUpdate(); fcon.commit(); i++; //fcon.close(); System.out.println(i); } con.close(); } }
12. 分别查询9个实例,检查执行结果
在192.168.56.102、192.168.56.103、192.168.56.104上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3326 -e "select * from test.chat_message"
在192.168.56.102、192.168.56.103、192.168.56.104上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3327 -e "select * from test.chat_message"
在192.168.56.102、192.168.56.103、192.168.56.104上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3328 -e "select * from test.chat_message"
从结果可以看到,global-group组中没有数据,my_group1和my_group2组中按Fabric内置的HASH算法分别插入了9条和11条数据,并且复制到了HA组内其它服务器中。
13. 在fab2、fab3两个虚拟机上新各建1个MySQL实例,端口为3329,分别用于测试remove_shard、split_shard
(1)准备配置文件
# 在fab2上准备如下2个配置文件
# cat /etc/my_group_4_init.cnf
[mysqld]
basedir=/root/mysql
datadir=/var/lib/group_4
port=3329
socket=/var/lib/group_4/mysql.sock
plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin
# cat /etc/my_group_4.cnf
[mysqld]
basedir=/root/mysql
datadir=/var/lib/group_4
port=3329
socket=/var/lib/group_4/mysql.sock
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
report-host=fab_group1
report-port=3329
server-id=24
log-bin=fab1a-bin.log
rpl_semi_sync_slave_enabled=1
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 1000
# 在fab3上准备如下2个配置文件
# cat /etc/my_group_4_init.cnf
[mysqld]
basedir=/root/mysql
datadir=/var/lib/group_4
port=3329
socket=/var/lib/group_4/mysql.sock
plugin_dir=/root/mysql-5.7.10-linux-glibc2.5-x86_64/lib/plugin
# cat /etc/my_group_4.cnf
[mysqld]
basedir=/root/mysql
datadir=/var/lib/group_4
port=3329
socket=/var/lib/group_4/mysql.sock
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
report-host=fab_group2
report-port=3329
server-id=34
log-bin=fab1a-bin.log
rpl_semi_sync_slave_enabled=1
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 1000 (2)启动实例(下面的命令在两个虚拟机上都要执行)
mkdir /var/lib/group_4 mysqld --defaults-file=/etc/my_group_4_init.cnf --initialize # 记下初始化生成的临时密码 chown -R mysql /var/lib/group_4 # 修改初始密码,添加fabric用户 mysqld --defaults-file=/etc/my_group_4_init.cnf --user=mysql & mysql -u root -p -h127.0.0.1 -P3329 ALTER USER USER() IDENTIFIED BY 'new_password'; CREATE USER 'fabric'@'%' IDENTIFIED BY 'secret'; GRANT ALL ON *.* TO 'fabric'@'%'; INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; # 重启MySQL实例 mysqladmin -u root --protocol=tcp -h127.0.0.1 -P3329 -p shutdown mysqld --defaults-file=/etc/my_group_4.cnf --user=mysql & # 查看MySQL实例进程 ps -ef | grep mysql14. 在fab_connector上配置HA
# 建立HA组 mysqlfabric group create my_group3 mysqlfabric group create my_group4 # 在HA组中添加服务器 mysqlfabric group add my_group3 192.168.56.103:3329 mysqlfabric group add my_group4 192.168.56.104:3329 # 提升主服务器 mysqlfabric group promote my_group3 mysqlfabric group promote my_group415. 测试move_shard
# 把分片1从my_group1移动到my_group3 mysqlfabric sharding move_shard 1 my_group3执行前后的分片定义如下图所示。
在192.168.56.103上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3327 -e "select * from test.chat_message"
mysql -u root -p -h127.0.0.1 -P3329 -e "select * from test.chat_message"
从结果可以看到,分片1中的数据复制到了my_group3中。move_shard缺省情况下实际上是执行了一次备份还原数据操作,而不是迁移数据,正如Fabric帮助中所描述的:
sharding move_shard shard_id group_id [--update_only] [--synchronous]
Move the shard represented by the shard_id to the destination group.
By default this operation takes a backup, restores it on the
destination group and guarantees that source and destination
groups are synchronized before pointing the shard to the new
group. If users just want to update the state store and skip these
provisioning steps, the update_only parameter must be set to true.
现在my_group1中的数据还在,但其中已经没有分片了。此时插入新的数据,将会插入到my_group2、my_group3中。修改执行Java程序再插入20条新数据,然后查询数据。
在192.168.56.103上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3328 -e "select * from test.chat_message"
mysql -u root -p -h127.0.0.1 -P3329 -e "select * from test.chat_message"
从图中可以看到,my_group3上的分片1中新增了16条数据,my_group2上的分片2中新增了4条数据。
16. 测试split_shard
# 把分片2分到my_group4组中 mysqlfabric sharding split_shard 2 my_group4执行后的分片定义如下图所示。
从图中可以看出,分片2的定义没有了,被分成了分片3和4,分别存在于my_group2和my_group4组中。
在192.168.56.104上执行,结果如下图所示。
mysql -u root -p -h127.0.0.1 -P3328 -e "select * from test.chat_message"
mysql -u root -p -h127.0.0.1 -P3329 -e "select * from test.chat_message"
从图中可以看到,原来my_group2上分片2中的15条数据,现在被分布到my_group2和my_group4上,my_group2上有10条数据,my_group4上有5条数据。
当前限制
当前版本的MySQL Fabric有如下限制:
分片对应用并不完全透明。应用不需要知道数据行存储在哪个服务器,也不需要关心数据存储的位置是否改变,但它在访问数据库时需要提供分片键。
所有的事务和查询被限制在分片表的单一分片和非分片表中。例如,多个分片的连接查询是不支持的。
连接器执行路由功能,这避免了基于代理的解决方案带来的额外延迟,但同时意味着需要Fabric连接器,当前支持PHP、Python和Java。
MySQL Fabric 本身并没有失败冗余,失败时需要重启。注意这并不表示是服务器池(HA或分片)的单点故障,因为当MySQL Fabric进程失效时,连接器可以使用本地缓存继续路由操作。
参考:
MySQL Fabric官方文档
http://mysqlhighavailability.com/mysql-fabric-adding-high-availability-and-scaling-to-mysql/
相关文章推荐
- Ubuntu 14.04 安装 64位的 MySQL 5.7.9
- 阿里云服务器Ubuntu安装mysql
- MySQL安装报2503错误
- 多种方法修改Mysql root密码
- navicat for mysql 10.1.7注册码
- 在mysql中创建索引,提升获取数据库数据效率
- MYSQL 内部 一个故事@MySQL DBA
- mysql主从复制详解
- mysql触发器
- mysql游标
- Mysql笔记——DQL
- Mysql笔记——DCL
- Mysql笔记——DML
- Mysql笔记——DDL
- Mysql笔记——触发器简单实例
- mysql技能点
- MySQL的存储引擎造成的事务无法回滚
- C#连接MySQL数据库
- 记——Mysql乱码
- mysql5.6.24 慢查询日志配置