业务兼容
同时分表之后还需要兼容其他业务;比如原有的报表业务、分页查询等,现在来看看我们是如何处理的。
报表
首先是报表,没分表之前之间查询一张表就搞定了,现在不同,由一张表变为 N 张表。
所以原有的查询要改为遍历所有的分表,考虑到性能可以利用多线程并发查询分表数据然后汇总。
不过只依靠 Java
来对这么大量的数据做统计分析还是不现实,刚开始可以应付过去,后续还得用上大数据平台来处理。
查询
再一个是查询,原有的分页查询肯定是不能用了,毕竟对上亿的数据分页其实没什么意义。
只能提供通过分表字段的查询,比如是按照订单 ID 分表,那查询条件就得带上这个字段,不然就会涉及到遍历所有表。
这也是所有分表之后都会遇到的一个问题,除非不用 MySQL
这类关系型数据库。
分库
分表完成后可以解决单表的压力,但数据库本身的压力却没有下降。
我们在完成分表之后的一个月内又由于数据库里“其他表”的写入导致整个数据库 IO 增加,而且这些“其他表”还和业务关系不大。
也就是说一些可有可无的数据导致了整体业务受影响,这是非常不划算的事情。
于是我们便把这几张表单独移到一个新的数据库中,完全和现有的业务隔离开来。
这样就会涉及到几个改造:
- 应用自身对这些数据的查询、写入都要改为调用一个独立的
Dubbo
服务,由这个服务对迁移的表进行操作。
- 暂时不做数据迁移,所以查询时也得按照分表那样做一个兼容,如果查询老数据就要在当前库查询,新数据就要调用
Dubbo
接口进行查询。
- 对这些表的一些关联查询也得改造为查询
Dubbo
接口,在内存中进行拼接即可。
- 如果数据量确实很大,也可将同步的
Dubbo
接口换为写入消息队列来提高吞吐量。
目前我们将这类数据量巨大但对业务不太影响的表单独迁到一个库后,数据库的整体 IO
下降明显,业务也恢复正常。
总结
最后我们还需要做一步历史数据归档的操作,将 N 个月之前的数据要定期迁移到 HBASE
之类存储,保证 MySQL
中的数据一直保持在一个可接受的范围。
而归档数据的查询便依赖于大数据提供服务。
本次分库分表是一次非常难得的实践操作,网上大部分的资料都是在汽车出厂前就换好了轮胎。
而我们大部分碰到的场景都是要对高速路上跑着的车子换胎,一不小心就“车毁人亡”!