同步操作将从 timfruit/sharding-datasource-demo 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
选用命中率高的, 减轻主要查询压力
t_order表和t_order_item表, 保存一次订单,确保分库后order和order_item都放在同一个库中,
这样就可以使用本地事务了。一般选用user_id, 选用order_id也可以, 本demo使用user_id
注意事项,选用了user_id做分片键,则原先使用order_id查询的接口会遍历各个分库查询数据
a. 如果数据量不是特别大,可以不处理
b. 本demo将user_id和order_id映射关系保存到t_order_mapping表中,使用order_id查询时先查询一次user_id,然后带上user_id查询订单
c. 基因id 处理,参考美团订单分库分表实现,定制order_id,中间嵌入user_id后几位数字,分片查询时根据user_id基因数字路由,这种改造工程比较大
d. 多列分库分表,在将user_id做一次分库分表的同时,也将order_id做一次分库分表,存了两份数据,存储较大
range
按时间或id范围划分,如[1-10000]放到1库,[10001-20000]放到2库
优点:单表大小可控,天然水平扩展。
缺点:无法解决集中写入瓶颈的问题。
hash
hash取模 2^n
分2(库) * 4 (表), 即分2个库,每个库4张表
则 路由规则是 库号= user_id % 2, 表号= (user_id/2) % 4
优点: 易扩展,解决集中写入瓶颈的问题
缺点: 扩容麻烦,需要重新hash,(注意避免在同一张表的数据,重新hash到不同的表), 需要迁移数据
(本demo采用该方法)
生产中一次性分够,够用好几年,不用考虑扩容
分32(库) * 32 (表) , 分成32个库,每个库32张表, 共1024张表(也可以16*64)
路由规则是 库号= user_id % 32, 表号= (user_id/32) % 32
初始逻辑分库,实际上可以部署4台机器,每台机器8库, 每个库32表
当表数据超过单机限制后,可以部署8台机器,每台机器4各库,每个库32表 最多可以部署1024台机器,每台机器1张表
扩容时,仅仅是改一下配置,迁移数据就可以了, 原来在同一张表的数据,扩容之后,还在同一张表
更具体的介绍看美团实现
uuid 字符串
占用空间较多, 不能做到递增
雪花算法
可以做到递增,性能较好
维护workId比较麻烦
存在时钟回拨问题
其他的实现一般都是基于雪花算法进行改造
比较复杂,暂不考虑
比较简单,解决workId维护问题,解决了时钟回拨问题,暂未提供workId重用实现
本demo采用该实现,已实现复用workId
ecp-uid整合了美团leaf、百度UidGenerator、原生snowflake 实现,可以参考,
由于直接使用uid-generator足够简单,且有效使用,暂不采用ecp-uid
参考美团双写实现
① 原系统中将需要订单表的关联查询(join)去掉
改成在应用中用代码处理join, 为后续分库分表做准备
② 改造系统中订单id的实现,统一使用uid-generator生成的唯一id
③ 数据库双写(先写单库,后写分库,事务以单库为主,读数据以单库为主 ),同步订单历史数据到分库,然后校验补偿分库数据
a. 先写单库,后写分库,事务以单库为主,读数据以单库为主
b. 同时,使用datax同步历史订单数据到分库
c. 校验单库和分库数据,补偿数据到分库(插入或根据更新时间比较更新)
④ 在③步骤数据补平后,数据仍双写(先写分库,后写单库,事务以分库为主,读数据以分库为主),同时校验补偿单库数据
a. 先写分库,后写单库,事务以分库为主,读数据以分库为主
(如果服务众多,可以切一小部分服务灰度尝试读写, 如果有问题,可以回退到③)
b. 校验单库和分库数据,补偿数据到单库(插入或根据更新时间比较更新)
⑤ 观察几天没问题后,下线单库订单表
mycat
基于数据库代理实现,存在单点问题
目前成为apache顶级项目, 从前景上说,采用该技术应是最好的
sharding-jdbc
shardingsphere子项目, jdbc代理
a. 不存在单点问题
b. 可能会存在多份配置
c. 升级比较麻烦,需要统一升级
d. 只能应用于java语言
sharding-proxy
shardingsphere子项目, 数据库代理
a. 存在单点问题
b. 兼容性问题
c. 优点是没有语言限制
目前demo采用sharding-jdbc实现为主,sharding-proxy运维为辅
create database db_lab;
db_lab_table.sql 用于创建数据表
db_lab_data.sql 用于创建测试数据,里面有3万订单(t_order)数据,和9万订单项(t_order_item)数据
create database db_lab_orders_0;
create database db_lab_orders_1;
创建uid数据库
create database uid;
创建uid数据表
DROP TABLE IF EXISTS WORKER_NODE;
CREATE TABLE WORKER_NODE
(
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name',
PORT VARCHAR(64) NOT NULL COMMENT 'port',
TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'launch date',
MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time',
CREATED TIMESTAMP NOT NULL COMMENT 'created time',
PRIMARY KEY(ID)
)
COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB;
修改uid数据库配置用户名密码
使用shrding-proxy创建分库分表后的订单表
CREATE TABLE `t_order` (
`order_id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`address_id` bigint(20) NOT NULL,
`status` varchar(50) DEFAULT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
CREATE TABLE `t_order_item` (
`order_item_id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` bigint(20) DEFAULT NULL,
`user_id` int(11) NOT NULL,
`status` varchar(50) DEFAULT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`order_item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
注意以下配置,用于分库分表迁移的切换
# 1 使用uid的初始下单 2 下单双写,以单库读写为主 3 下单双写, 以分库读写为主 4 下单只写在分库
transfrom.step=2
可以打包放到idea外部部署运行,高配机器可以忽略
模拟用户访问订单服务
本项目使用datax+sharding-jdbc同步订单历史数据,查看使用方法
在single-datasource-lab项目运行时配置是'transfrom.step=2'时, 启动 validate-step2项目,用于校验补偿分库订单数据
修改single-datasource-lab配置'transfrom.step=3',并重启 观察是否有问题,如果有问题,则回退到step=2
因为step2启动时,会读取当前最大的订单id, 进行校验,重启是为了防止遗漏
这里主要是为了可回滚
真实项目需持续观察几天, 没有问题,则修改配置为'transfrom.step=4', 重启下线单库订单
有问题,则回退到step2, 注意,回退后,validate-step2也需重新运行校验
props:
sql:
show: true # 打印 SQL
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。