DBLE 是企業級開源分布式中間件,江湖人送外號 “MyCat Plus”;以其簡單穩定,持續維護,良好的社區環境和廣大的群眾基礎得到了社區的大力支持;
環境准備
DBLE項目資料
-
DBLE官方網站:https: //opensource.actionsky.com
-
可以詳細了解DBLE的背景和應用場景,本文不涉及到的細節都可在官方文檔獲得更細節都信息;對於剛了解到同學,可以以本文為快速入門基礎
-
-
DBLE官方項目:https: //github.com/actiontech/dble
-
如對源碼有興趣或者需要定制的功能的可以通過源碼編譯
-
-
DBLE下載地址:https: //github.com/actiontech/dble/releases
-
建議下載最新的releases版本,下載tar壓縮包即可,如有源碼編譯需求的,可以下載源碼包
-
DBLE社區交流: 669663113
-
安裝JDK環境
DBLE是使用java開發的,所以需要啟動dble需要先在機器上安裝java版本1.8或以上,並且確保JAVA_HOME參數被正確的設置;
這里通過yum源的方式安裝了openjdk,同學們可以自行google jdk的幾百種安裝方式,這里不在贅述;
# yum install java-1.8.0-openjdk
確認java環境已配置完成
-
# java -version
-
openjdk version "1.8.0_191"
-
OpenJDK Runtime Environment (build 1.8.0_191-b12)
-
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
安裝DBLE
DBLE的安裝其實只要解壓下載的目錄就可以了,非常簡單。
- 通過此連接下載最新安裝包https://github.com/actiontech...
- 解壓並安裝dble到指定文件夾中
-
mkdir -p $working_dir
-
cd $working_dir
-
tar -xvf actiontech-dble- $version.tar.gz
-
cd $working_dir/dble/conf
安裝完成后,目錄如下:
目錄 | 說明 |
---|---|
bin | dble命令:啟動、重啟、停止等 |
conf | dble配置信息,本文重點關注 |
lib | dble引用的jar包 |
logs | 日志文件,包括dble啟動的日志和運行的日志 |
配置DBLE
DBLE的配置文件都在conf目錄里面,這里介紹幾個常用的文件:
文件 | 說明 |
---|---|
server.xml | DBLE server相關參數定義,包括dble性能,定時任務,端口,用戶配置等;本文主要涉及到訪問用戶的配置 |
schema.xml | DBLE具體分片定義,規定table和schema以及dataNode之間的關系,指定每個表格使用哪種類型的分片方法,定義每個dataNode的連接信息等 |
rule.xml | DBLE實際用到的分片算法的配置 |
應用場景一:數據拆分
后端MySQL節點
DBLE的架構其實很好理解,DBLE是代理中間件,DBLE后面就是物理數據庫。對於使用者來說,訪問的都是DBLE,不會接觸到后端的數據庫。
我們先演示簡單的數據拆分的功能。物理部署結構如下表:
服務 | IP:Port | 說明 |
---|---|---|
DBLE | 172.16.3.1:9066 | DBLE實例,連接數據庫時,連接此IP:Port |
Mysql A | 172.16.3.1:14014 | 物理數據庫實例A,真正存儲數據的數據庫 |
Mysql B | 172.16.3.1:14015 | 物理數據庫實例B,真正存儲數據的數據庫 |
備注:為了演示簡單,這里將實例都部署在了一台機器上並用不同端口做區分,同學們也可以用三台機器來做環境搭建
在MySQL A和MySQL B中創建庫表testdb.users來方便后續的驗證,表結構如下:
-
CREATE TABLE `users` (
-
`id` int(11) NOT NULL,
-
`user` varchar(20) DEFAULT NULL,
-
PRIMARY KEY (`id`)
-
) ENGINE=InnoDB DEFAULT CHARSET=latin1
server.xml
server.xml里可以配置跟DBLE自身相關的許多參數,這里重點只關注下面這段訪問用戶相關的配置,其他默認即可;
第一段 "< system >" 為DBLE的服務端口(默認8066)和管理端口(默認9066)的配置
- 管理端口只能接受DBLE的管理命令,這里不做展開
- 服務端口即DBLE的業務訪問端口,可以接受SQL語句
第二段“< user >”配置管理理用戶,默認為man1,密碼為654321
- 即可以通過 mysql -P9066 -h 127.0.0.1 -u man1 -p654321來下發管理命令
第三段“< user >”配置業務用戶,配置了一個賬號test 密碼password,針對數據庫testdb,讀寫權限都有,沒有針對表做任何特殊的權限,故把表配置做了注釋
- 即可以通過 mysql -P8066 -h 127.0.0.1 -utest -ppassword下發SQL語句
-
...
-
-
<system>
-
...
-
<!-- property name="serverPort">8066</property> -->
-
<!--<property name="managerPort">9066</property> -->
-
...
-
</system>
-
<user name="man1">
-
<property name="password">654321</property>
-
<property name="manager">true</property>
-
<!-- manager user can't set schema-->
-
</user>
-
-
<user name="test">
-
<property name="password">password</property>
-
<property name="schemas">testdb</property>
-
-
<!-- table's DML privileges INSERT/UPDATE/SELECT/DELETE -->
-
<!--
-
<privileges check="false">
-
<schema name="TESTDB" dml="0110" >
-
<table name="tb01" dml="0000"></table>
-
<table name="tb02" dml="1111"></table>
-
</schema>
-
</privileges>
-
-->
-
</user>
-
...
參數 | 說明 |
---|---|
user | 用戶配置節點 |
name | 登錄的用戶名,也就是連接DBLE的用戶名 |
password | 登錄的密碼,也就是連接DBLE的密碼 |
schemas | 數據庫名,這里會和schema.xml中的配置關聯,多個用逗號分開,例如需要這個用戶需要管理兩個數據庫db1,db2,則配置db1,db2 |
privileges | 配置用戶針對表的增刪改查的權限,具體見官方文檔,這里不做展開 |
schema.xml
schema.xml是最主要的配置項,我們將users用戶表按照取模的方式平均拆分到了MySQL A和MySQL B兩個數據數據庫實例上,
詳細請看配置文件:
-
-
-
<dble:schema xmlns:dble="http://dble.cloud/">
-
-
<schema name="testdb">
-
<table name="users" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-mod2" />
-
</schema>
-
-
<!-- 分片配置 -->
-
<dataNode name="dn1" dataHost="Group1" database="testdb"/>
-
<dataNode name="dn2" dataHost="Group2" database="testdb"/>
-
-
<!-- 物理數據庫配置 -->
-
<dataHost name="Group1" maxCon="1000" minCon="10" balance="0" switchType="1" slaveThreshold="100">
-
<heartbeat>show slave status</heartbeat>
-
<writeHost host="MySQLA" url="172.16.3.1:14014" user="test" password="password"/>
-
</dataHost>
-
-
<dataHost name="Group2" maxCon="1000" minCon="10" balance="0" switchType="1" slaveThreshold="100">
-
<heartbeat>show slave status</heartbeat>
-
<writeHost host="MySQLA" url="172.16.3.1:14015" user="test" password="password"/>
-
</dataHost>
-
</dble:schema>
參數說明
- schema 邏輯數據庫信息,此數據庫為邏輯數據庫,name 與 server.xml 中 schema對應;
- dataNode 分片信息,此為分片節點的定義;分片名字和schema的dataNode對應;分片與下面的dataHost 物理實例進行關聯;
- dataHost 物理實例組信息,dataHost下可以掛載同組的讀寫物理實例節點,實現高可用或者讀寫分離;
每個節點的屬性逐一說明:
- schema:
屬性說明 :
-
- name 邏輯數據庫名,與 server.xml 中的 schema 對應;
-
- table:
子屬性說明 :
-
- name 表名,物理數據庫中表名
-
- dataNode 表存儲到哪些節點,多個節點用逗號分隔
-
- primaryKey 主鍵,用於主鍵緩存和自增識別,不作主鍵約束
-
- autoIncrement 是否自增
-
- rule 分片規則名,具體規則下文 rule 詳細介紹
-
dataNode
屬性說明:- name 節點名,與 table 中 dataNode 對應
- datahost 物理實例組名,與 datahost 中 name 對應
- database 物理數據庫中數據庫名;
- dataHost
屬性說明:
- name 物理數據庫名,與 dataNode 中 dataHost 對應
- balance 均衡負載的方式
- switchtype 寫節點的高可用切換方式;等於1時,心跳不健康發生切換
- heartbeat 心跳檢測語句,注意語句結尾的分號要加
-
writehost 寫物理實例
-
子屬性說明 :
-
- host 物理實例名
-
- url 物理庫IP+Port
-
- user 物理庫用戶
-
- password 物理庫密碼
-
rule.xml
主要關注rule屬性,rule屬性的內容來源於rule.xml這個文件,DBLE支持多種分表分庫的規則,基本能滿足你所需要的要求
table中的rule屬性對應的就是rule.xml文件中tableRule的name,具體有哪些拆分算法實現,建議還是看下文檔。我這里選擇的sharding-by-mod2,是hash算法的特例,就是將數據平均拆分。因為我后端是兩台物理庫,所以rule.xml中hashmod2對應的partitionCountt為2,配置如下:
-
<tableRule name="sharding-by-mod2">
-
<rule>
-
<columns>id</columns>
-
<algorithm>hashmod2</algorithm>
-
</rule>
-
</tableRule>
-
<function name="hashmod2" class="Hash">
-
<property name="partitionCount">2</property>
-
<property name="partitionLength">1</property>
-
</function>
驗證配置生效
啟動DBLE
-
-
./bin/dble start
-
-
-
STATUS | wrapper | 2019/01/21 17:31:43 | --> Wrapper Started as Daemon
-
STATUS | wrapper | 2019/01/21 17:31:43 | Launching a JVM...
-
INFO | jvm 1 | 2019/01/21 17:31:43 | OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
-
INFO | jvm 1 | 2019/01/21 17:31:44 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
-
INFO | jvm 1 | 2019/01/21 17:31:44 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
-
INFO | jvm 1 | 2019/01/21 17:31:44 |
-
INFO | jvm 1 | 2019/01/21 17:31:45 | Server startup successfully. see logs in logs/dble.log
通過DBLE流量入口8066登陸數據庫
mysql -P8066 -h 127.0.0.1 -utest -ppassword
插入兩條用戶記錄,並獲取DBLE側的查詢記錄
-
mysql> insert into users(id,user) values(1,"zhangsan");
-
Query OK, 1 row affected (0.09 sec)
-
mysql> insert into users(id,user) values(2,"lisi");
-
Query OK, 1 row affected (0.09 sec)
-
-
-
mysql> explain select * from users;
-
+-----------+----------+---------------------+
-
| DATA_NODE | TYPE | SQL/REF |
-
+-----------+----------+---------------------+
-
| dn1 | BASE SQL | select * from users |
-
| dn2 | BASE SQL | select * from users |
-
+-----------+----------+---------------------+
-
2 rows in set (0.00 sec)
-
-
mysql> select * from users;
-
+----+----------+
-
| id | user |
-
+----+----------+
-
| 2 | lisi |
-
| 1 | zhangsan |
-
+----+----------+
-
2 rows in set (0.01 sec)
獲取MySQLA和MySQLB的記錄
-
# mysql -P14014 -h 127.0.0.1 -utest -ppassword
-
mysql> select * from users;
-
+----+----------+
-
| id | user |
-
+----+----------+
-
| 2 | lisi |
-
+----+----------+
-
1 rows in set (0.01 sec)
-
-
# mysql -P14015 -h 127.0.0.1 -utest -ppassword
-
mysql> select * from users;
-
+----+----------+
-
| id | user |
-
+----+----------+
-
| 1 | zhangsan |
-
+----+----------+
-
1 rows in set (0.01 sec)
從上面的驗證流程,往DBLE插入的數據,會按照取模的方式下發到真實的物理庫,來實現數據庫的自動分片;同時通過DBLE下發的查詢會被DBLE自動下發給實際的物理庫,合並返回給客戶端,可以通過explain執行計划觀察到下發的實際下發給物理庫的SQL語句
應用場景二:讀寫分離
DBLE除了做數據的分片功能外,也支持讀寫分離功能;開啟讀寫分離功能后,可以將主實例上的讀壓力負載給原本stand by的從實例,從而擴展整個集群的吞吐能力;
后端MySQL節點
我們再通過示例,演示DBLE的讀寫分離的功能。物理部署結構如下表:
服務 | IP:Port | 說明 |
---|---|---|
DBLE | 172.16.3.1:9066 | DBLE實例,連接數據庫時,連接此IP:Port |
Mysql A | 172.16.3.1:14014 | 物理數據庫實例A,master實例 |
Mysql B | 172.16.3.1:14015 | 物理數據庫實例B,slave實例 |
備注:為了演示簡單,這里將實例都部署在了一台機器上並用不同端口做區分,同學們也可以用三台機器來做環境搭建
此場景中,我們將MySQL A和MySQL B搭建成主從復制關系,同時我們只變更schema.xml的配置來完成讀寫分離的架構;
schema.xml
-
-
-
<dble:schema xmlns:dble="http://dble.cloud/">
-
-
<schema name="testdb">
-
</schema>
-
-
<!-- 分片配置 -->
-
<dataNode name="dn1" dataHost="Group1" database="testdb"/>
-
-
<!-- 物理數據庫配置 -->
-
<dataHost name="Group1" maxCon="1000" minCon="10" balance="3" switchType="1" slaveThreshold="100">
-
<heartbeat>show slave status</heartbeat>
-
<writeHost host="MySQLA" url="172.16.3.1:14014" user="test" password="password">
-
<readHost host="MySQLB" url="172.16.3.1:14015" user="test" password="password"/>
-
</writeHost>
-
</dataHost>
-
</dble:schema>
DBLE通過balance參數來控制讀寫分離的負載策略,寫節點是否參與均衡與datahost的balance屬性有關,本案例中我們將值調整為balance="3",並定義了writeHost和readHost
balance的定義具體見下圖
驗證配置生效
通過DBLE管理入口9066登陸數據庫,注意這里我們通過管理入口的show @@datasource來驗證讀寫分離的狀態的正確性
- session1
-
##session1 登陸DBLE的管理端,查看讀寫分離的節點狀態
-
mysql -P9066 -h 127.0.0.1 -uman1 -p654321
-
mysql> show @@datasource;
-
+--------+------------+-------+------+--------+------+------+---------+-----------+------------+
-
| NAME | HOST | PORT | W/R | ACTIVE | IDLE | SIZE | EXECUTE | READ_LOAD | WRITE_LOAD |
-
+--------+------------+-------+------+--------+------+------+---------+-----------+------------+
-
| MySQLA | 172.16.3.1 | 19388 | W | 11 | 11 | 1000 | 11 | 0 | 0 |
-
| MySQLB | 172.16.3.1 | 19389 | R | 1 | 4 | 1000 | 3 | 0 | 0 |
-
+--------+------------+-------+------+--------+------+------+---------+-----------+------------+
-
2 rows in set (0.00 sec)
- session2
-
## session2 下發selct語句5次,查看READ_LOAD字段計數器的變化
-
mysql -P8066 -h 127.0.0.1 -utest -ppassword
-
mysql> select * from users;
- session1
-
##session1 返回DBLE的管理端,查看讀寫分離的節點狀態
-
mysql> show @@datasource;
-
+--------+------------+-------+------+--------+------+------+---------+-----------+------------+
-
| NAME | HOST | PORT | W/R | ACTIVE | IDLE | SIZE | EXECUTE | READ_LOAD | WRITE_LOAD |
-
+--------+------------+-------+------+--------+------+------+---------+-----------+------------+
-
| MySQLA | 172.16.3.1 | 19388 | W | 11 | 11 | 1000 | 11 | 0 | 0 |
-
| MySQLB | 172.16.3.1 | 19389 | R | 1 | 4 | 1000 | 8 | 5 | 0 |
-
+--------+------------+-------+------+--------+------+------+---------+-----------+------------+
-
2 rows in set (0.00 sec)
從show @@datasource;這個管理命令上我們能夠觀測到READ_LOAD在slave節點上計數器增加了5次,也就是說讀流量順利的下發到了slave節點;當然大家也可以通過打開mysql的general log來觀測讀寫分離的情況
總結
本文通過兩個場景來講解DBLE的快速入門,希望通過簡單的示例來給大家梳理DBLE的基本概念,幫助大家快速熟悉和使用DBLE這個中間件;更高階的使用方法和細節建議大家參考官方文檔;