1 MySQL分布式架构演变
- 垂直分割:同库的不同表分库分表
- 水平分割:同表的不同列拆分。
常用的分片策略 :- 对id取余\模,优点:数据分布均匀。缺点:扩容麻烦
- 按照范围分片:比较好扩容,数据分布不均匀
- 按照时间分片:比较容易将热点数据区分出来
- 按照枚举值分片:例如按照地区分片
- 按照目标字段前缀指定进行分区:自定义业务规则分片
2 架构图
两个服务器节点10.0.0.51和10.0.0.52,每个服务器节点起4个进程,分为两个集群。
#两节点3307双主,3309作为3307的从库
10.0.0.51:3307 <-----> 10.0.0.52:3307
10.0.0.51:3309 ------> 10.0.0.51:3307
10.0.0.52:3309 ------> 10.0.0.52:3307
#两节点3308双主,3310作为3308的从库
10.0.0.51:3308 <-----> 10.0.0.52:3308
10.0.0.51:3310 ------> 10.0.0.51:3308
10.0.0.52:3310 ------> 10.0.0.52:3308
3 MyCat安装部署
3.1 安装java环境
安装jdk,https://www.oracle.com/java/technologies/javase-downloads.html
或
yum -y install java
3.2 安装MyCat
从官网http://www.mycat.org.cn/下载安装包
解压到
/usr/local
目录下
mv mycat /usr/local/
配置环境变量
3.3 MyCat命令
mycat start 启动
mycat stop 停止
mycat console 前台运行
mycat install 添加到系统自动启动(暂未实现)
mycat remove 取消随系统自动启动(暂未实现)
mycat restart 重启服务
mycat pause 暂停
mycat status 查看启动状态
3.4 MyCat连接
MyCat对外提供的端口是8066
mysql -uroot -p123456 -P8066 -h127.0.0.1
3.5 后端数据库配置autocommit
MyCat无法自动提交,后端数据库需要配置autocommit
4 MyCat配置
4.1 MyCat目录结构
- bin:程序目录,mycat程序,启动和关闭mycat中间件
- conf:配置相关目录
- schema.xml:主配置文件,逻辑库定义和表以及分片定义的配置文件
- rule.xml:分片规则配置
- server.xml:Mycat服务参数调整和用户授权的配置文件
注意:schema.xml文件中的
schema name="scott"
和server.xml配置文件中的2处schema名称要一致。
scott
- logs:日志相关目录
- wrapper.log:mycat启动的相关日志
- mycat.log:mycat运行日志
4.2 schema.xml配置解析
schema.xml的逻辑结构
4.2.1 逻辑库:schema
4.2.2 数据节点:datanode
逻辑分片,进行垂直和水平拆分。
4.2.3 数据主机:datahost
高可用和读写分离,通过writeHost
和readHost
两个主机实现
select user()
balance参数
负载均衡类型,目前取值有3种:
1.balance="0",不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
2.balance="1",全部的readHost与standby writeHost参与select语句的负载均衡。当双主双从模式(M1->S1,M2->S2,并且M1与M2互为主备),正常情况下,M2、S1、S2都参与select语句的负载均衡。
3.balance="2",所有读操作都随机的在writeHost、readHost上分发。
writeType属性
负载均衡类型,目前取值有2种:
1.writeType="0",所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为主,切换记录在配置文件中:dnindex.properties
2.writeType="1",所有写操作都随机的发送到配置的writeHost,不推荐使用。
switchType属性
-1 表示不自动切换
1 默认值,自动切换
maxCon=1000
最大的并发连接数
minCon=10
mycat启动之后,会在后端节点上自动开启的连接线程数
tempReadHostAvailable="1"
一主一从时(1个writehost,1个readhost),可以开启,当主宕机时从库仍旧能够提供读的操作。
2个writehost,2个readhost时,不需要开启。
4.2.4 用户访问逻辑
4.3 schema.xml单数据节点读写分离
vim mycat/conf/schema.xml
select user()
4.4 schema.xml单数据节点读写分离及高可用
真正的 writehost:负责写操作的writehost,配置文件中的第一个writeHost(db1)
standby writeHost :正常时和readhost一样,只提供读服务,为配置文件中的其他writeHost(db3)
- 正常时,db1提供写服务,db2、db3、db4提供读服务。
- 当写节点(db1)宕机后,后面跟的readhost(db2)也不提供服务,这时候standby writehost(db3)接管写服务,后面跟的readhost(db4)提供读服务。
- 原写节点(db1)恢复后,成为standby writehost,提供读服务,后面跟的readhost(db2)也重新启用提供读服务。
- 故障恢复后,db3提供写服务,db1、db2、db4提供读服务
select user()
4.4 schema.xml垂直分表
逻辑库scott,默认使用dataNode:node1。
垂直分表:
- 表user使用dataNode:node1
- 表order_t使用dataNode:node2
- 其余表使用dataNode:node1
dataNode:node1使用dataHost:host1、库taobao。
dataNode:node2使用dataHost:host2、库taobao。
总结:
host1需要有真实的taobao库、user表、其余表
host2需要有真实的taobao库、order_t表
整体配置
select user()
select user()
4.5 schema.xml水平分表
4.5.1 范围分表
适用场景:
- 行数非常多,2000w行(1-1000w:node1,1000w-2000w:node2)
- 访问非常频繁,用户访问离散
逻辑库scott,默认使用dataNode:node1。
水平分表:
- 表t3依据分片规则
auto-sharding-long
使用dataNode:node1、node2 - 其余表使用dataNode:node1
dataNode:node1使用dataHost:host1、库taobao。
dataNode:node2使用dataHost:host2、库taobao。
总结:
host1需要有真实的taobao库、t3表、其余表
host2需要有真实的taobao库、t3表
4.5.1.1 schema.xml配置
select user()
select user()
4.5.1.2 分表rule配置
schema.xml
中配置使用auto-sharding-long
规则
rule.xml
中定义了auto-sharding-long
的rule:
- 依据
id
列 - 使用
rang-long
规则
rule.xml
中定义了rang-long
的规则:
- 使用
autopartition-long.txt
配置文件
autopartition-long.txt
文件中定义:默认按500W数据分配一个datanode
4.5.2 取模分表
分片方式:分片键(一个列)与节点数量进行取余,得到余数,按照余数将数据写入对应dataNode,0对应第1个dataNode,1对应第2个dataNode...
4.5.2.1 schema.xml配置
select user()
select user()
4.5.2.2 分表rule配置
schema.xml
中配置使用mod-long
规则
rule.xml
中定义了mod-long
的rule:
- 依据
id
列 - 使用
mod-long
规则
rule.xml
中定义了mod-long
的规则:
-
count
配置为dataNode
数量
4.5.3 枚举分表
分片方式:分片键(一个列)进行枚举,依据枚举匹配,将数据写入对应节点,0对应第1个dataNode,1对应第2个dataNode...
4.5.3.1 schema.xml配置
select user()
select user()
4.5.3.2 分表rule配置
schema.xml
中配置使用sharding-by-intfile
规则
rule.xml
中定义了sharding-by-intfile
的rule:
-
columns
定义使用name
列枚举 - 使用
hash-int
规则
rule.xml
中定义了hash-int
的规则:
- 使用
partition-hash-int.txt
配置文件 -
type
为1
,使用字符串
枚举 -
defaultNode
为0
,当没有匹配到枚举列时,使用0
号dataNode
作为默认节点
partition-hash-int.txt
文件中定义:枚举字符串为sh
和bj
。
4.6 全局表
当进行多表join查询时,性能很差。尤其在MyCat中跨dataNode进行join查询时。
全局表的使用场景:
对于经常需要被join查询的表,例如查询t1、t2、t3表时都需要join到t表,将t表做成全局表,在所有的dataNode上保存一份t表,Mycat 在Join操作中,业务表与全局表进行Join聚合会优先选择相同分片内的全局表join,避免跨库Join。
4.6.1 全局表数据读写
在进行数据插入操作时,mycat将把数据分发到全局表对应的所有dataNode执行,在进行数据读取时候将会随机获取一个节点读取数据。
4.6.2 schema.xml配置
primaryKey
="id"
,表示表的主键是id
type
="global"
,表示表是全局表
4.7 E-R分片
为了解决跨dataNode进行join查询的问题,进行E-R分片,将进行join查询的2张表按照关联列分片到相同的dataNode,避免跨dataNode的join查询。
4.7.1 E-R分片场景
表a
id | name |
---|
表b
id | addr | aid |
---|
join查询语句
select * from a join b on a.id=b.aid where a.name='b'
分片方式:
由于条件是a.id=b.aid,将表a按照id列分片时,将表b按照aid列进行相同的规则分片,保证a.id=b.aid的数据在一个dataNode上
4.7.2 schema.xml配置
rule="mod-long-ajoinb"
,使用mod-long取模分片规则,为了不与其他表共用mod-long默认规则,使用新建的mod-long-ajoinb规则
joinKey="aid"
,表b的分片键
parentKey="id"
,表a的分片键
4.7.3 rule配置
配置rule.xml
,新增mod-long-ajoinb
tableRule
id
mod-long-ajoinb
新增mod-long-ajoinb
function
2