数据库插曲 | 记一次数据库分表的初体验!
数据库插曲
记一次数据库分表的初体验!
本篇文字约为600字,阅读时间约为5分钟。
1
业务前景
由于小编所在的公司是传统型公司,而业务对接的确实像蚂蚁货运险这样的大业务,从2017年中旬对接到公司的业务数据量大约一天150W左右数据,而去年的双十一最高峰值则达到2000W一天的数据量!公司所入的数据量全部存在10多张不同业务的表中,而中途数据库已经告警过几次,显然这样的架构是不符合现在的交易规模的。。。预计今年双十一的数据量会暴增2倍,也就是4000W左右一天。而为了提前预防这样的爆表措施,老大提出了一次分表的优化!我一听,激动的心情就像这样:
2
优化方案
所以呢,有了需求就是干!优化方案如下:
在不影响原来的10+张表相对应的业务逻辑基础上,将其揉合成一张表,其中这张表所包含的字段是10+张表***重要***字段。通过蚂蚁货运险中的保单号作为唯一条件,对合成的一张表进行分表设计!目的是:降低原来单表的数据量,减少数据库单笔交易的竞争压力。这里我估计且将合成的表称之为Ant表吧!分表的同时,也考虑到不影响其它系统的正常运行,所以分表的设计是对自己系统无外关联的表进行分表设计,也就是说,这合成的10+表仅仅是我们组使用的业务表!
3
重点实现思路
本次优化采用的是水平分表,水平分表的含义:分表之后的所有表结构都是相同的。
将上述Ant表分为每个季度16张表,也就是一共64张表,采用对货运险中的保单号值进行hash计算,经算出来的值在进行相应的位运算,最终算出每笔交易落在哪个季度的哪个表中。
表名设定:
1. 一年有四季度,故采用计算机中常用的索引表达,0 - 3来表示4个季度,0代表第一季度,1代表第二季度,2代表第三季度,3代表第四季度。
2. 合成后的一张表对其进行拆分成16张表,同样采用计算机中常用的索引表达,0 - 15,来表示16张表的索引值,比如0 代表分割后的第一张表,15代表分割后的第16张表。
有了以上两个逻辑,可以得出的表名设定: Ant_0_0 ,代表第一季度的第一张表, Ant_1_2 代表第二季度的第三张表, Ant_2_0 代表第三季度的第一张表。。。以此类推。。。
实际上,此项目业务逻辑分为了两部分,一部分是入库逻辑,还有一部分是查询逻辑。入库逻辑部分采用python语言进行编写(脚本语言的好处:与蚂蚁对接后直接读取文件进行sql拼接入库,入库周期较短,节省流程的耗时);查询部分是镶嵌在web项目中的,所以是用java语言进行实现的。有了思路,一切都是浮云了好吧~一个字干!
4
部分重点代码实现
下面分别给出两部分重点的代码实现思路。
python 部分:
1. 计算出对应的16张表所属字段:
2. 获取当前季度:
java 部分:
1. 计算出对应的16张表所属字段:
2. 获取当前季度:
5
总结
基本上述就是本次分表的设计主思路,可以看到,入库和查库,为了保证一致性,需要设计相同的算法才可以保证数据一致,所以python版迎合了java版的hashcode算法,最终入库的同一笔交易可以在java中查到。其中还有一个编程上的小技巧,就是在求具体0 - 15的时候,当初编码的时候没有用求余的方式,而采用了位运算,感兴趣的同学可以看下jdk7中HashMap的实现源码,在计算时,是可以用位运算替代求余操作的!优势就在于位运算的速度比较快。。。
以上!就是最近了解到的新知识,感谢组内带我初体验了一波分表的操作!后来还问了相关的设计,在分库分表上优先考虑分表,原因是分表相对分库来说简单,减少多笔数据对一个表的访问压力就是分表的核心。若有更好的想法,欢迎小伙伴们留言区探讨!
长按关注
公众号名称:咪哥杂谈
一个咪咪怪的公众号
长按二维码关注哦!
来呀!来呀!关注我吧!!