MHA原理
mha启动是通过 masterha_manger
1监控 是通过masterha_master_monitor
通过ping_intrval值调整
2选主
判断
先生节点的数组
alive slave 存活 数组
lastest slave 最接近主的数组
candidate slave 备选数组
bad slave 损坏节点
1判断 在最接近主的数组和备选数同出现不在损坏节点 优先选为主节点
2判断 在 最接近主的数组不在损坏节点 选为主节点
3判断 在备选数组不在损坏节点 选为主节点‘
4判断 在存活数组 不在损坏节点选为主节点
3数据补偿
1原主库ssh能连接,截取缺失部分日志scp到各个从库(/var/tmp/xxxx)调用save_binary_logs
2原主库不能ssh 两个从库之间做diff app_diff_relay_logs
4切换
masterha_master_switch
1原来的主从关系要解除
2构建新的主从关系
5应用透明vip 单独去做
master_ip_failover
6故障节点剔除集群
masterha_conf_host
7故障提醒 单独去做
mha搭建
1node软件包要在主从所有节点安装
2mha-manager需要在别的机器安装
1配置关键程序软连接(在mha脚本内调用的是绝对路径所以要做软连接)
ln -s /usr/local/mysql-80/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /usr/local/mysql-80/bin/mysql /usr/bin/mysql
2配置ssh
在主库配置
rm -rf /root/.ssh
ssh-keygen
cd /root/.ssh
mv id_rsa.pub authorized_keys
scp -r /root/.ssh 10.0.0.52:/root
scp -r /root/.ssh 10.0.0.53:/root
各个节点测试不需要输入密码
ssh 10.4.7.11 date
ssh 10.4.7.12 date
ssh 10.4.7.13 date
下载软件
下载mha软件
mha官网:https://code.google.com/archive/p/mysql-master-ha/
github下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
分版本 主流版本 0.56 0.57 0.58 针对不同的版本mysql
所有节点上传node软件安装和依赖包
yum install perl-DBD-MySQL -y
rpm -ivh mha4mysql-node*.rpm
manage软件安装和依赖包
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-ParallelForkManager perl-Time-HiRes
rpm -ivh mha4mysql-manager*.rpm
配置manager配置文件
创建目录
mkdir -p /etc/mha 配置文件目录
mkdir -p /var/log/mha/app1
日志目录
vim /etc/mha/app1.cnf 增加配置文件
[server default] manager 服务相关
manager_log=/var/log/mha/app1/manager 主程序日志文件
manager_workdir=/var/log/mha/app1 工作路径保存状态和日志文件
master_binlog_dir=/data/binlog/ 主库的binlog位置
user=mha mha内部监控需要创建 数据库用户
password=mha
ping_interval=2 心跳检测,每隔多少秒
repl_password=123 复制用户的用户名和密码
repl_user=repl
ssh_user=root ssh互信
[server1]节点信息 如果好多节点满足条件会按照数字的顺序从小到大选
hostname=10.0.0.51
port=3306
[server2]
hostname=10.0.0.52
candidate_master=1 是否是被选主
port=3306
[server3]
hostname=10.0.0.53
port=3306
创建mha用户
create user mha@'10.4.7.%' identified with mysql_native_password by 'mha';
grant all privileges on *.* to mha@'10.4.7.%';
状态检查
互信检测
masterha_check_ssh --conf=/etc/mha/app1.cnf
主从状态检测
masterha_check_repl --conf=/etc/mha/app1.cnf
启动mha
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
查看mha状态
masterha_check_status --conf=/etc/mha/app1.cnf
mha组件介绍
manager 组件
masterha_manger 启动MHA
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_master_monitor 检测master是否宕机
masterha_check_status 检测当前MHA运行状态
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的server信息
node 组件
save_binary_logs 保存和复制master的二进
master_ip_failover制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
mha配合应用透明
master_ip_failover脚本
需要修改的地方
my $vip = '10.4.7.55/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
my $ssh_Bcast_arp= "/sbin/arping -I eth0 -c 3 -A 10.4.7.55";
修改mha配置文件
master_ip_failover_script=/usr/local/bin/master_ip_failover
重启mha
masterha_stop --conf=/etc/mha/app1.cnf
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
第一次需要在主库手工设置上vip
ifconfig eth0:1 10.4.7.51/24
ifconfig eth0:1 10.4.7.51/24 down 如果不想要基于可以down掉
生产注意:
1. 自带脚本,不能跨网段的,必须在局域网中应用。打通二层网络。而且不是特别稳定。
2. 如果需要跨网段,推荐使用智能DNS。
3. 可以配合ProxySQL类似的中间件,就可以不使用VIP了。
故障提醒send_report脚本
#new_master_host and new_slave_hosts are set only when recovering master succeeded
my ( $dead_master_host, $new_master_host, $new_slave_hosts, $subject, $body );
my $smtp='smtp.qq.com'; 发件箱
my $mail_from='22654481@qq.com';
my $mail_user='22654481';
my $mail_pass='gemghsvgkeyzcagh';
#my $mail_to=['to1@qq.com','to2@qq.com'];
my $mail_to='410846191@qq.com';收件箱
修改mha配置文件
report_script=/usr/local/bin/send_report
重启mha
修复mha
启动原主库
备份新主库数据 然后做主从
CHANGE MASTER TO
MASTER_HOST='10.4.7.12',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1;
hma不支持级联主从
需要在mha配置文件把原来的主库加回来mha切换之后会把原来主库信息删除
状态检查
互信检测
masterha_check_ssh --conf=/etc/mha/app1.cnf
主从状态检测
masterha_check_repl --conf=/etc/mha/app1.cnf
启动mha
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
查看mha状态
masterha_check_status --conf=/etc/mha/app1.cnf
mha不会管从节点down不down
日志补偿冗余方案
在异步复制中能规避一定风险
找一台新的节点
会源源不断的拉取主库的日志因为从库会发生业务
binlogserver将近实时拉去主库日志
可以从当前从库的起点拉取就好
查看从库当前拉取的位置
mysql -e "show slave status \G" |grep "Master_Log"
在我们创建好的路径下手动拉取
mysqlbinlog -R --host=主库地址 --user=拉取用户 --paseword= --raw --stop-never mysql-bin.0002 &
也是异步的过程,理论上是比从库快
配置MHA
vim /etc/mha/app1.cnf
[binlog1] 新增一个标签
no_master=1 不能参与选主
hostname=10.0.0.53 那台机器拉取的
master_binlog_dir=/data/binlog_server/ 拉取的日志路径
重启mha。。。。
binlog server不是100%可靠的 他是模拟io线程的功能异步
代替方案 5.7+gtid+增强半同步
MHA自愈思路
MHA在线手工切换
1先把mha停下来
masterha_stop --conf=/etc/mha/app1.cnf
配置master_ip_online_change_script功能实现
功能: 在线切换时,自动锁原主库,VIP自动切换
修改mha配置文件
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
只切换角色
masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=10.4.7.11 --orig_master_is_new_slave --running_updates_limit=10000
注意提示
FLUSH NO_WRITE_TO_BINLOG TABLES在老主库上执行下可以保证已经提交的日志刷新一边 不在写新的日志
一路yes就好了
后续如果有binlog-server需要重构binlog-server从新主库取日志
启动mha
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null>/var/log/mha/app1/manager.log 2>&1 &
检测mha状态
mha如何防止脑裂
什么是脑裂
多个节点争抢主库角色
网络故障,默认manager是单一心跳检测
读写分离
可以把读的压力分担到从库
proxysql
在应用程序和数据库之间加了一层代理可以把流量转发
在互联网企业读写一般是73分读的请求比较大
一般配合高可用一起用
# 下载proxySQL
https://proxysql.com/
https://github.com/sysown/proxysql/releases
proxysql可以在线操作不需要重启服务
proxysql启动会给我们启动两个端口
tcp 0 0 0.0.0.0:6032 内部管理,通过6032端口 0.0.0.0:* LISTEN 88723/proxysql
tcp 0 0 0.0.0.0:6033 对外通过服务,应用服务连接6033端口 0.0.0.0:* LISTEN 88723/proxysql
连接proxysql
mysql -uadmin -h127.0.0.1 -padmin -P6032
proxysql库说明
mysql> show databases;
+-----+---------------+-------------------------------------+
| seq | name | file |
+-----+---------------+-------------------------------------+
| 0 | main | 核心配置库 |
| 2 | disk | /var/lib/proxysql/proxysql.db | 持久化磁盘的配置
| 3 | stats | | 统计信息汇总
| 4 | monitor | | 监控信息收集
| 5 | stats_history | /var/lib/proxysql/proxysql_stats.db |手机的内部功能的历史指标
+-----+---------------+-------------------------------------+
main库核心表
show tables;
+----------------------------------------------------+
| tables |
+----------------------------------------------------+
| global_variables | 系统总配置
| mysql_aws_aurora_hostgroups |
| mysql_collations |
| mysql_firewall_whitelist_rules |
| mysql_firewall_whitelist_sqli_fingerprints |
| mysql_firewall_whitelist_users |
| mysql_galera_hostgroups |
| mysql_group_replication_hostgroups 节点分组信息 把后端服务器分组 简单理解读组写组 |
| mysql_query_rules 指定不同的查询路由到后端不同的服务器列表 |
| mysql_query_rules_fast_routing |
| mysql_replication_hostgroups |
| mysql_servers 后端可以连接 mysql服务器的列表 |
| mysql_users 配置后端数据库的账号和监控账号 |
| proxysql_servers |
| restapi_routes |
| runtime_checksums_values |
| runtime_global_variables |
| runtime_mysql_aws_aurora_hostgroups |
| runtime_mysql_firewall_whitelist_rules |
| runtime_mysql_firewall_whitelist_sqli_fingerprints |
| runtime_mysql_firewall_whitelist_users |
| runtime_mysql_galera_hostgroups |
| runtime_mysql_group_replication_hostgroups |
| runtime_mysql_query_rules |
| runtime_mysql_query_rules_fast_routing |
| runtime_mysql_replication_hostgroups |
| runtime_mysql_servers |
| runtime_mysql_users |
| runtime_proxysql_servers |
| runtime_restapi_routes |
| runtime_scheduler |
| scheduler |
+----------------------------------------------------+
实际分为两大类 runtime开头是运行时正在用的 不是runtime开头的是可以被修改的
配置流程
配置是分层管理的
分为三层配置结构
runtime 当前在使用的,不可被修改
memory 是runtime的快照 可以被修改
disk 持久化存储
cfg 配置文件
一般都针对memory修改 如何让我们修改的生效呢load加载一下就可以runtime最后还需要save保存
配置
1先去配置一个组
insert into
mysql_replication_hostgroups
(writer_hostgroup, reader_hostgroup, comment)
values (10,20,'proxy');
配置完成后 需要保存一下和加载一下
load mysql servers to runtime;
save mysql servers to disk;
proxysql如何区分是主库和从库呢是通过read_only
需要在加节点之前需要将从库的read_only参数设置上
set global super_read_only=1;
set global super__read_only=1;
添加主机到proxysql
insert into mysql_servers(hostgroup_id,hostname,port) values
(10,'10.4.7.11',3306);
insert into mysql_servers(hostgroup_id,hostname,port) values
(20,'10.4.7.12',3306);
insert into mysql_servers(hostgroup_id,hostname,port) values
(20,'10.4.7.13',3306);
因为我们之前设置了两个组一个读组一个写组
加完之后需要保存一下和加载一下
需要配置一个专用的账号
mysql做
create user monitor@'%' identified with mysql_native_password by '123';
grant replication client on *.* to monitor@'%';
proxysql设置监控用户
set mysql-monitor_username='monitor';
set mysql-monitor_password='123';
做一下配置完成后 需要保存一下和加载一下
load mysql servers to runtime;
save mysql servers to disk;
查询proxysql监控日志
select * from mysql_server_connect_log;查看监控信息
select * from mysql_server_ping_log; 心跳探测
select * from mysql_server_read_only_log; 查看后端那些节点是读节点
select * from mysql_server_replication_lag_log;
配置业务用户需要配置一个业务用户,去数据库上执行相应的操作
数据库配置
create user root@'%' identified with mysql_native_password by '123';
grant all on *.* to root@'%';
insert into mysql_users(username,password,default_hostgroup) values('root','123',10);
proxysql需要配置业务用户,需要配置一个默认组,将来不配置读写分离的规则默认走默认组
insert into mysql_users(username,password,default_hostgroup)
values('root','123',10);
做一下配置完成后 需要保存一下和加载一下
load mysql servers to runtime;
save mysql servers to disk;
早期版本,需要开启事务持续化。 update mysql_users set transaction_persistent=1 where username='root';
load mysql users to runtime;
save mysql users to disk;
需要配置事务走主库
实用的读写规则
insert into
mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply)
values
(1,1,'^select.*for update$',10,1);
insert into
mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply)
values
(2,1,'^select',20,1);
load mysql query rules to runtime;
save mysql query rules to disk;
注: select … for update规则的rule_id必须要小于普通的select规则的rule_id,ProxySQL是根
据rule_id的顺序进行规则匹配。
规则其实就是if的判断从上到下去匹配规则找不到规则默认走detination组
可以写任何的正则
可以将危险操作定义到30号组 一个不存在的组 这样就可以规避一些危险操作
测试
mysql -uroot -p123 -P 6033 -h 127.0.0.1 -e "begin;select @@server_id;commit"
mysql ionndb cluster
mha高可用技术前端会配合proxysql
架构
mysql router 代理路由
mysql shell 集群的管理和配置
mysql group replication mysql计算节点
三个组件组合到一起形成一个集群
计算节点 mysql mysqlsh
管理节点 mysql shell mysql router
数据库分布式架构
1
nginx+php+mysql
2
nginx+php拆分mysql
3访问量上来了
有多套应用连接一套数据库(使用的仍然是一套库)
nginx+php=mysql
nginx+php=mysql
4做高可用架构mha读写分离
主库提供写入,从库提供读取
5演变单业务单数据库服务(垂直拆分)
应用端拆分不同服务,有不同数据库服务
逻辑拆分
6单业务变得非常高,基于每个业务拆分数据库的热表,每个热表拆分到多个库中
前面加个mycat/shardingjdbc
应用层和数据库之间加入
这种技术检查基于表的垂直拆分
如果单表,较大可以把单表拆分多份,分布到不同的数据库实例(基于表的水平拆分)
维护难度较大,分片较多,扩容新的分片要重新做
mycat
10.4.7.11 3307《---》10.4.7.12 3307
10.4.7.11 3309----》10.4.7.11 3307
10.4.7.12 3309----》10.4.7.12 3307
10.4.7.12:3308 <-----> 10.4.7.11:3308
10.4.7.12:3310 -----> 10.4.7.12:3308
10.4.7.11:3310 -----> 10.4.7.11:3308
1安装java环境
yum install -y java
2mycat下载
Mycat-server-xxxxx.linux.tar.gz
http://dl.mycat.org.cn/
解压就用
配置环境变量
export PATH=/data/mycat/bin:$PATH
3mycat配置
mycat start启动
tcp6 0 0 :::8066 对外提供服务端口
tcp6 0 0 :::9066 管理端口
连接
mysql -uroot -p123456 -h 127.0.0.1 -P8066
注: Mycat中使用的是MySQL 5.1版本驱动,连接8.0时
将会失败。
解决方案:
1. 下载更新客户端程序
https://downloads.mysql.com/archives/cj/
2. 连接时添加auth=mysql_native_password参
数
mysql -uroot -p123456 -h10.4.7.11 -P8066 --default-auth=mysql_native_password
3. 更新MySQL客户端命令为8.0之前版
默认只有一个库
show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
mycat配置
所有的配置都在conf目录
-rwxrwxrwx 1 root root 92 Oct 22 2019 autopartition-long.txt 分片策略传参时候用
-rwxrwxrwx 1 root root 51 Oct 22 2019 auto-sharding-long.txt
-rwxrwxrwx 1 root root 67 Oct 22 2019 auto-sharding-rang-mod.txt
-rwxrwxrwx 1 root root 340 Oct 22 2019 cacheservice.properties
-rwxrwxrwx 1 root root 3338 Oct 22 2019 dbseq.sql
-rwxrwxrwx 1 root root 3532 Oct 22 2019 dbseq - utf8mb4.sql
-rwxrwxrwx 1 root root 446 Oct 22 2019 ehcache.xml
-rwxrwxrwx 1 root root 2454 Dec 30 2019 index_to_charset.properties 将来做从新分片用的
-rwxrwxrwx 1 root root 1285 Oct 22 2019 log4j2.xml
-rwxrwxrwx 1 root root 183 Oct 22 2019 migrateTables.properties
-rwxrwxrwx 1 root root 271 Nov 26 2019 myid.properties
-rwxrwxrwx 1 root root 16 Oct 22 2019 partition-hash-int.txt
-rwxrwxrwx 1 root root 108 Oct 22 2019 partition-range-mod.txt
-rwxrwxrwx 1 root root 5423 Oct 22 2019 rule.xml 分片策略定制
-rwxrwxrwx 1 root root 3080 Dec 30 2019 schema.xml 分片的定制节点配置
-rwxrwxrwx 1 root root 440 Oct 22 2019 sequence_conf.properties
-rwxrwxrwx 1 root root 79 Oct 22 2019 sequence_db_conf.properties
-rwxrwxrwx 1 root root 29 Oct 22 2019 sequence_distributed_conf.properties
-rwxrwxrwx 1 root root 28 Oct 22 2019 sequence_http_conf.properties
-rwxrwxrwx 1 root root 53 Oct 22 2019 sequence_time_conf.properties
-rwxrwxrwx 1 root root 6392 Dec 30 2019 server.xml 是mycat程序配置文件
-rwxrwxrwx 1 root root 18 Oct 22 2019 sharding-by-enum.txt
-rwxrwxrwx 1 root root 4251 Jan 5 2020 wrapper.conf
drwxrwxrwx 2 root root 4096 Mar 26 18:04 zkconf 和zk结合时候用的
drwxrwxrwx 2 root root 36 Mar 26 18:04 zkdownload
日志
-rw-r--r-- 1 root root 119725 Mar 26 18:27 mycat.log 工作过程中出现问题看这个日志
-rw-r--r-- 1 root root 7 Mar 26 18:20 mycat.pid
-rw-r--r-- 1 root root 96 Mar 26 18:20 switch.log
-rw-r--r-- 1 root root 488 Mar 26 18:20 wrapper.log 启动相关日志
mycat读写分离配置文件
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schemaxmlns:mycat="http://io.mycat/">
简称逻辑库应用永远访问的是testdb这个库 应用访问到这个库就会给转接到分片
<schema name="TESTDB"checkSQLschema="false" sqlMaxLimit="100"dataNode="dn1">
1</schema> 三部分构成
2简称分片 对于那个库的读走哪里
<dataNode name="dn1"dataHost="localhost1" database= "world" />
3配置节点信息表示后端节点有那些
<dataHost name="localhost1"maxCon="1000" minCon="10" balance="1"writeType="0" dbType="mysql"dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
配置写节点 虽然有多喝writhost也只有1个提供服务平常作为读操作
<writeHost host="db1"url="10.0.0.51:3307" user="root"password="123">
配置读节点 可以配置多个
<readHost host="db2"url="10.0.0.51:3309" user="root"password="123" />
</writeHost>
</dataHost>
</mycat:schema>
如果写入节点主库宕机从库也不能提供读的服务, 如果故障节点短时间恢复了就会变成被主状态
<dataHost name="localhost1"maxCon="1000" minCon="10" balance="1"writeType="0" dbType="mysql"dbDriver="native" switchType="1">
balance="1" 指的是读操作的负载均衡 默认是轮询
0不开启代表所有操作都在写节点做
2所有读的操作会在读写节点随机
writeType="0" 写的负载均衡
设置为1所有节点都会写入
0只有一台主机会被被写入
switchType="1"
-1代表不自动切换
1默认切换
2 基于mysql主从同步的状态决定是否切换
3基于 pxc mgc 切换机制
minCon="10" mycat在启动后,会在后端节点自动开启连接线程
maxCon="10" 最大并发连接数
sqlMaxLimit="100"仅限于启用,分片之后限制最大查询
mycat垂直分表
test库中有三张表巨大,把这三张表放到单独的分片
当我们访问a表mycat给我们路由到一个分片
当我们访问b表mycat给我们路由到一个分片
当我们访问c表mycat给我们路由到一个分片
简称垂直分表
需要加入两个datahost
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schemaxmlns:mycat="http://io.mycat/">
<schema name="TESTDB"checkSQLschema="false" sqlMaxLimit="100"dataNode="sh1">
查询user表,路由到sh1分片
<table name="user" dataNode="sh1"/>
当问order_t表,路由到sh2分片
<table name="order_t"dataNode="sh2"/>
</schema>
两个分片访问sh1分片路由到oldguo1
<dataNode name="sh1" dataHost="oldguo1"database= "taobao" />
<dataNode name="sh2" dataHost="oldguo2"database= "taobao" />
<dataHost name="oldguo1" maxCon="1000"minCon="10" balance="1" writeType="0"
dbType="mysql" dbDriver="native"switchType="1">
<heartbeat>select user()
</heartbeat>
<writeHost host="db1"url="10.0.0.51:3307" user="root"password="123">
<readHost host="db2"url="10.0.0.51:3309" user="root"password="123" />
</writeHost>
<writeHost host="db3"url="10.0.0.52:3307" user="root"password="123">
<readHost host="db4"url="10.0.0.52:3309" user="root"password="123" />
</writeHost>
</dataHost>
<dataHost name="oldguo2" maxCon="1000"minCon="10" balance="1" writeType="0"dbType="mysql" dbDriver="native"switchType="1">
<heartbeat>select user()
</heartbeat>
<writeHost host="db1"url="10.0.0.51:3308" user="root"password="123">
<readHost host="db2"url="10.0.0.51:3310" user="root"password="123" />
</writeHost>
<writeHost host="db3"url="10.0.0.52:3308" user="root"password="123">
<readHost host="db4"url="10.0.0.52:3310" user="root"password="123" />
</writeHost>
</dataHost>
</mycat:schema>
单表数据巨大水平拆分
把一张完整的表拆成多份,放到不同的分片上
分片策略
范围分片
取模
枚举
日期
hash
分片键 作为分片条件的列
1要选一个分片键,能够使得数据按照这个分片键均匀的分布到分片上
2要看拿什么列做查询多
比如说t3表
1行数比较多 2000w (1-1000wsh1分片 1000w01-2000wsh2分片)
范围分片
1修改schema.xml
加到
按照后面的auto-sharding-long 范围分片 mycat内部定制
<table name="t3" dataNode="sh1,sh2"rule="auto-sharding-long" />
rule.xml 在这个文件里面定制
vim rule.xml
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns> 分片键
<algorithm>rang-long</algorithm> 算法
</rule>
定制的方法
<function name="rang-long"class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition.long.txt</property> 定制如何分片
</function>
vim autopartition-long.txt
如果数字太大
k可以表示1000
可以表示10000
0-10=0 0-10到0号分片
10-20=1 10-20到1号分片
重启mycat
数据需要在两张表都有,只是有不同分段的数据
痛点访问有可能会集中在一个分片上会造成热点分片
取模分片
和分片个数有关
取模是数字列
当前分片键和节点数量取模
取余分片方式:分片键(一个列)与节点数量进行取余,得 到余数,将数据写入对应节点
1修改配置文件
<table name="t4" dataNode="sh1,sh2"rule="mod-long" />
2如何使用看rule.xml
vim rule.xml
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns> 分片键
<algorithm>mod-long</algorithm> 算法
</rule>
算法和几去取模,就是你的分片有几个
<property name="count">2</property
3重启mycat
mycat restart
月份分片
按照每个月分片
1要在配置文件中加一个
<table name="t4" dataNode="sh1,sh2"rule="sharding-by-month"" />
2查看rule.xml配置文件
<tableRule name="sharding-by-month">
<rule>
<columns>create_time</columns> 分片键
<algorithm>partbymonth</algorithm> 算法
</rule>
</tableRule>
<function name="partbymonth"
class="io.mycat.route.function.PartitionByMonth">
<property name="dateFormat">yyyy-MM-dd</property> 日期格式
<property name="sBeginDate">2020-01-01</property> 设定开始时间
</function>
3各个数据库创建表
4重启mycat
枚举分片(区域分片)
有一列专门存省的
没有定制策略的可以走默认分片
默认只能给数字列做为分片
1vim schema.xml
<table name="t5" dataNode="sh1,sh2"rule="sharding-by-intfile" />
2vim rule.xml
<tableRule name="sharding-by-intfile">
<rule>
<columns>name</columns> 那一列作为分片键
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<function name="hash-int"class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>定制如何分片
<property name="type">1</property> 加这一行就能支持字符串的
</function>
3vim partition-hash-int.txt 配置:
bj=0 北京的走0号分片
sh=1 上海的走1号分片
DEFAULT_NODE=1 来了别的可以走默认分片
4重启mycat
mycat全局表
有一张表会和其他表join
两个表的数据在不同分片会把两个表的数据拿到mycat在进行join
最好设置成全局表
a表做了分片要和t表进行join t表在每个节点是全量的数据
数据库的节点能帮我们做一波join操作会把有关联的数据拿到mycat
带来的压力
存储压力
数据量比较小的表
配置
vim schema.xml
<table name="t_area" primaryKey="id"type="global" dataNode="sh1,sh2" /> 设置t_area分布到所有节点类型为全局
er分片
两个表要join按照分片的分片的表去走
b表的数据跟a表指定分片规则走
1vim schema.xml
<table name="a" dataNode="sh1,sh2"rule="mod-long"> 如过调用过需要改个名字
<childTable name="b" joinKey="aid"parentKey="id" />
</table>
2自定制规则
修改rule.xml mod-log分片策略:
vim rule.xml
<tableRule name="mod-long_oldguo"> 如过调用过需要改个名字
<rule>
<columns>id</columns>
<algorithm>modlong_oldguo</algorithm>
</rule>
</tableRule>
<function name="mod-long_oldguo"class="io.mycat.route.function.PartitionByMod"> 如果调用过需要修改名字
<!-- how many data nodes -->
<propertyname="count">2</property> 自己定制方法
</function>
管理类操作
show @@help 查看帮助
在线重新加载配置
reload @@config : schema.xml
reload @@config_all : 所有配置重新加载
sql监控功能 会记录到日志里面
reload @@sqlstat=open | Open real-time sql stat analyzer
reload @@sqlstat=close | Close
real-time sql stat analyzer
查看mycat服务情况
show @@server ;
查看分片DN节点信息
show @@datanode;
show @@datanode where schema = ?;
查看后端节点
show @@datasource
show @@datasource where datanode=sh1;
报告心跳信息
show @@heartbeat
show @@heartbeat.detail where name=?
RS_CODE :
-1:连接失败
1 :连接正常
-2:连接超时
0 :初始化状态
如果节点故障,会有5次检测,失败后则状态为-1。
查看连接信息
show @@connection
关闭连接
kill @@connection id1,id2,...
查看后端连接
show @@backend
查看sql统计
mysql> show @@sql;
mysql> show @@sql_slow;
mysql> show @@sql.sum
日志管理
<asyncRoot level="info"includeLocation="true">
级别:All < Trace < Debug < Info < Warn <Error < Fatal < OFF
调试建议使用 Debug 级别,生产上一般使用 Info级别
vim server.xml
该属性用于字符集设置。
<system>
<property
name="charset">utf8</property>
</system> 按照数据库端设置就行
processors 属性:
该属性主要用于指定系统可用的线程数,默认值为机器
CPU 核心线程数。主要影响 processorBufferPool、
processorBufferLocalPercent、
processorExecutor 属性。NIOProcessor 的个数也
是由这个属性定义的,所以调优的时候可以适当的调高这个
属性
mycat本身可以连接的线程数
processorBufferChunk 属性:
该属性指定每次分配 Socket Direct Buffer 的
大小,默认是 4096 个字节。这个属性也影响 buffer
pool 的长度。如果一次性获取的数过大 buffer 不够用
会经常出现警告,此时可以适当调大。
processorBufferPool 属性:
该属性指定 bufferPool 计算比例值。由于每次执行
NIO 读、写操作都需要使用到 buffer,系统初始化的时
候会建立一定长度的 buffer 池来加快读、写的效率,减
少建立 buffer 的时间。Mycat 中有两个主要的buffer 池:
BufferPool:BufferPool 由
ThreadLocalPool 组合而成,每次从 BufferPool 中
获取 buffer 都会优先获取ThreadLocalPool 中的
buffer,未命中之后才会去获取 BufferPool 中的
buffer。也就是说 ThreadLocalPool 是作为
BufferPool 的二级缓存,每个线程内部自己使用的。
BufferPool 上的 buffer 则是每个 NIOProcessor
都共享的。这个属性的默认值为:
默认bufferChunkSize(4096) * processors属
性 * 1000
BufferPool 的总长度 = bufferPool /
bufferChunk。
若 bufferPool 不是 bufferChunk 的整数倍,
则总长度为前面计算得出的商 + 1
假设系统线程数为 4,其他都为属性的默认值,则:
bufferPool = 4096 * 4 * 1000
BufferPool 的总长度 : 4000 = 16384000 / 4096
processorBufferLocalPercent 属性:
前面提到了 ThreadLocalPool。这个属性就是用来
控制分配这个 pool 的大小用的,这个属性默认值为100。
线程缓存百分比 = bufferLocalPercent /
processors 属性。
例如,系统可以同时运行 4 个线程,使用默认值,则
根据公式每个线程的百分比为 25。最后根据这个百分比来
计算出具体的 ThreadLocalPool 的长度公式如下:
ThreadLocalPool 的长度 = 线程缓存百分比 *
BufferPool 长度 / 100
假设 BufferPool 的长度为 4000,其他保持默认值。
那么最后每个线程建立上的 ThreadLocalPool 的长
度为: 1000 = 25 * 4000 / 100
心跳属性
mycat 中有几个周期性的任务来异步的处理一些我需要的
工作。这些属性就在系统调优的过程中也是比不可少的。
processorCheckPeriod :
清理 NIOProcessor 上前后端空闲、超时和关闭连
接的间隔时间。默认是 1 秒,单位毫秒。
dataNodeIdleCheckPeriod :
对后端连接进行空闲、超时检查的时间间隔,默认是
300 秒,单位毫秒。
dataNodeHeartbeatPeriod :
对后端所有读、写库发起心跳的间隔时间,默认是 10
秒,单位毫秒。
服务相关属性
bindIp :
mycat 服务监听的 IP 地址,默认值为 0.0.0.0。
serverPort :
定义 mycat 的使用端口,默认值为 8066。
managerPort :
定义 mycat 的管理端口,默认值为 9066
Mysql 连接相关属性
packetHeaderSize :
指定 Mysql 协议中的报文头长度。默认 4。
maxPacketSize :
指定 Mysql 协议可以携带的数据最大长度。默认16M。
idleTimeout :
指定连接的空闲超时时间。某连接在发起空闲检查下,
发现距离上次使用超过了空闲时间,那么这个连接会被回
收,就是被直接的关闭掉。默认 30 分钟,单位毫秒。
charset :
连接的初始化字符集。默认为 utf8。
txIsolation :
前端连接的初始化事务隔离级别,只在初始化的时候使
用,后续会根据客户端传递过来的属性对后端数据库连接进
行同步。默认为 REPEATED_READ,设置值为数字默认3。
READ_UNCOMMITTED = 1;
READ_COMMITTED = 2;
REPEATED_READ = 3;
SERIALIZABLE = 4;
sqlExecuteTimeout :
SQL 执行超时的时间,Mycat 会检查连接上最后一次
执行 SQL 的时间,若超过这个时间则会直接关闭这连接。
默认时间为 300 秒,单位秒
逻辑库配置
每次登录mycat都是tsdb
vim server.xml
1schema.xml
<schema name="oldguo"checkSQLschema="false" sqlMaxLimit="100"dataNode="sh1">
</schema>
2server.xml
server.xml
<user name="root" defaultAccount="true">
<propertyname="password">123456</property>
<propertyname="schemas">oldguo</property>
<propertyname="defaultSchema">oldguo</property>
<!--No MyCAT Databaseselected 错误前会尝试使用该schema作为schema,不
设置则为null,报错 -->
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schemaname="TESTDB" dml="0110" >
<tablename="tb01" dml="0000"></table>
<tablename="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user">
<property
name="password">user</property>
<property
name="schemas">oldguo</property>
<property
name="readOnly">true</property>
<property
name="defaultSchema">oldguo</property>
</user>
reload @@config_all : 所有配置重新加载
新增逻辑库
添加一个逻辑库
schema.xml
<schema name="oldguo"checkSQLschema="false" sqlMaxLimit="100"dataNode="sh1">
</schema>
server.xml
<property
name="schemas">oldguo,oldguo</property>
reload @@config_all : 所有配置重新加载
sequence分布式全局
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。