MyCat
是一個功能強大的分佈式數據庫中間件,是一個實現了 MySQL
協議的 Server
,前端人員能夠把它看作是一個數據庫代理中間件,用 MySQL
客戶端工具和命令行訪問;然後端人員能夠用 MySQL
原生協議與多個 MySQL
服務器通訊,也能夠用 JDBC
協議與大多數主流數據庫服務器通訊。能夠用做 讀寫分離、分庫分表(分片)、容災備份、多租戶應用開發、大數據基礎設施,使底層數據架構具有很強的適應性和靈活性。前端
MyCat
的智能優化模塊可使系統的數據訪問瓶頸和熱點一目瞭然,而且能夠將這些統計分析數據自動或手工調整後端存儲,將不一樣的表映射到不一樣存儲引擎上,而整個應用的代碼能夠一行也不用變。node
Hbase
:用於分析大數據;本文主要實踐核心功能 分庫分表。mysql
指經過某種特定的條件,將存放在同一個數據庫中的數據分散存放到多個數據庫上面,以達到分散單臺設備負載的效果。git
根據切分規則的類型能夠分爲如下兩種切分模式。github
垂直切分:最大特色是規則簡單,適合各業務之間的的耦合度很是低、相互影響小、業務邏輯很是清晰的系統。在這種系統中,能夠很容易 將不一樣業務模塊所使用的的表切到不一樣的數據庫中。sql
水平切分:相對來講複雜一些,由於要 將同一個表中的不一樣數據切分到不一樣的數據庫中,後期的數據維護也更爲複雜一些。docker
一個數據庫由不少表構成,每一個表對應着不一樣的業務,垂直切分就是按照業務將表進行分類,從而分佈到不一樣的數據庫上面,這樣也就將壓力分擔到不一樣的數據庫上,如圖。數據庫
一個架構設計好的系統其整體功能一般是由多個功能模塊所組成的,而每個功能模塊的數據對應到數據庫中就是一個或多個表。而在架構設計中,各個功能模塊相互之間的交互點越少和越統一,系統的耦合度就越低,系統各個模塊的維護性以及擴展性也就越好,這樣的系統也就越容易實現垂直切分。後端
可是每每系統中有些表難以作到徹底的獨立,存在跨庫 join
的狀況,對於這類分庫,能夠共用一個數據源,業務之間經過接口來調用。服務器
優勢:規則明確、業務清晰、更易於整合和擴展、維護簡單。
缺點:部分業務表沒法 join
,須要經過業務接口方式解決,提升系統複雜度;各業務存在單庫性能瓶頸,不易於數據擴展和性能提升;事務處理複雜問題。
因爲垂直切分是將表按照業務分類切分到不一樣的單庫中,全部致使某些業務表過於龐大,存在單庫讀寫與存儲瓶頸,則須要水平切分來解決。
水平切分不是將表按照業務分類,而是按照某個字段的某種規則分散到多個庫中,每一個表中包含一部分數據,如圖。
拆分數據須要定義分片規則,拆分的第一原則是找到 拆分維度。好比:從會員的角度來分析,須要查詢會員某天某月某個訂單,那麼就須要按照日期來拆分,不一樣的數據按照會員 ID 作分組。
優勢:拆分規則抽象好;不存在單庫數據瓶頸問題;提升系統穩定性和負載能力。
缺點:事務一致性難以解決;數據擴展和維護的難度極大;跨庫 join 性能差。
均採用 Docker Compose 搭建服務
分別建立 3 份 docker-compose.yml
文件
mysql-01
version: '3.1' services: mysql-1: image: mysql container_name: mysql-01 environment: MYSQL_ROOT_PASSWORD: 123456 command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1 ports: - 3306:3306 volumes: - ./data:/var/lib/mysql
mysql-02
version: '3.1' services: mysql-2: image: mysql container_name: mysql-02 environment: MYSQL_ROOT_PASSWORD: 123456 command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1 ports: - 3307:3306 volumes: - ./data:/var/lib/mysql
mysql-03
version: '3.1' services: mysql-3: image: mysql container_name: mysql-03 environment: MYSQL_ROOT_PASSWORD: 123456 command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1 ports: - 3308:3306 volumes: - ./data:/var/lib/mysql
分別啓動 3 臺容器
$ docker-compose up -d
克隆項目
$ git clone https://github.com/antoniopeng/docker.mycat.git
構建鏡像
$ cd docker.mycat $ docker-compose build
啓動容器
$ docker-compose up -d
此處以 水平切分 爲例
$ vi config/mycat/server.xml
找到第 90 行,參考配置以下:
<mycat:server xmlns:mycat="http://io.mycat/"> <user name="root"> <property name="password">123456</property> <property name="schemas">hellomycat</property> <property name="usingDecrypt">0</property> </user> </mycat:server>
$ vi config/mycat/schema.xml
參考配置以下:
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="hellomycat" checkSQLschema="true" sqlMaxLimit="100"> <table /> </schema> <dataNode name="dataNode1" dataHost="dataHost1" database="hellomycat_1" /> <dataNode name="dataNode2" dataHost="dataHost2" database="hellomycat_2" /> <dataNode name="dataNode3" dataHost="dataHost3" database="hellomycat_3" /> <dataHost name="dataHost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="192.168.127.130" url="jdbc:mysql://192.168.127.130:3306?useSSL=false&serverTimezone=UTC&characterEncoding=utf8" user="root" password="123456"> </writeHost> </dataHost> <dataHost name="dataHost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="192.168.127.130" url="jdbc:mysql://192.168.127.130:3307?useSSL=false&serverTimezone=UTC&characterEncoding=utf8" user="root" password="123456"> </writeHost> </dataHost> <dataHost name="dataHost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="192.168.127.130" url="jdbc:mysql://192.168.127.130:3308?useSSL=false&serverTimezone=UTC&characterEncoding=utf8" user="root" password="123456"> </writeHost> </dataHost> </mycat:schema>
$ vi config/mycat/rule.xml
第 32 行配置
<tableRule name="auto-sharding-long"> <rule> <columns>id</columns> <algorithm>rang-long</algorithm> </rule> </tableRule>
第 105 行配置
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong"> <property name="mapFile">autopartition-long.txt</property> </function>
$ vi config/mycat/autopartition-long.txt
配置以下:
# range start-end ,data node index # K=1000,M=10000. # ID 0-5000000 保存在 dataNode1 0-500M=0 # ID 5000000-10000000 保存在 dataNode2 500M-1000M=1 # ID 10000000-15000000 保存在 dataNode3 1000M-1500M=2
使用 MySQL 客戶端工具鏈接 MyCat,默認端口號爲 8066
。
分別在 3 個數據庫中建立表,只須要 ID 一個字段便可:
create table sys_user (id int not null primary key);
新增數據:
insert into sys_user(id) values(2000000); insert into sys_user(id) values(7000000); insert into sys_user(id) values(1200000);
新增後若是 3 個數據庫的表中都出現了一條數據,則說明分片成功。
- 文章做者:彭超
- 本文首發於我的博客:https://antoniopeng.com/2020/08/20/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%AD%E9%97%B4%E4%BB%B6%20MyCat%20-%20%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8%E5%AE%9E%E8%B7%B5/
- 版權聲明:本博客全部文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 彭超的博客 | Antonio Blog