shardingsphere-proxy分库分表配置
Posted 境悟初
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shardingsphere-proxy分库分表配置相关的知识,希望对你有一定的参考价值。
shardingsphere-proxy
shardingsphere-proxy是一个代理,兼容mysql和postgresql协议,可以接入多种语言。
1.下载
- 下载ss-proxy安装包:https://shardingsphere.apache.org/document/current/en/downloads/
- 下载mysql-jdbc-driver-lib:https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar
2.安装zookeeper&mysql
proxy目前依赖ZK做调度,不过很快会有多种分布式框架可选,比如etcd,甚至自研。
3.配置proxy
使用mysql的话需要将mysql driver包放在lib下,postgresql不需要。
配置文件位于conf目录。
server.yaml
这个是必选。
governance:
name: governance_ds # ZK上的节点名称
registryCenter:
type: ZooKeeper
serverLists: localhost:2181
props:
retryIntervalMilliseconds: 500
timeToLiveSeconds: 60
maxRetries: 3
operationTimeoutMilliseconds: 500
overwrite: true # 如果设为false,每次重启后ZK上的配置还是之前的,不利于调试,生产环境设为false
scaling:
blockQueueSize: 10000
workerThread: 40
rules:
- !AUTHORITY
users:
- root@%:passw23ey8dg
# - sharding@:sharding # 密码太简单mysql会报错
provider:
type: NATIVE
props:
sql-show: true
若是governance.overwrite设为false
,当配置文件出了问题,得先删除ZK上的节点,否则会一直使用之前的配置
[zk: localhost:2181(CONNECTED) 11] deleteall /governance_ds
config-sharding.yaml
当然,这个名字以config-
开头,后面可以随便取。
ShardingSphere-Proxy 支持多逻辑数据源,每个以
config-
前缀命名的 YAML 配置文件,即为一个逻辑数据源
schemaName: order_db # 逻辑库名
dataSources:
ds_0:
url: jdbc:mysql://127.0.0.1:3306/order_db_0?serverTimezone=UTC&useSSL=false
username: root
password: passw23ey8dg!e
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
maintenanceIntervalMilliseconds: 30000
ds_1:
url: jdbc:mysql://127.0.0.1:3306/order_db_1?serverTimezone=UTC&useSSL=false
username: root
password: passw23ey8dg!e
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
maintenanceIntervalMilliseconds: 30000
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ds_${0..1}.t_order_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: t_order_inline
keyGenerateStrategy:
column: order_id
keyGeneratorName: snowflake
t_order_item:
actualDataNodes: ds_${0..1}.t_order_item_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: t_order_item_inline
keyGenerateStrategy:
column: order_item_id
keyGeneratorName: snowflake
bindingTables:
- t_order,t_order_item
defaultDatabaseStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: database_inline
defaultTableStrategy:
none:
shardingAlgorithms:
database_inline:
type: INLINE
props:
algorithm-expression: ds_${user_id % 2}
t_order_inline:
type: INLINE
props:
algorithm-expression: t_order_${order_id % 2}
t_order_item_inline:
type: INLINE
props:
algorithm-expression: t_order_item_${order_id % 2}
keyGenerators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 123
需要手动在mysql中创建这几个数据库:
CREATE SCHEMA IF NOT EXISTS order_db_0;
CREATE SCHEMA IF NOT EXISTS order_db_1;
4.启动ss-proxy
bin/start.sh
他的默认端口是3307,如果要修改端口,可以在启动时指定 bin/start.sh 3308
可以看到ZK和proxy的进程
# jps -l
5745 org.apache.zookeeper.ZooKeeperMain
14068 org.apache.shardingsphere.proxy.Bootstrap
7102 org.apache.zookeeper.server.quorum.QuorumPeerMain
这时候,是可以通过mysql客户端直接连接的:
mysql -p -P 3307
5.测试分片
数据源和规则建好后,就是建表测试。
建表语句:
CREATE TABLE IF NOT EXISTS t_user (user_id INT NOT NULL AUTO_INCREMENT, user_name VARCHAR(200), user_name_plain VARCHAR(200), pwd VARCHAR(200), assisted_query_pwd VARCHAR(200), PRIMARY KEY (user_id));
CREATE TABLE IF NOT EXISTS t_order_item (order_item_id BIGINT NOT NULL AUTO_INCREMENT, order_id BIGINT NOT NULL, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_item_id));
CREATE TABLE IF NOT EXISTS t_order (order_id BIGINT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id));
写一段简单的JDBC代码:连接的库为逻辑库,注意端口为 3307
,这是ss-proxy的默认端口,
try (Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3307/order_db", "root", "passw23ey8dg")) {
final Statement st1 = conn.createStatement();
String sql = "CREATE TABLE IF NOT EXISTS t_user (user_id INT NOT NULL AUTO_INCREMENT, user_name VARCHAR(200), user_name_plain VARCHAR(200), pwd VARCHAR(200), assisted_query_pwd VARCHAR(200), PRIMARY KEY (user_id));";
st1.executeUpdate(sql);
sql = "CREATE TABLE IF NOT EXISTS t_order_item (order_item_id BIGINT NOT NULL AUTO_INCREMENT, order_id BIGINT NOT NULL, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_item_id));";
st1.executeUpdate(sql);
sql = "CREATE TABLE IF NOT EXISTS t_order (order_id BIGINT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id))";
st1.executeUpdate(sql);
st1.executeUpdate("insert into t_user(user_id,user_name) values(1,'jimo'),(2,'hehe')");
st1.executeUpdate("insert into t_order values(1,1,'ok'),(2,1,'err'),(3,2,'ok')");
final Statement st2 = conn.createStatement();
final ResultSet rs = st2.executeQuery("select count(1) from t_order");
rs.next();
System.out.println(rs.getInt(1));
} catch (SQLException e) {
e.printStackTrace();
}
6.验证数据
mysql> use order_db_0;
Database changed
mysql> show tables;
+----------------------+
| Tables_in_order_db_0 |
+----------------------+
| t_order_0 |
| t_order_1 |
| t_order_item_0 |
| t_order_item_1 |
| t_user |
+----------------------+
5 rows in set (0.00 sec)
mysql> use order_db_1;
Database changed
mysql> show tables;
+----------------------+
| Tables_in_order_db_1 |
+----------------------+
| t_order_0 |
| t_order_1 |
| t_order_item_0 |
| t_order_item_1 |
+----------------------+
4 rows in set (0.00 sec)
mysql> select * from order_db_0.t_order_0;
Empty set (0.00 sec)
mysql> select * from order_db_0.t_order_1;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
| 3 | 2 | ok |
+----------+---------+--------+
1 row in set (0.00 sec)
mysql> select * from order_db_1.t_order_0;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
| 2 | 1 | err |
+----------+---------+--------+
1 row in set (0.00 sec)
mysql> select * from order_db_1.t_order_1;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
| 1 | 1 | ok |
+----------+---------+--------+
1 row in set (0.00 sec)
关于集群模式
每个proxy的实例是独立无状态的,通过JDBC URL上配置多个实例来做到分布式。
以上是关于shardingsphere-proxy分库分表配置的主要内容,如果未能解决你的问题,请参考以下文章
ShardingSphere-Proxy分库分表以及多租户安装使用