Kingshard 是基於 Go 語言開發的 MySQL Proxy,支援讀寫分離、分庫分表、SQL 審計。本文以單機雙實例模擬分片環境,演示從 MySQL 多實例部署、Kingshard 編譯配置、分表規則定義到數據寫入驗證的全鏈路實戰。
mysqld_multi 啟動 3307/3308 兩個節點(node1/node2)test_shard_hash(Hash 分片)、test_shard_range(Range 分片)# 初始化數據目錄 mysql_install_db --datadir=/var/lib/mysql2 --user=mysql mysql_install_db --datadir=/var/lib/mysql3 --user=mysql # 生成並修改配置 mysqld_multi --example > mysqld_multi.conf # 編輯 [mysqld2] port=3307 datadir=/var/lib/mysql2 ... # 編輯 [mysqld3] port=3308 datadir=/var/lib/mysql3 ... # 啟動 mysqld_multi --defaults-extra-file=./mysqld_multi.conf start mysqld_multi --defaults-extra-file=./mysqld_multi.conf report
git clone https://github.com/flike/kingshard.git src/github.com/flike/kingshard cd src/github.com/flike/kingshard source ./dev.sh make # 產出 ./bin/kingshard
etc/multi.yaml 解析addr: 127.0.0.1:9696
user: kingshard
password: kingshard
log_level: debug
allow_ips: 127.0.0.1
nodes:
- name: node1
idle_conns: 16
rw_split: true
user: root
password: root
master: 127.0.0.1:3307
slave: []
down_after_noalive: 300
- name: node2
idle_conns: 16
rw_split: true
user: root
password: root
master: 127.0.0.1:3308
slave: []
down_after_noalive: 100
schemas:
- db: kingshard
nodes: [node1, node2]
rules:
default: node1
shard:
- table: test_shard_hash
key: id
nodes: [node1, node2]
type: hash
locations: [4,4] # 4張子表在node1,4張在node2
- table: test_shard_range
key: id
type: range
nodes: [node1, node2]
locations: [4,4]
table_row_limit: 10000
YAML 陷阱:嚴禁 Tab 縮進,冒號後必須有一空格,建議用 yamllint 校驗。
# /etc/hosts 映射 127.0.0.1 node1 127.0.0.1 node2 # 建用戶、建庫 mysqladmin -h127.0.0.1 -P3307 -uroot password 'root' mysqladmin -h127.0.0.1 -P3308 -uroot password 'root' mysql -h127.0.0.1 -P3307 -uroot -proot -e "CREATE DATABASE kingshard;" mysql -h127.0.0.1 -P3308 -uroot -proot -e "CREATE DATABASE kingshard;" # 啟動 Kingshard ./bin/kingshard -config=etc/multi.yaml
for i in {0..3}; do
mysql -h127.0.0.1 -P3307 -uroot -proot kingshard -e "
CREATE TABLE IF NOT EXISTS test_shard_hash_000$i (
id BIGINT UNSIGNED NOT NULL, str VARCHAR(256), f DOUBLE,
e ENUM('test1','test2'), u TINYINT UNSIGNED, i TINYINT, ni TINYINT,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
done
for i in {4..7}; do
mysql -h127.0.0.1 -P3308 -uroot -proot kingshard -e "... 同上 ..."
done
for i in {1..10}; do
mysql -h127.0.0.1 -P9696 -ukingshard -pkingshard -e "
INSERT INTO test_shard_hash (id,str,f,e,u,i) VALUES ($i,'abc$i',3.14,'test$i',255,-127);"
done
2015/07/29 07:39:15 - INFO - 127.0.0.1:40135->127.0.0.1:3307: INSERT INTO test_shard_hash_0001 ... 2015/07/29 07:39:15 - INFO - 127.0.0.1:40138->127.0.0.1:3308: INSERT INTO test_shard_hash_0004 ...
日志顯示 id=1,2,3,8,9,10 路由 node1(_0001/_0002/_0000),id=4,5,6,7 路由 node2(_0004~_0007),Hash 分片生效。
mysql -h127.0.0.1 -P9696 -ukingshard -pkingshard \ -e "SELECT * FROM test_shard_hash WHERE id IN (2,3,4,5);"
返回 4 行數據,跨分片聚合查詢正常。注意:不支援無 WHERE 條件的全表掃描,必須帶分片鍵條件。
locations 總數 = 子表總數,需與物理建表數量一致。table_row_limit 僅作預估,實際遷移需配合工具。