大家好,我是七淅(xī)。
如题目所说,本文会联合我本人的亲身经历,介绍 3 局部内容:
- 线上单库单表变更到多库多表的各个实现计划
- 计划优劣比照
- 对于历史存在的单表,并且它们 不须要 变成多表,须要怎么解决
先下个论断,没有百分百完满的计划,技术计划永远要联合产品业务来设计。
以下举例的计划也只是较为通用的做法,具体细节是能够依据业务场景进行变动调整的。
只有可能满足业务需要,就是好计划,不要为了秀技术而疏忽业务。
看完这篇文章,如果前面有人问你,对于变更到多库多表的计划问题,那你能够和他谈笑自若了。
好了,上面我说下我这边的业务背景,和大家解释分明为什么须要多库多表。前面会引申出计划的,莫急。
1. 业务背景
有一个 在线上运行着 的数据库,假如是 user 库,库中 只有 1 张单表。
当初有个新需要,该需要的性能有肯定的申请量和数据量。
其中数据量初期是百万级,思考到业务减少,增长到千万、上亿都是有可能的。所以从数据量上看,单库单表不适合。
Q1:如果只是数据量问题,那用单库多表行不行?
A1:行。
Q2:那为什么还用多库多表呢?
A2:因为一个数据库的连贯数量是无限的,怕翻车。
下面有介绍业务有肯定的申请量,放心一个库来解决的话,万一哪天网络不好 / 慢查 / 该表业务有突发性流动等状况呈现。
一不小心就把连接数占满了,那就间接翻车了。
加上我司对多库多表的基建比拟成熟,所以我这边就间接上多库多表了。
Q3:既然如此,后期先上单库多表,等量上来后再多库多表行不行?
A3:能够。然而到时再来一次太累了。
比方再来一次会经验以下事件:
- 每天须要看看数据监控
- 有没有到瓶颈
- 到时再次变更时,开发运维测试业务的排期和执行
- 业务变动:说好的下个季度大推,后果提前到下一个月进行,此时数据库能不能扛住,扛不住革新工夫是否短缺?
所以,咱们要不还是一步到位吧。
滴,七淅揭示你:看到这,如果有人问你单库多表和多库多表的应用场景,你应该晓得怎么施展了吧
2. 历史数据处理
我先说下对历史数据处理,篇幅较少。
这里的内容对应文章结尾的第三点:对于历史存在的单表,并且它们 不须要 变成多表,须要怎么解决
这里能够有两种解决形式。
咱们晓得,历史数据在 user 库,假如业务须要减少到 8 个库,并且新表须要在这 8 个库中
2.1 形式一
新增 user_0、user_1、...、user_7
共 8 个库,应用 rename
命令,将 user 库的表迁徙到 user_0
库中,最初将 user 库删掉即可。
rename 命令其实就是重新命名,实现剪切数据的成果,而不是复制。当然要用复制的形式迁徙数据也是能够的,但咱们这边没用。
reanme 命令应用如下:
rename table user.table_name to user_0.table_name;
2.2 形式二
新增 user_0、user_1、...、user_7
共 8 个库,user 库数据不动,持续应用。
至于选哪种形式,大多状况下,我集体认为都能够,但如果历史表自身申请就很高,那能够思考用形式二,防止 0 号库压力太大。
我这边是抉择的形式一。当用户要拜访历史表时,指定路由到 0 号库就好了,顺便省下一台数据库的钱,真香
3. 变更计划
计划这块内容,我会基于形式一的历史数据处理形式来讲。
首先,先不思考任何计划,我把最简略的,变更到多库多表的操作按程序列举一下:
- 批改服务连贯数据库的配置,业务代码编写
- 减少 user 0-7 号数据库
- 将 user 库旧表数据迁徙到新增 user_0 库
- 部署服务
然而如果依照上述做法,在第 3、4 步执行期间,如果用户拜访原 user 库的数据会有问题。
具体来说:user 库的旧数据此时曾经通过 rename,迁徙到了 user_0 库,但因为部署还没部署实现,连贯数据库的配置没有更新。
所以申请依旧会跑去 user 库查问,导致查不到数据,后续业务逻辑没法程序继续执行。
用户也会纳闷:「这个中央之前进来都有数据的呀,怎么当初全空了?」
所以,须要确定正当的降级计划,最大水平缩小对业务和用户的影响,
3.1 计划一
这是最简略的形式。
看监控,筛选没有流量的时候,进行 db 变更和服务部署。
当然,监控也只是过来的状况,保不准性能上线那天就始终有流量没停歇过呢。
所以再求稳一点的话,能够发个布告,告知用户 xx 性能会在 xxx 时间段进行保护,期间不可拜访。
如果有玩农药(王者光荣)的敌人应该很相熟吧,每次版本更新都须要停服,就是这样的成果哈。
最初在实现之后,进行回归测试和新功能测试,看看性能是否失常。
如果失常那就能够去睡觉了,有问题就持续改 bug 解决;
如果评估没法在布告所说的截止工夫解决,那就只能进行回滚,改日再(jia)战(ban)。
PS:如果须要对历史数据进行分库分表的话,最好进行数据量的比照测验。因为我这边不波及对历史数据进行分库分表,所以这步就省了。
3.2 计划二
这个计划会简单很多,开发量也会很大。
我这边就只说关键步骤,具体细节就没法一一写了。因为要写的话又多出几千字的内容,篇幅太长,我预计也没多少人有急躁看完。
那话说回来,这个计划最大的益处就是业务性能不必停用,所以也就不必熬大夜了。
那要怎么做呢?
3.2.1 历史单表数据处理
1、先把 user 库现有的数据复制一份到 user_0 库。
2、因为 user 库的数据是会被批改和新增的。所以当复制实现后,数据仍旧存在变动,所以须要新增双写逻辑,保障 user_0 库的数据也能同步到变更。
3、对于数据的读写,都反对由开关管制,别离能够控制数据读写是申请到哪个数据库。
4、服务更新实现后,进行两个库的数据一致性比照。都没问题后,开关管制读写数据都申请到 user_0 库
3.2.2 新性能的多表数据处理
因为是新性能,其实不必怎么非凡解决。
为什么这么说呢?
因为咱们部署服务的程序必定是操作数据库的底层服务先公布,公布实现后,才对用到底层服务的应用服务进行公布。
所以作为业务性能入口的应用服务都还没公布,此时是不会有新性能数据达到底层服务的。
要是不能保障这个程序,你想下性能入口凋谢了,用户申请进来后,底层服务发现找不到这个表,是不是就间接报错了?
所以才会有下面说的公布程序,只有保障公布程序没错,那这块新性能的数据是不须要非凡解决。
3.3 计划优劣比照
其实 2 个计划就是互补的,一个计划的长处就是解决了另一个计划的毛病。
七淅用表格总结一下:
长处 | 毛病 | |
---|---|---|
计划一 | 操作简略,无需编写简单代码来保障有流量时,业务的失常执行 | 累人,熬大夜太酸爽了;会停用局部业务,影响用户体验 |
计划二 | 业务不用停用,不影响用户 | 开发成本大 |
最初,你问我当初是选哪个计划?
那必定是计划一啊,大不了熬一夜嘛。
不然那么麻烦的计划,排期又那么缓和,开发是不可能开发的,这辈子都不可能的。真有什么问题,大不了就人工染指解决,yyds
文章首发公众号:七淅在学 Java,继续原创输入 Java 后端干货。
如果对你有帮忙的话,能够给个赞再走吗