11.1 Mycat 11.2 sharding-jdbc
11.1 Mycat
性能很好的分库分表中间件
大数据集群,加强版mysql数据库,融合内存缓存,NoSql,HDFS大数据的新SQL服务器
应用场景
分库分表,读写分离,替代Hbase分析大数据,海量数据实时查询
Mycat工作原理
1 将订单表order表按照省分片
2 应用连接Mycat提交SQL
3 Mycat拦截
解析SQL,分片分析,路由,读写分离,缓存等一系列分析
然后orderBy,groupBy排序等合并结果集
架构
核心概念
逻辑层
逻辑库:数据库
逻辑表:分库分表储存的表
dataNode:逻辑表分片的存放节点
dataHost: dataNode所在的主机
物理层
writeHost:真实数据库负责写的主机
readHost:真实数据库负责读的主机
schema中配置逻辑概念
所有分片需要schema定义 dataNode/dataHost, childTable定义ER分片子表,与父类关联等
应用
配置Mycat读写分写
1 配置mysql主从数据自动同步,mycat不负责数据的同步问题
mysql主库 配置主节点,开启binlog
mysql从库
配置server-id,
CHANGE MASTER TO同步主库地址
开启从库 mysql>START SLAVE
2 Mycat配置读写分离
conf/server.xml中可以看用户名,密码,IP,port等配置信息
<user name="root" ...>
<property name="password">123456</>
<~="schemas">mydb1</>
schema.xml配置文件中
元素配置必须按照schema name="mydb1", dataNode,dataHost顺序配置
方法1
<dataHost name=...>
<heartbeat>
<writeHost host="host1M1" url="localhost:3306" user="root" password="123456">//配置写的主库
<readHost host="~" url="~" user="root" password="123456"/>//可配置多个读从库
<readHost ~/>
</writeHost>
但是该方法当写主库挂了,从读库也不能使用了。则方法2可以解决该问题
方法2
<dataHost ... writeType="0"> //writeType="0"表示第一个writeHost负责写,其他负责读
<writeHost host=....>
<writeHost host=....>
</>
Mycat分库分表
分片表,数据太大切分到多个数据库表,所有分片构成完整的数据
1 分片表
<table name="t_goods" primaryKeys="vid" autoIncrement="true" dataNode="dn1,dn2" rule="rule1"/>
//name制定表名,dataNode制定多个分片节点,rule制定分片规则
2 非分片表
<... 同上 ... dataNode="dn1"> //只制定一个节点,无需分片规则
3 ER表
<table name="customer" ...同上... dataNode="dn1,dn2" rule="sharding-by-infile">
<childTable name="orders" ...
<childTable ...
</~>
</~>
//有联级关系,用childTable讲父子关系放在相同分片上,保证数据join不会跨库
4 全局表
真实中往往有很少改动但是需要大量join的表,可以冗余处理
<tablie name="company" ~~~ type="global" dataNode="dn1,dn2,dn3...">
//在指定的所有节点上冗余复制一份,就不需要跨库了
分片规则(conf/rule.xml中规定)
如前面rule1中
<tableRule name="rule1">
<rule>
<colums>id</colums> //根据id分片
<algorithm>id</algorithm> //分片的算法
</rule>
<function name="func1" class=""io.mycat.xxx>//定义算法
<...>
<...>
</function>
分库分表原则
分片:
1 能不分则不分,1000万以内不建议分(读写分离,索引已经能很好处理)
2 分片数量尽量少,尽量均匀DataHost
3 分片规则慎重
4 一个事务sql尽量不要跨多个分片
5 查询条件尽量优化,如避免select*
数据拆分
1 800万数据以上再拆分
2 大表关联
1 小于100则用全局表
2 大于100万,小于800万用和大表相同的拆分策略。
无法使用相同策略的,java代码上分步骤处理不走join或者破例全局表
3 破例全局表必须不能有太激烈的并发更新
3 拆分后每个库数据要小于800万
DataNode分布
理想:在几个DataHost上均匀分布,比如Node1对应Mysql1,Node2对应Mysql2推类
Mycat内置常用分片规则
1 分片枚举(非int数据列表分片,比如按照地区省市)
2 范围分片(如id范围)
3 按日期范围分片
4 按月份
5 取模
6 取模范围
7 二进制取模范围
等等
Mycat有事务管理器,2PC模式处理分布式事务
主键值生成
Mycat提供全局序列
1 本地文件方式
1 sequence_conf.properties文件中配置
GLOBAL.HISIDS=
GLOBAL.MINID=1001
GLOBAL.MAXID=
GLOBAL.CURID=当前id
2 server.xml中配置
<system><property name="sequenceHandlerType">0</propery></system>
//0表示使用本地文件方式
也可以为表配置主键自增值序列
sequence_conf.properties下
T_COMPANY.CURID = 501
T_COMPANY.MINID = xx
T_COMPANY.MAXID = xx
缺点:Mycat重新发布后,sequence会恢复初始值
有点:本地读取快
2 数据库方式
数据库创建sequence表存name,current_value,步长等信息,Mycat来维护这张表
server.xml下配置sequenceHandlerType为1
3 本地时间戳 Type为2
4 分布式Zookeeper ID生成Type为3
5 ZK递增
6 分片表主键自增
Mycat高可用
11.2 sharding-jdbc
轻量级Java框架,jar包形式类似增强版jdbc,完全兼容JDBC和orm框架
混合架构
应用
读写分离
1 binlog开启主从同步数据
2 SringBoot中加maven依赖
application.yml配置
sharding:
jdbc:
datasource:
names:ds0,ds1 //数据源
ds0:
type
driver-class
url
username
password
maxPoolSize
minPoolSize
ds1:一样
默认选择哪个数据源
masterSlaveRule //配置读写分离
name:ds_ms //读写分离集群名
masterDataSourceName:ds0
slaveDataSourceName:[ds1,ds2....]或者ds1
分库分表
逻辑表,dataNode,dataHost和Mycat一致
5中分片策略
1 不分片
2 行表达式分片(主流)
根据行表数量取模
区间,枚举
yml中
actual_data_nodes:db0.t_order(),db0.t_order1(),....//db0是dataNode,t_order()是逻辑表
inline:
sharding_column:customer_id
algorithm_expressio:ds$->{customer_id%2}
3 标准分表
等等
分布式主键
yml配置,默认提供雪花,UUID
绑定表(对应Mycat ER表)
主表,子表分片规则一致,放到相同分片上
否则笛卡尔积太复杂且跨库
广播表(对应Mycat全局表)
指所有分片都存在的表,如字典表。
Sharding-JDBC分布式事务
1 maven加入
2 应用
@ShardingTransactionalType(TransactionType.LOCAL) //或者TransactionType.XA则是强一致性。不跨库用local,跨库用XA
@Transactional
两个注解一起使用
注册中心 Zookeeper
1 maven加入
2 yml配置注册中心信息