对于大型互联网应用来说,面对持续增长的海量业务数据,分布式数据库架构几乎是标准配置。而如何让业务开发人员在面向分布式数据库开发时如同在同一个库中,让数据分片对应用开发人员透明,将副作用降到最低,是众多优秀程序员持续追求的目标。
本文将通过一个简单实例,介绍如何使用 ShardingSphere 分片中间件,实现 Enhancer 应用对后台分布式数据库的操作。希望对您使用 Enhancer 应用管理大型分布式业务数据有所启发。
目标效果
实现步骤
1. 准备 4 台 mysql 服务器并创建相关的实验数据库和表
- 1.1. 创建四个数据库分别命名为 user_db_0, user_db_1, user_db_2, user_db_3
- 1.2. 在每个库中创建用户表
CREATE TABLE `t_user` (
`id` int(11) NOT NULL DEFAULT '0',
`name` varchar(40) DEFAULT NULL,
`gender` char(1) DEFAULT NULL,
`phone` varchar(20) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. 下载并安装 ShardingSphere
- 2.1.下载。实际上需要使用的是 ShardingSphere 的跨语言中间件产品 ShardingProxy : 下载地址
- 2.2. 解压 tar 包,得到 apache-shardingsphere-xxx-shardingsphere-proxy-bin 目录。
- 2.3. 下载 mysql 连接器 jar 包: mysql-connector-java-5.1.47.jar,并将该 jar 包放入 apache-shardingsphere-xxx-shardingsphere-proxy-bin/lib 目录中。
3. 配置代理服务器和数据库分片规则
- 3.1 配置代理服务器 apache-shardingsphere-xxx-shardingsphere-proxy-bin/conf/server.yaml 文件,
此文件描述了将来用作 Enhancer 工作台配置数据库连接的相关信息。注意配置文件中
[xxxx]
(含中括号)为需要自行修改部分:
authentication:
users:
root:
password: [xxx]
[db_account_xxx]:
password: [xxx]
authorizedSchemas: user_db
props:
max-connections-size-per-query: 1
acceptor-size: 16 # The default value is available processors count * 2.
executor-size: 16 # Infinite by default.
proxy-frontend-flush-threshold: 128 # The default value is 128.
# LOCAL: Proxy will run with LOCAL transaction.
# XA: Proxy will run with XA transaction.
# BASE: Proxy will run with B.A.S.E transaction.
proxy-transaction-type: LOCAL
proxy-opentracing-enabled: false
proxy-hint-enabled: false
query-with-cipher-column: true
sql-show: false
check-table-metadata-enabled: false
- 3.2 配置分片规则 apache-shardingsphere-xxx-shardingsphere-proxy-bin/conf/config-sharding.yaml 文件,此文件配置了分片数据库源信息和
t_user 表在分布式数据库中的分片规则信息。注意配置文件中
[xxxx]
(含中括号)为需要自行修改部分:
schemaName: user_db
dataSourceCommon:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
maintenanceIntervalMilliseconds: 30000
dataSources:
ds_0:
url: jdbc:mysql://[数据库IP地址0]:3306/user_db_0?serverTimezone=UTC&useSSL=false&characterEncoding=utf8
username: [xxx]
password: [xxx]
ds_1:
url: jdbc:mysql://[数据库IP地址1]:3306/user_db_1?serverTimezone=UTC&useSSL=false&characterEncoding=utf8
username: [xxx]
password: [xxx]
ds_2:
url: jdbc:mysql://[数据库IP地址2]:3306/user_db_2?serverTimezone=UTC&useSSL=false&characterEncoding=utf8
username: [xxx]
password: [xxx]
ds_3:
url: jdbc:mysql://[数据库IP地址3]:3306/user_db_3?serverTimezone=UTC&useSSL=false&characterEncoding=utf8
username: [xxx]
password: [xxx]
rules:
- !SHARDING
tables:
t_user:
actualDataNodes: ds_${0..3}.t_user # 配置表的实际数据节点数 0 ... n。
keyGenerateStrategy:
column: id
keyGeneratorName: snowflake
bindingTables:
- t_user
defaultDatabaseStrategy:
standard:
shardingColumn: id
shardingAlgorithmName: database_inline
defaultTableStrategy:
none:
shardingAlgorithms:
database_inline:
type: INLINE
props:
algorithm-expression: ds_${id % 4} # 使用简单的用 t_user 表的 id 字段对数据库节点数 n 求余规则来分片。
allow-range-query-with-inline-sharding: true
keyGenerators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 123
- 3.3 在 apache-shardingsphere-xxx-shardingsphere-proxy-bin 目录执行 ./bin/start.bat 或者 ./bin/start.sh 启动服务。
4. Enhancer 工作台配置连接 ShardingProxy,后续开发如常
-
4.1. 在工作台-全局配置-数据库-连接中配置 3.1 所配置的数据库服务连接[用户 db_account_xxx]和[密码 password],地址为 apache-shardingsphere-xxx-shardingsphere-proxy-bin 所在的机器地址,若在本机则填写为 127.0.0.1,端口号为
3307
, 库名为 user_db。 -
4.2. 在工作台-页面管理中创建一个页面,添加一个窗口组件 enhancer-jqgrid, 配置绑定 SQL:
SELECT * FROM t_user
至此,保存后可以运行起来查看效果,后续相关开发如常。
结语
本例仅仅是实现了对单一表的分片增、删、改、查操作。在分布式数据库实战业务开发中,对于一些复杂场景,尤其是在金融级数据强完整性、强一致性、强可用性的要求下,分片中间件并不能做到完全对应用开发层透明,比如多个大表跨数据库 join, 分布式事务等等。此时一般需要通过应用层合理设计,来补偿或者规避这些问题(比如支付宝不允许你跨年查账,也不会提供一个界面同时呈现总账和明细账,需要用户分多次多层点开逐步呈现)。对于已经采用 IOE 结构实现的大规模金融级应用来说,在不改动应用层的情况下就实现去 IOE,还有很长的路要走。而对于一般电商、社交级互联网应用使用 Enhancer + ShardingSphere 来实现对分布式数据库的管理,会是一个不错的选择。
参考
这个是java版本的内容把
@i5ting 不是,分片中间件ShardingSphere 是跨语言使用的,而 Enhancer 应用开发是纯 nodejs 实现的:https://wuyuan.io 只不过大部分情况下,开发者只需要写 SQL 就直出系统了。但系统本身是基于 nodejs 的。
学起来~
顶善繁
但是ShardingSphere-Proxy在性能上面损耗略高,这块怎么取舍?