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配置註冊中心信息