PXC系列学习笔记（四）——搭建双机热备的MyCat集群
一、介绍 目前已经搭建好了2套PXC集群，使用了单台mycat进行数据路由，在数据库层实现了高可用，但若mycat宕机，后端数据库依然无法使用，故还需要搭建多一台mycat，结合HAProxy和Keepalived实现负载均衡、双机热备。 二、集群架构 三、搭建 服务器资源规划如下 名称 IP CPU 内存 磁盘 服务 pxc3 192.168.1.33 1 2G 40G mycat pxc4 192.168.1.35 1 2G 40G haproxy、Keepalived pxc5 192.168.1.36 1 2G 40G mycat pxc6 192.168.1.37 1 2G 40G haproxy、Keepalived 1. 安装mycat集群 用两个虚拟机实例，各自部署MyCat，采用相同配置 2. 安装Haproxy集群 用一个虚拟机实例部署Haproxy 安装Haproxy，需要开放两个端口，3306（TCP转发），4001（监控界面） $ yum install -y haproxy 编辑配置文件 $ vi /etc/haproxy/haproxy.cfg 由于该节点同时也运行了PXC数据库，3306端口已经占用，故使用13306端口 global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats defaults mode http log global option httplog 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 listen admin_stats bind 0.0.0.0:4001 mode http stats uri /dbs stats realm Global\ statistics stats auth admin:Abc%6870 listen proxy_mysql bind 0.0.0.0:13306 mode tcp balance roundrobin option tcplog server mycat_1 192.168.1.33:8066 check port 8066 weight 1 maxconn 2000 server mycat_2 192.168.1.36:8066 check port 8066 weight 1 maxconn 2000 option tcpka 启动Haproxy $ service haproxy start 访问Haproxy监控画面 http://192.168.1.35:4001/dbs 用另外一个虚拟机同样按照上述操作安装Haproxy 3. 安装Keepalived集群 在某个Haproxy虚拟机实例上部署Keepalived 开启防火墙的VRRP协议 #开启VRRP firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --protocol vrrp -j ACCEPT # iptable配置 iptables -I INPUT -p vrrp -j ACCEPT #应用设置 firewall-cmd --reload 安装Keepalived yum install -y keepalived 编辑配置文件 vi /etc/keepalived/keepalived.conf vrrp_instance VI_1 { state MASTER # 争抢虚拟IP，若不争抢，则设置为slave interface ens192 virtual_router_id 51 # 唯一ID，范围0-255 priority 100 # 抢占权重 advert_int 1 # 心跳检测间隔时间 authentication { # 心跳检测账户和密码 auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.1.9 # 新虚拟IP } } 启动Keepalived $ systemctl start keepalived 在两台Keepalived节点上ping虚拟IP，看是否已经创建并可以访问 $ ping 192.168.1.9 在另外一个Haproxy虚拟机上，按照上述方法部署Keepalived 使用MySQL客户端连接192.168.1.9，执行增删改查数据
PXC系列学习笔记（三）——MyCat安装和读写分离配置
一. 介绍 由于每个PXC集群有3个节点，故需要使用mycat进行读写分离，分摊单个节点的读写压力。 同时由于有两套PXC集群，故需要针对不同表采用不同分片算法进行数据路由。 因为mycat不支持跨分片表连接，还需要配置父子表等，让需要表连接操作的数据路由到同一个分片中。 二. JDK安装与配置 安装JDK #搜索JDK版本 yum search jdk #安装JDK1.8开发版 yum install java-1.8.0-openjdk-devel.x86_64 配置环境变量 #查看JDK安装路径 ls -lrt /etc/alternatives/java vi /etc/profile #在文件结尾加上JDK路径 JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/ PATH=$JAVA_HOME/bin:$PATH export PATH JAVA_HOME source /etc/profile 三. 创建数据表 创建两套PXC集群，每套3台机器 在两组PXC集群中分别创建t_user数据表 CREATE TABLE t_user ( id INT(10) UNSIGNED NOT NULL, username VARCHAR(200) NOT NULL, password VARCHAR(200) NOT NULL, tel CHAR(11) NOT NULL, locked TINYINT(1) UNSIGNED NULL, PRIMARY KEY (ID) USING BTREE, INDEX `idx_username` (`username`) USING BTREE, UNIQUE INDEX `unq_username` (`username`) USING BTREE ) COMMENT 'pxc测试表'; 四、MyCat安装与配置 下载MyCat http://dl.mycat.io/1.6.5/Mycat-server-1.6.5-release-20180122220033-linux.tar.gz 上传MyCat压缩包到虚拟机 安装unzip程序包，解压缩MyCat yum install unzip unzip MyCAT压缩包名称 开放防火墙8066和9066端口，关闭SELINUX 修改MyCat的bin目录中所有.sh文件的权限 chmod -R 777 ./*.sh MyCat启动与关闭 #cd MyCat的bin目录 ./startup_nowrap.sh #启动MyCat ps -aux #查看系统进程 kill -9 MyCat进程编号 mycat配置文件解析 文件 作用 修改内容 rule.xml 切分算法 修改mod-long分片数量为2 server.xml 虚拟MySQL 修改用户名、密码和逻辑库 scnema．Xml 数据库连接、读写分离、负载均衡、数据表映射 定义连接、读写分离、负载均衡、数据表映射 修改server.xml文件，设置MyCat帐户和虚拟逻辑库 0 1 0 0 2 false 0 0 1 64k 1k 0 384m false Abc_123456 test 修改schema.xml文件，设置数据库连接和虚拟数据表 此处有两个分片，则配置两个dataHost 重点配置介绍 1. balance 属性 负载均衡类型，目前的取值有 3 种： balance="0", 不开启读写分离机制，所有读操作都发送到当前可用的 writeHost 上。 balance="1"，全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡，简单的说，当双 主双从模式(M1->S1，M2->S2，并且 M1 与 M2 互为主备)，正常情况下，M2,S1,S2 都参与 select 语句的负载 均衡。 balance="2"，所有读操作都随机的在 writeHost、readhost 上分发。防止写节点浪费 balance="3"，所有读请求随机的分发到 wiriterHost 对应的 readhost 执行，writerHost 不负担读压力， 注意 balance=3 只在 1.4 及其以后版本有，1.3 没有。 2. writeType 属性 负载均衡类型，目前的取值有 3 种： writeType="0", 所有写操作发送到配置的第一个 writeHost，第一个挂了切到还生存的第二个 writeHost， 重新启动后已切换后的为准，切换记录在配置文件中:dnindex.properties . writeType="1"，所有写操作都随机的发送到配置的 writeHost，1.5 以后废弃不推荐。 3. switchType 属性 -1 表示不自动切换。 1 默认值，自动切换。 2 基于 MySQL 主从同步的状态决定是否切换。 select user() select user() 修改rule.xml文件，把mod-long的count值修改成2 2 放行端口 8066：数据服务 9066：管理端口 重启MyCat $ ./startup_nowrap.sh 关闭命令： $ ps -aux | grep mycat $ kill $PID 向t_user表写入数据，感受数据的切分 USE test; select * from t_user; #第一条记录被切分到第二个分片 INSERT INTO t_user(id,username,password,tel,locked) VALUES(1,"A",HEX(AES_ENCRYPT('123456','HelloWorld')),"12345678901",false); #第二条记录被切分到第一个分片 INSERT INTO t_user(id,username,password,tel,locked) VALUES(2,"B",HEX(AES_ENCRYPT('123456','HelloWorld')),"12345678912",false); 五、配置数据分片和父子表 1. 数据切分算法 切分算法 适用场合 备注 主键求模切分 数据增长速度慢,难于增加分片 有明确主键值 枚举值切分 归类存储数据,适合大多数业务 主键范围切分 数据快速增长,容易增加分片 有明确主键值 日期切分 数据快速增长,容易增加分片 （1）主键求模切分 求模切分适合用在初始数据很大,但是数据增长不快的场景 求模切分的弊病在于扩展新分片难度大,迁移的数据太多 建议扩张后的分片数是原有分片的2n倍 （2）枚举值切分 按照某个字段的值（数字）来切分数据 2. 数据分片 在conf目录下创建customer-hash-int文件，内容如下： 101=0 102=0 103=0 104=1 105=1 106=1 在rule.xml文件中加入自定义和 customer-hash-int.txt sharding_id customer-hash-int 修改schema.xml文件，配置数据分片算法 重载mycat配置 使用navicat打开命令行界面，执行语句 reload @@config_all; USE test; CREATE TABLE t_customer( id INT UNSIGNED PRIMARY KEY, username VARCHAR(200) NOT NULL, sharding_id INT NOT NULL ); select * from t_customer; insert into t_customer(id, username, sharding_id) VALUES (1,'tom',101); insert into t_customer(id, username, sharding_id) VALUES (2,'jetty',102); insert into t_customer(id, username, sharding_id) VALUES (3,'tomcat',105); 第一个分片 第二个分片 查询mycat数据 3. 父子表 出现原因：在 MyCat中是不允许跨分片做表连接查询的 解决原理：部分业务总会可以抽象出父子关系的表。这类表适用于 ER 分片表，子表的记录与 所关联的父表记录存放在同一个数据分片上，避免数据 Join 跨库操作 修改schema.xml文件，添加父子表定义。此处定义成父表t_customer允许分在不同分片，子表t_orders不允许跨分片。一个父表可以包含多个子表，子表也可嵌套多个子表。 重载mycat配置 使用navicat打开命令行界面，执行语句 reload @@config_all; 在MyCat上执行如下SQL： USE test; CREATE TABLE t_orders( id INT PRIMARY KEY, customer_id INT NOT NULL, datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); 向t_customer表和t_orders表写入数据，查看字表数据跟随父表切分到同一个分片 -- 预期写入第一个分片 insert into t_orders(id, customer_id) VALUES (1,1); insert into t_orders(id, customer_id) VALUES (2,1); insert into t_orders(id, customer_id) VALUES (3,1); -- 预期写入第二个分片 insert into t_orders(id, customer_id) VALUES (4,2); insert into t_orders(id, customer_id) VALUES (5,3); 分片一t_customer查询结果 分片一t_orders查询结果 分片二t_customer查询结果 分片二t_orders查询结果 同一个客户订单和客户信息都存在相同分片中，结果符合预期 连接查询测试 select c.username,t.id,t.datetime from t_customer c join t_orders t on c.id = t.customer_id