1. 程式人生 > 實用技巧 >Sharding-Proxy的基本功能使用

Sharding-Proxy的基本功能使用

Sharding-Proxy是一個分散式資料庫中介軟體,定位為透明化的資料庫代理端。作為開發人員可以完全把它當成資料庫,而它具體的分片規則在Sharding-Proxy中配置。它的整體架構圖如下:

在架構圖中,中間的藍色方塊就是我們的中介軟體Sharding-Proxy,下面連線的是資料庫,我們可以配置每一個資料庫的分片,還可以配置資料庫的讀寫分離,影子庫等等。上方則是我們的業務程式碼,他們統一連線Sharding-Proxy,就像直接連線資料庫一樣,而具體的資料插入哪一個資料庫,則由Sharding-Proxy中的分片規則決定。再看看右側,右側是一些資料庫的工具,比如:MySQL CLI,這是MySQL的命令列;Workbench是MySQL自己出的一個管理工具;還可以連線其他的工具,比如:Navicat,SQLYog等。最後再來看看左側,是一個註冊中心,目前支援最好的是Zookeeper,在註冊中心中,我們可以統一配置分片規則,讀寫資料來源等,而且是實時生效的,在管理多個Sharding-Proxy時,非常的方便。而官方也給我們提供了介面化的工具——ShardingSphere-UI,使用起來非常的方便。

Sharding-Proxy的安裝

我們可以在Sharding-Proxy官網上找的下載目錄,再找到Sharding-Proxy的下載連結,下載最新版本的二進位制包。然後把二進位制包(tar.gz)上傳到伺服器的目錄中,這個目錄可以自定義,/opt或者/usr/local都可以,然後解壓,命令如下:

tar -zxvf apache-shardingsphere-4.1.1-sharding-proxy-bin.tar.gz

解壓後,進入到sharding-proxy的conf目錄,這個目錄sharding-proxy的配置目錄,我們所有的資料來源、分片規則、讀寫分離等都在此目錄下配置。

[[email protected]
conf]# ll
總用量 28
-rw-r--r--. 1 root root 3019 6月 4 15:24 config-encrypt.yaml
-rw-r--r--. 1 root root 3633 7月 7 13:51 config-master_slave.yaml
-rw-r--r--. 1 root root 2938 6月 4 15:24 config-shadow.yaml
-rw-r--r--. 1 root root 5463 7月 7 14:08 config-sharding.yaml
-rw-r--r--. 1 root root 1322 6月 4 15:24 logback.xml
-rw-r--r--. 1 root root 2171 7月 7 15:19 server.yaml
  • logback.xml是日誌的配置。
  • server.yaml是Sharding-Proxy的一些基礎配置,比如:賬號、密碼、註冊中心等。
  • 剩下的所有以config開頭的yaml檔案,都是一個邏輯資料來源,我們可以看到最常見的兩個config-sharding.yaml(分片的配置),config-master_slave.yaml(讀寫分離的配置)。注意,如果我們要配置分片+讀寫分離,要不要在兩個配置檔案中配置呢?不需要的,我們只需要在config-sharding.yaml中配置就可以了,如果要配置單獨的讀寫分離,則需要按照config-master_slave.yaml配置。單獨的讀寫分離和分片+讀寫分離在配置上,還是有一些區別的。

這些配置我們在後面會展開講。Sharding-Proxy預設支援的資料庫是PostgreSQL,而我們大多數都是使用的MySQL,在這裡我們的資料庫使用的是MySQL,我們要將mysql-connector-java.jar這個jar包放入lib目錄,這裡推薦使用5.x版本的jar包,如果使用8.x可能會有一些位置的錯誤。

最後,我們執行bin目錄下的start.sh就可以運行了。

 ./bin/start.sh

Sharding-Proxy預設的啟動埠是3307,我們在連線的時候要格外注意一下。

server.yaml配置

下面我們看看server.yaml檔案中,都具體配置哪些內容,我們用vim開啟檔案,

vim server.yaml

檔案的內容如下:

#########################################################################################
#
# If you want to configure orchestration, authorization and proxy properties, please refer to this file.
#
#########################################################################################
#
#orchestration:
# orchestration_ds:
# orchestrationType: registry_center,config_center
# instanceType: zookeeper
# serverLists: 192.168.73.131:2181
# namespace: sharding-proxy
# props:
# overwrite: false
# retryIntervalMilliseconds: 500
# timeToLiveSeconds: 60
# maxRetries: 3
# operationTimeoutMilliseconds: 500 authentication:
users:
root:
password: root
sharding:
password: sharding
authorizedSchemas: sharding_db
  • 其中,orchestration是連線zookeeper註冊中心,這裡我們暫時用不到,將其註釋掉。
  • authentication中,配置的是使用者名稱和密碼,以及授權的資料庫,在這裡,我們配置了兩個使用者,分別為:root/root和sharding/sharding,其中root預設授權所有的資料庫,而sharding使用者則授權sharding_db資料庫。在這裡的資料庫(schema)是邏輯資料庫,在config-*.yaml中配置的。

config-sharding.yaml的配置

這個檔案是Sharding-Proxy的核心的配置,所有的分片規則都在這個檔案中配置,讓我們一起來看看吧,

schemaName: sharding_db

dataSources:
ds_1:
url: jdbc:mysql://192.168.73.132:3306/shard_order?serverTimezone=Asia/Shanghai&useSSL=false
username: imooc
password: [email protected]
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
master_ds:
url: jdbc:mysql://192.168.73.131:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
username: imooc
password: [email protected]
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds_0:
url: jdbc:mysql://192.168.73.130:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
username: imooc
password: [email protected]
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
  • 在這個配置檔案中,總共分為3個部分,我們先看看前面2個部分。
  • schemaName:是邏輯資料庫的名稱,這裡我們叫做sharding_db。在server.yaml檔案中,授權的schema就是這裡的schemaName。
  • 第二部分是資料來源,在dataSources裡邊,我們配置了3個資料來源。分別是ds_1、master_ds和slave_ds_0。我們先來說一下資料庫的規劃吧,我們的資料將通過user_id進行資料庫的分片,總共有2個分片,user_id尾數為奇數的將分配到ds_1的資料庫中,user_id尾數為偶數的,將分配到ds_0中,但是我們的資料來源中沒有ds_0呀,ds_0將由master_ds和slave_ds_0組成一個讀寫分離資料來源。

接下來再看看具體分片的配置,

shardingRule:
masterSlaveRules:
ds_0:
masterDataSourceName: master_ds
slaveDataSourceNames:
- slave_ds_0
tables:
t_order:
actualDataNodes: ds_${0..1}.t_order_${1..2}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_${order_id % 2 + 1}
keyGenerator:
type: SNOWFLAKE
column: order_id
t_order_item:
actualDataNodes: ds_${0..1}.t_order_item_${1..2}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_item_${order_id % 2 + 1}
keyGenerator:
type: SNOWFLAKE
column: id
defaultDatabaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: ds_${user_id % 2}
defaultTableStrategy:
none:
defaultDataSourceName: ds_0
  • 分片的配置都在shardingRule下。
  • 在這裡我們要配置讀寫分離主從資料來源,在這裡我們配置的是分片+讀寫分離,和單純的讀寫分離配置是不一樣的。讀寫分離的配置在masterSlaveRules下,我們配置讀寫分離資料來源ds_0,指定主庫的資料來源masterDataSourceName為master_ds,master_ds在上面的資料來源中已經配置,而從資料來源slaveDataSourceNames可以配置多個,也就是一主多從的配置,我們用陣列的方式進行配置,- slave_ds_0指定從資料來源為slave_ds_0,如果有多個從資料來源,可以配置多個。
  • 我們先跳過tables的配置,往下看,defaultDataSourceName,預設資料來源,我們指定ds_0。這個配置非常有用,在我們的專案中,並不是所有的表都要進行水平切分,只有資料量比較大的表才會用到水平切分,比如:訂單表(t_order)和訂單明細表(t_order_item)。而其他的表資料量沒有那麼大,單庫單表就可以完全支撐,這些表沒有分片規則,而我們指定了預設的資料來源,當我們操作這些沒有分片規則的表時,都統一使用預設的資料來源。
  • defaultTableStrategy,預設表的分片規則,這裡我們配置的是none,沒有。也就是說所有的分片表都要配置表的分片規則。
  • defaultDatabaseStrategy,預設資料庫的分片規則,這裡我們配置它的規則為行內表示式,分片欄位為user_id,規則為ds_${user_id % 2},當user_id為偶數時,資料來源為ds_0,也就是前面配置的讀寫分離資料來源;而當user_id為奇數時,資料來源為ds_1。如果我們的表的分片規則中,沒有配置資料來源的分片規則,將使用這個預設資料來源的分片策略。
  • 最後再來看看tables的配置,這裡配置的是分片表的規則,我們配置兩個表,t_order和t_order_item。每個分片表都由3部分組成。首先,actualDataNodes,實際的資料節點,這個節點是在MySQL中真是存在的,以t_order的配置為例,ds_${0..1}.t_order_${1..2},說明t_order的資料節點有4個,分表為ds_0.t_order_1、ds_0.t_order_2、ds_1.t_order_1和ds_1.t_order_2。再來看錶的分片規則,tableStrategy,它的規則也是用行內表示式配置的,分片欄位為order_id,規則為t_order_${order_id % 2 + 1},當order_id為奇數時,資料會分配到表t_order_1中;當order_id為偶數時,會分配到表t_order_2中。

整個的分片策略就配置完了,決定每條資料的具體分片由兩個欄位決定,user_id決定資料分配到哪一個資料來源中,order_id決定資料分配到哪一個表中。這就是分片+讀寫分離的配置,如果要進行更詳細的配置,可以參考官方檔案,這裡不贅述了。

config-master_slave.yaml的配置

如果我們只配置資料來源的讀寫分離,而不進行分片配置,就需要參照這個配置檔案進行配置了,雖然分片+讀寫分離的配置已經有了讀寫分離的配置,但是他倆之間還是有一些細微的區別的,我們來看看這個檔案中的內容吧,

schemaName: master_slave_db

dataSources:
master_ds:
url: jdbc:mysql://192.168.73.131:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
username: imooc
password: [email protected]
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds:
url: jdbc:mysql://192.168.73.130:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
username: imooc
password: [email protected]
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds_1:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_slave_1?serverTimezone=UTC&useSSL=false
username: root
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50 masterSlaveRule:
name: ds_0
masterDataSourceName: master_ds
slaveDataSourceNames:
- slave_ds
- slave_ds_1
  • 首先,我們還是定義邏輯資料庫的名稱,schemaName: master_slave_db,叫做master_slave_db。
  • 然後在dataSources中定義資料來源,這些配置的結構是通用,和前面沒有區別,我們配置了3個資料來源,一主兩從,master_ds(主)、slave_ds(從)和slave_ds_1(從)。
  • 最後就是主從的規則masterSlaveRule,在前面分片+讀寫分離的配置中,叫做masterSlaveRules,複數形式。說明在單獨的讀寫分離配置中,只能配置一個主從資料來源。主從資料來源的名字叫做ds_0,主資料來源masterDataSourceName是master_ds,從資料來源slaveDataSourceNames配置了兩個,slave_ds和slave_ds_1。

這裡只是單純的配置主從讀寫分離資料來源,如果要配置分片+讀寫分離,請參照前面的配置。

config-shadow.yaml影子庫配置

在現在微服務盛行的情況下,系統被切分的很細,這對於測試,尤其是壓測是非常難的,如果在測試環境部署一套和生產一摸一樣的環境,是非常浪費資源的。而如果只部署一兩個服務,又不能進行全鏈路的整體壓測。而我們的解決方案是在生產環境直接進行壓測,得出的結果也是真實有效的。那麼這些壓測的資料怎麼辦,如果不做特殊的處理,就和生產的真實資料混在一起了。

這裡我們就需要配置影子資料庫了,所有壓測資料都會有一個特殊的標識,sharding-proxy根據這個特殊的標識,將壓測的資料分配到影子庫中,和生產的真實資料隔離開,我們看看具體怎麼配置

schemaName: sharding_db

dataSources:
ds:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
shadow_ds:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50 shadowRule:
column: shadow
shadowMappings:
ds: shadow_ds
  • 前面還是邏輯資料庫的名稱和資料來源的配置。在資料來源我們配置了兩個,一個是真實的資料庫ds,另一個是影子庫shadow_ds,所有壓測的資料都會分配的影子庫中。
  • shadowRule中配置影子庫的規則,column,影子庫欄位標識,所有壓測資料,在程式中,將此欄位設定為true。shadowMappings是主庫和影子庫的對映關係,ds資料庫的影子庫是shadow_ds。

影子庫的配置在我們壓測中還是十分有用的,將測試資料和生產資料隔離開,不會影響到生產資料。

config-encrypt.yaml資料加密配置

最後我們再看看資料加密的配置,一些使用者的資訊是不希望在資料庫中以明文存在的,比如:使用者的身份證號、銀行卡號。但是,在使用的時候,我們還要把它解密回來。當然,我們可以在程式中,針對這些欄位進行加解密,這裡呢,我們看看Sharding-Proxy為我們提供的資料加密配置。我們看一下配置檔案,

schemaName: encrypt_db

dataSource:
url: jdbc:mysql://127.0.0.1:3306/demo_ds?serverTimezone=UTC&useSSL=false
username: root
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50 encryptRule:
encryptors:
encryptor_aes:
type: aes
props:
aes.key.value: 123456abc
tables:
t_card_no:
columns:
card_no:
cipherColumn: card_no_cipher
encryptor: encryptor_aes
  • 邏輯庫與資料來源的配置略過。
  • 在加密規則encryptRule中,我們先定義加密演演算法,encryptor_aes,它的型別是aes,key是123456abc,這個key我們可以修改,但是一旦用這個key產生資料,就不要再改了,如果改了,舊資料就不能正確的解密了。
  • 然後在tables中定義加密資料的表t_card_no,加密的列為card_no,這個列是邏輯列,在表中不是真實存在的,當你的sql中無論查詢、插入,出現這個欄位,都會進行加密處理。而cipherColumn是加密後儲存資料的列,encryptor則是加密的規則。例如,我們執行insert into t_card_no (card_no) values ('123456'),card_no列在表t_card_no中並不存在,t_card_no中存在的是card_no_cipher列,我們執行成功後,card_no_cipher列存的是密文資料;當我們執行select card_no from t_card_no 時,雖然表t_card_no沒有card_no 列,但是可以將card_no_cipher列解密,card_no 顯示解密後的值。

資料加密在實際的應用中還是比較多的。

總結

這一篇我們主要介紹了Sharding-Proxy的一些基本功能,下一篇將給大家shardingsphere-ui和註冊中心的應用。