在实际项目中, Mycat 服务也需要考虑高可用性,如果 Mycat 所在服务器出现宕机,或 Mycat 服务故障,需要有备机提供服务,需要考虑 Mycat 集群。
高可用方案
我们可以使用 HAProxy + Keepalived 配合两台 Mycat 搭起 Mycat 集群,实现高可用性。 HAProxy实现了MyCat 多节点的集群高可用和负载均衡, 而 HAProxy 自身的高可用则可以通过 Keepalived 来实现。继续上一章的部署,添加一台mycat做轮询,mycat2部署和mycat1一样,需要提前配置,添加两台haproxy加keepalived。
拓扑图如下:
安装配置 HAProxy
安装 HAProxy
注意:两台haproxy服务器都需要安装。
1. 准备好HAProxy安装包,传到/opt目录下 解压到/usr/local/src
[root@haproxy1 ~]# tar zxf haproxy-2.1.2.tar.gz -C /usr/local/src
2. 进入解压后的目录,查看内核版本, 进行编译
1. [root@haproxy1 ~]# cd /usr/local/src/haproxy-2.1.2 2. [root@haproxy1 haproxy-2.1.2]# uname -r 3. 3.10.0-1160.el7.x86_64 4. [root@haproxy1 haproxy-2.1.2]# make TARGET=linux310 PREFIX=/usr/local/haproxy ARCH=x86_64
ARGET=linux310,内核版本,使用uname -r查看内核,如: 3.10.0-514.el7,此时该参数就为linux310;
ARCH=x86_64,系统位数;
PREFIX=/usr/local/haprpxy #/usr/local/haprpxy,为haprpxy安装路径。
3. 编译完成后,进行安装,向配置文件中插入以下配置信息,并保存
1. [root@haproxy1 haproxy-2.1.2]# make install PREFIX=/usr/local/haproxy 2. [root@haproxy1 haproxy-2.1.2]# vim /usr/local/haproxy/haproxy.conf 3. global 4. log 127.0.0.1 local0 5. #log 127.0.0.1 local1 notice 6. #log loghost local0 info 7. maxconn 4096 8. chroot /usr/local/haproxy 9. pidfile /usr/local/haproxy/haproxy.pid 10. uid 99 11. gid 99 12. daemon 13. #debug 14. #quiet 15. defaults 16. log global 17. mode tcp 18. option abortonclose 19. option redispatch 20. retries 3 21. maxconn 2000 22. timeout connect 5000 23. timeout client 50000 24. timeout server 50000 25. listen proxy_status 26. bind :48066 27. mode tcp 28. balance roundrobin 29. server mycat_1 192.168.8.10:8066 check inter 10s #mycat1主机 30. server mycat_2 192.168.8.11:8066 check inter 10s #mycat2主机 31. frontend admin_stats 32. bind :7777 33. mode http 34. stats enable 35. option httplog 36. maxconn 10 37. stats refresh 30s 38. stats uri /admin 39. stats auth admin:123123 40. stats hide-version 41. stats admin if TRUE
注意:haproxy2配置和haproxy1相同,这里不在重复。
启动验证
1. 启动HAProxy
[root@haproxy1 haproxy-2.1.2]# /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.conf
2. 查看HAProxy进程
1. [root@haproxy1 haproxy-2.1.2]# ps -ef | grep haproxy 2. nobody 101066 1 0 17:14 ? 00:00:00 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.conf 3. root 101086 5343 0 17:15 pts/2 00:00:00 grep --color=auto haproxy
3. 打开浏览器访问 http://192.168.8.1:7777/admin 或者8.2主机,在弹出登录框后输入用户名: admin密码: 123123,注意开启mycat。
4. 验证负载均衡,通过haproxy1和haproxy2访问mycat登录mysql,端口号为48066
[root@master1 ~]# mysql -umycat -p123456 -h192.168.8.1 -P 48066
配置 Keepalived
注意:两台haproxy主机都需要安装keepalived,这里以haproxy1主机为例。
安装 Keepalived
1. 准备好Keepalived安装包,传到/opt目录下 解压到/usr/local/src
[root@haproxy1 ~]# tar zxf keepalived-2.2.7.tar.gz -C /usr/local/src
2. 安装依赖插件
[root@haproxy1 ~]# yum install -y gcc openssl-devel popt-devel
3. 进入解压后的目录, 进行配置, 进行编译
1. [root@haproxy1 ~]# cd /usr/local/src/keepalived-2.2.7/ 2. [root@haproxy1 keepalived-2.2.7]# ./configure --prefix=/usr/local/keepalived
4. 进行编译, 完成后进行安装
[root@haproxy1 keepalived-2.2.7]# make && make install
5. 运行前配置
1. [root@haproxy1 keepalived-2.2.7]# cp /usr/local/src/keepalived-2.2.7/keepalived/etc/init.d/keepalived /etc/init.d/ 2. [root@haproxy1 keepalived-2.2.7]# mkdir /etc/keepalived 3. [root@haproxy1 keepalived-2.2.7]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf.sample /etc/keepalived/ 4. [root@haproxy1 keepalived-2.2.7]# mv /etc/keepalived/keepalived.conf.sample /etc/keepalived/keepalived.conf 5. [root@haproxy1 keepalived-2.2.7]# cp /usr/local/src/keepalived-2.2.7/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ 6. [root@haproxy1 keepalived-2.2.7]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
修改配置文件
haproxy1配置文件
1. [root@haproxy1 ~]# vim /etc/keepalived/keepalived.conf 2. ! Configuration File for keepalived 3. 4. global_defs { 5. router_id ha1 6. } 7. 8. vrrp_instance VI_1 { 9. state MASTER 10. interface ens33 11. virtual_router_id 51 12. priority 100 13. advert_int 1 14. authentication { 15. auth_type PASS 16. auth_pass 1111 17. } 18. virtual_ipaddress { 19. 192.168.8.100 20. } 21. } 22. 23. virtual_server 192.168.8.100 48066 { 24. delay_loop 6 25. lb_algo rr 26. lb_kind NAT 27. persistence_timeout 50 28. protocol TCP 29. 30. real_server 192.168.8.1 48066 { 31. weight 1 32. TCP_CHECK { 33. connect_timeout 3 34. retry 3 35. delay_before_retry 3 36. } 37. } 38. real_server 192.168.8.2 48066 { 39. weight 1 40. TCP_CHECK { 41. connect_timeout 3 42. retry 3 43. delay_before_retry 3 44. } 45. } 46. }
haproxy2配置文件
1. [root@haproxy2 ~]# cat /etc/keepalived/keepalived.conf 2. ! Configuration File for keepalived 3. 4. global_defs { 5. router_id ha2 6. } 7. 8. vrrp_instance VI_1 { 9. state BACKUP 10. interface ens33 11. virtual_router_id 51 12. priority 50 13. advert_int 1 14. authentication { 15. auth_type PASS 16. auth_pass 1111 17. } 18. virtual_ipaddress { 19. 192.168.8.100 20. } 21. } 22. 23. virtual_server 192.168.8.100 48066 { 24. delay_loop 6 25. lb_algo rr 26. lb_kind NAT 27. persistence_timeout 50 28. protocol TCP 29. 30. real_server 192.168.8.1 48066 { 31. weight 1 32. TCP_CHECK { 33. connect_timeout 3 34. retry 3 35. delay_before_retry 3 36. } 37. } 38. real_server 192.168.8.2 48066 { 39. weight 1 40. TCP_CHECK { 41. connect_timeout 3 42. retry 3 43. delay_before_retry 3 44. } 45. } 46. }
启动验证
两台主机都启动Keepalived
1. [root@haproxy1 ~]# systemctl start keepalived 2. [root@haproxy1 ~]# ps -ef | grep keep 3. root 2864 2487 0 16:21 ? 00:00:00 /usr/libexec/gsd-housekeeping 4. root 108226 1 0 17:43 ? 00:00:00 /usr/local/keepalived/sbin/keepalived --dont-fork -D 5. root 108227 108226 0 17:43 ? 00:00:00 /usr/local/keepalived/sbin/keepalived --dont-fork -D 6. root 108228 108226 0 17:43 ? 00:00:00 /usr/local/keepalived/sbin/keepalived --dont-fork -D 7. root 108244 5343 0 17:43 pts/2 00:00:00 grep --color=auto keep 8. [root@haproxy1 ~]# ip a show dev ens33 9. 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 10. link/ether 00:0c:29:e6:ef:60 brd ff:ff:ff:ff:ff:ff 11. inet 192.168.8.1/24 brd 192.168.8.255 scope global noprefixroute ens33 12. valid_lft forever preferred_lft forever 13. inet 192.168.8.100/32 scope global ens33 14. valid_lft forever preferred_lft forever
使用一台mysql服务器远程登录验证
1. [root@slave1 ~]# mysql -umycat -p123456 -P48066 -h192.168.8.100 2. mysql: [Warning] Using a password on the command line interface can be insecure. 3. Welcome to the MySQL monitor. Commands end with ; or \g. 4. Your MySQL connection id is 16 5. Server version: 5.6.29-mycat-1.6.7.6-release-20220524173810 MyCat Server (OpenCloudDB) 6. 7. Copyright (c) 2000, 2022, Oracle and/or its affiliates. 8. 9. Oracle is a registered trademark of Oracle Corporation and/or its 10. affiliates. Other names may be trademarks of their respective 11. owners. 12. 13. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
测试高可用
关闭一台mycat通过虚拟ip查询数据,通过mysql访问登录mysql
1. [root@mycat1 ~]# mycat stop 2. Stopping Mycat-server... 3. Stopped Mycat-server.[root@mycat1 ~]# mycat stop 4. Stopping Mycat-server... 5. Stopped Mycat-server.
登录mycat
[root@slave1 ~]# mysql -umycat -p123456 -P48066 -h192.168.8.100
mycat 安全设置
权限配置
user 标签权限控制 目前 Mycat 对于中间件的连接控制并没有做太复杂的控制,目前只做了中间件逻辑库级别的读写权限控制。是通过 server.xml 的 user 标签进行配置。
修改server.xml配置文件user部分,通过下面配置文件看到,有mycat用户(这里就不多讲了)和user用户,可以看到user用户密码,逻辑库等信息。
1. [root@mycat1 ~]# cd /usr/local/mycat/conf 2. [root@mycat1 conf]# vim server.xml 3. #省略部分内容 4. <user name="mycat" defaultAccount="true"> 5. <property name="password">123456</property> 6. <property name="schemas">TESTDB</property> 7. <property name="defaultSchema">TESTDB</property> 8. </user> 9. 10. <user name="user"> 11. <property name="password">user</property> 12. <property name="schemas">TESTDB</property> 13. <property name="readOnly">true</property> 14. <property name="defaultSchema">TESTDB</property> 15. </user>
privileges 标签权限控制 在 user 标签下的 privileges 标签可以对逻辑库(schema)、表(table)进行精细化的 DML 权限控制。 privileges 标签下的 check 属性,如为 true 开启权限检查,为 false 不开启,默认为 false。 由于 Mycat 一个用户的 schemas 属性可配置多个逻辑库(schema) ,所以 privileges 的下级节点 schema 节点同样可配置多个,对多库多表进行细粒度的 DML 权限控制。
修改server.xml配置文件privileges部分,orders表没有删除权限,配置tb1表没有增删改查权限。
1. [root@mycat1 ~]# cd /usr/local/mycat/conf 2. [root@mycat1 conf]# vim server.xml 3. #省略部分内容 4. <!-- 表级 DML 权限设置 --> 5. <privileges check="true"> 6. <schema name="TESTDB" dml="1111" > 7. <table name="orders" dml="1110"></table> 8. <table name="tb1" dml="0000"></table> 9. </schema> 10. </privileges> 11. [root@mycat1 conf]# mycat restart 12. Stopping Mycat-server... 13. Stopped Mycat-server. 14. Starting Mycat-server...
配置说明
DML 权限 | 增加(insert) | 更新(update) | 查询(select) | 删除(delete) |
0000 | 禁止 | 禁止 | 禁止 | 禁止 |
0001 | 禁止 | 禁止 | 禁止 | 允许 |
0010 | 禁止 | 禁止 | 允许 | 禁止 |
1111 | 允许 | 允许 | 允许 | 允许 |
测试查看两个表是否按照要求修改成功,我这里只修改了mycat1主机,就直接登录mycat1测试了。
1. [root@master2 ~]# mysql -umycat -p123456 -h192.168.8.10 -P8066 2. #省略部分内容 3. mysql> use TESTDB 4. mysql> select * from orders; 5. +------+------------+-------------+-----------+ 6. | id | order_type | customer_id | amount | 7. +------+------------+-------------+-----------+ 8. | 2 | 101 | 100 | 100300.00 | 9. | 4 | 101 | 101 | 103000.00 | 10. | 6 | 102 | 100 | 100020.00 | 11. | 1 | 101 | 100 | 100100.00 | 12. | 3 | 101 | 101 | 120000.00 | 13. | 5 | 102 | 101 | 100400.00 | 14. +------+------------+-------------+-----------+ 15. 6 rows in set (0.34 sec) 16. 17. mysql> delete from orders where id=1; 18. ERROR 3012 (HY000): The statement DML privilege check is not passed, reject for user 'mycat' 19. 20. mysql> show tables; 21. +------------------+ 22. | Tables_in_mytest | 23. +------------------+ 24. | customer | 25. | dict_order_type | 26. | orders | 27. | orders_detail | 28. | tb1 | 29. +------------------+ 30. 5 rows in set (0.01 sec) 31. 32. mysql> select * from tb1; 33. ERROR 3012 (HY000): The statement DML privilege check is not passed, reject for user 'mycat'
通过上面命令行显示,删除orders以及查看tb1无法成功执行,返回结果为DML权限检查未通过而拒绝。
SQL 拦截
firewall 标签用来定义防火墙; firewall 下 whitehost 标签用来定义 IP 白名单 , blacklist 用来定义SQL 黑名单。
1. 白名单 可以通过设置白名单, 实现某主机某用户可以访问 Mycat,而其他主机用户禁止访问。
修改server.xml配置文件firewall标签,配置只有192.168.8.50主机可以通过mycat用户访问,其他主机拒绝访问。
1. [root@mycat1 conf]# vim server.xml 2. <firewall> 3. <whitehost> 4. <host host="192.168.8.50" user="mycat"/> 5. </whitehost> 6. </firewall> 7. [root@mycat1 conf]# mycat restart 8. Stopping Mycat-server... 9. Stopped Mycat-server. 10. Starting Mycat-server...
测试用mysql服务器通过192.168.8.10登录mysql,最终结果为只有192.168.8.50主机成功登录,至此白名单完成。
1. [root@master2 ~]# mysql -umycat -p123456 -h192.168.8.10 -P8066 2. mysql: [Warning] Using a password on the command line interface can be insecure. 3. Welcome to the MySQL monitor. Commands end with ; or \g. 4. Your MySQL connection id is 1 5. Server version: 5.6.29-mycat-1.6.7.6-release-20220524173810 MyCat Server (OpenCloudDB) 6. 7. Copyright (c) 2000, 2022, Oracle and/or its affiliates. 8. 9. Oracle is a registered trademark of Oracle Corporation and/or its 10. affiliates. Other names may be trademarks of their respective 11. owners. 12. 13. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 14. 15. mysql>
2. 黑名单 可以通过设置黑名单, 实现 Mycat 对具体 SQL 操作的拦截, 如增删改查等操作的拦截。
修改server.xml配置文件firewall标签,配置禁止mycat用户进行插入操作
1. [root@mycat1 conf]# vim server.xml 2. <firewall> 3. <whitehost> 4. <host host="192.168.8.50" user="mycat"/> 5. </whitehost> 6. <blacklist check="true"> 7. <property name="insertAllow"> false</property> 8. </blacklist> 9. </firewall> 10. [root@mycat1 conf]# mycat restart 11. Stopping Mycat-server... 12. Stopped Mycat-server. 13. Starting Mycat-server...
测试使用8.50主机登录,并且对orders表插入数据,最终结果发现无法插入,黑名单成功。
1. mysql> use TESTDB 2. Reading table information for completion of table and column names 3. You can turn off this feature to get a quicker startup with -A 4. 5. Database changed 6. mysql> show tables; 7. +------------------+ 8. | Tables_in_mytest | 9. +------------------+ 10. | customer | 11. | dict_order_type | 12. | orders | 13. | orders_detail | 14. +------------------+ 15. 4 rows in set (0.02 sec) 16. 17. mysql> select * from orders; 18. +------+------------+-------------+-----------+ 19. | id | order_type | customer_id | amount | 20. +------+------------+-------------+-----------+ 21. | 2 | 101 | 100 | 100300.00 | 22. | 4 | 101 | 101 | 103000.00 | 23. | 6 | 102 | 100 | 100020.00 | 24. | 1 | 101 | 100 | 100100.00 | 25. | 3 | 101 | 101 | 120000.00 | 26. | 5 | 102 | 101 | 100400.00 | 27. +------+------------+-------------+-----------+ 28. 6 rows in set (0.04 sec) 29. 30. mysql> insert into orders values(^C 31. mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(7,102,101,111400); 32. ERROR 3012 (HY000): The statement is unsafe SQL, reject for user 'mycat'
在修改一次,使其可以插入数据,通过下面语法很好理解,false为拒绝,true为允许。
1. [root@mycat1 conf]# vim server.xml 2. <host host="192.168.8.50" user="mycat"/> 3. </whitehost> 4. <blacklist check="true"> 5. <property name="insertAllow"> true</property> 6. </blacklist> 7. </firewall> 8. [root@mycat1 conf]# mycat restart 9. Stopping Mycat-server... 10. Stopped Mycat-server. 11. Starting Mycat-server...
插入数据成功。
1. [root@master2 ~]# mysql -umycat -p123456 -P48066 -h192.168.8.100 2. 3. mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(7,102,101,111400); 4. Query OK, 1 row affected (0.21 sec) 5. OK! 6. 7. mysql> select * from orders; 8. +------+------------+-------------+-----------+ 9. | id | order_type | customer_id | amount | 10. +------+------------+-------------+-----------+ 11. | 2 | 101 | 100 | 100300.00 | 12. | 4 | 101 | 101 | 103000.00 | 13. | 6 | 102 | 100 | 100020.00 | 14. | 1 | 101 | 100 | 100100.00 | 15. | 3 | 101 | 101 | 120000.00 | 16. | 5 | 102 | 101 | 100400.00 | 17. | 7 | 102 | 101 | 111400.00 | 18. +------+------------+-------------+-----------+ 19. 7 rows in set (0.06 sec)
可以设置的黑名单 SQL 拦截功能列表
配置项 | 缺省值 | 描述 |
selectAllow | true | 是否允许执行 SELECT 语句 |
deleteAllow | true | 是否允许执行 DELETE 语句 |
updateAllow | true | 是否允许执行 UPDATE 语句 |
insertAllow | true | 是否允许执行 INSERT 语句 |
creaetTableAllow | true | 是否允许创建表 |
setAllow | true | 是否允许使用SET语法 |
alterTableAllow | true | 是否允许执行 Alter Table 语句 |
dropTableAllow | true | 是否允许修改表 |
commitAllow | true | 是否允许执行 commit 操作 |
rollbackAllow | true | 是否允许执行 roll back 操作 |