分庫分表中間件
分庫分表的缺點:
- 引入分布式事務的問題;
- 跨節點 Join 的問題;
- 跨節點合并排序分頁等聚合類SQL問題;
- 多數據源管理問題;
- 擴容縮容,數據遷移等問題;
分庫分表的經驗:
- 第一原則:能不切分盡量不要切分。
- 第二原則:如果要切分一定要選擇合適的切分規則,提前規劃好。
- 第三原則:數據切分盡量通過數據冗余或表分組(Table Group)來降低跨庫 Join 的可能。
- 第四原則:由于數據庫中間件對數據 Join 實現的優劣難以把握,而且實現高性能難度極大,業務讀取盡量少使用多表 Join。
接下來主要比較cobar,mycat,sharding-jdbc三個人氣較高的分庫分表中間件;
1. cobar
Cobar is a proxy for sharding databases and tables,compatible with MySQL protocal and MySQL SQL grama,underlying storage only support MySQL for support foreground business more simple,stable,efficient and safety。
說明:cobar的前身是amoeba;
網址
- cobar github
- cobar 官網 -- 無
架構圖
特性
- 不支持跨庫(數據節點)的關聯操作:join、分頁、排序、子查詢。
- BLOB, BINARY, VARBINARY字段不能使用。若特殊需求需要這三種字段,禁止使用PreparedStatement的setBlob()或setBinaryStream()方法設置參數。
- 對于拆分表(分庫表),不能更新已有記錄的拆分字段(分庫字段)值。
- 只支持MySQL數據節點,使用mysql-jdbc-5.1以上版本,推薦5.1.6或者5.1.12版本。
- 對于拆分表,插入操作須給出列名,必須包含拆分字段。
備注: cobar限制摘自cobar github
SQL優化示例
- select * from t_order where partition_key in(...)的優化(根據條件往目標服務器上發送SQL然后對返回的結果merge)
- select * from t_order where user_id=12 and article_id=10023的優化(兩個字段作為拆分字段:X軸上user_id取模,Y軸上article_id取模)
- select * from t_order order by txn_time desc limit 100,2的優化(方式1:往所有服務器上發送limit 0, 102然后對返回的結果merge,如果偏移量太大,問題比較嚴重;方式2:假設各個分庫數據分布大致一樣... ...)
- select sum(price) from t_order group by item_id的優化(往所有服務器上發送select sum(price), item_id from t_order group by item_id order by item_id然后對返回的結果merge)
cobar缺點
- SQL批處理模式采用SQL并發執行,所以事務會跨庫,可能導致數據不一致;
- cobar前端后端之間的"寫隊列"可能導致阻塞,MyCAT將數據結構由數組改為鏈表,且達到指定閾值會產生告警日志;
- 部署雙機cobar負載均衡前提下,可能出現主備兩個庫都在寫數據;原因是cobar啟動時默認第一個datasource進行數據讀寫操作;
- cobar連接池的缺陷,cobar連接池的管理基于分片,假設db-server1和db-server2上各50個分片,且連接池上限為1000,那么每個片只有20個連接在連接池中;各分片之間的連接池不互通,從而導致饑飽不均--db-server1上可用連接充足但是某分片連接耗盡;
- 不支持讀寫分離;
來源于MyCAT權威指南
2. MyCAT
MyCAT is an enforced database which is a replacement for MySQL and supports transaction and ACID. MyCAT is combined with the traditional database and new distributed data warehouse. In a word, MyCAT is a fresh new middleware of database. Mycat’s target is to smoothly migrate the current stand-alone database and applications to cloud side with low cost and to solve the bottleneck problem caused by the rapid growth of data storage and business scale.
說明:MyCAT的前身是cobar,1.4 版本以后 完全的脫離基本cobar內核;
網址
特性
- 遵守Mysql原生協議,跨語言,跨平臺,跨數據庫的通用中間件代理。
- 基于心跳的自動故障切換,支持讀寫分離,支持MySQL主從,以及galera cluster集群。
- 支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster。
- 支持單庫內部任意join,支持跨庫2表join,甚至基于caltlet的多表join。
- 集群基于ZooKeeper管理,在線升級,擴容,智能優化,大數據處理(2.0開發版)。
- 支付多租戶;
MyCAT特性來源于MyCAT官網
3. shardding-jdbc
Sharding-JDBC is a JDBC extension, provides distributed features such as sharding, read/write splitting, BASE transaction and database orchestration.
網址
架構圖
特性
- Aggregation functions, group by, order by and limit SQL supported in distributed database.
- Join (inner/outer) query supported.
- Sharding operator =, BETWEEN and IN supported.
- Sharding algorithm customization supported.
- Hint supported(強制主庫路由).
- BASE Transaction(柔性事務--最大努力送達事務).
- Read/Write Splitting.
- Distributed Unique Time-Sequence Generation.
限制
- 不支持or;(1.5.x之前支持OR,1.5.x之后不再支持,原因是有or時SQL的解析和路由都非常復雜,某些or的SQL性能非常差不適合分布式數據庫使用)
- 不支持HAVING
- 不支持UNION & UNION ALL
- 不支持DISTINCT聚合
- 不支持存儲過程,函數,游標的操作
- 不支持執行native的SQL
- 不支持savepoint相關操作
- 不支持Schema/Catalog的操作
- 不支持自定義類型映射
sharding-jdbc限制來源于http://shardingjdbc.io/1.x/docs/01-start/limitations/
分庫分表
- 支持多分片鍵
- 支持通過=,BETWEEN,IN分片
- 支持級聯表
- 支持多表笛卡爾積查詢
- 支持多表結果歸并
- 支持聚合查詢結果歸并
- 支持AVG函數改寫為SUM/COUNT
- 支持ORDER BY結果歸并
- 支持GROUP BY結果歸并
- 支持LIMIT分頁查詢以及多庫表結果改寫及歸并