查看原文
其他

数据库插曲 | 记一次数据库分表的初体验!

sssyyy 咪哥杂谈 2019-07-11
咪哥杂谈

数据库插曲

记一次数据库分表的初体验!


本篇文字约为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的实现源码,在计算时,是可以用位运算替代求余操作的!优势就在于位运算的速度比较快。。。




以上!就是最近了解到的新知识,感谢组内带我初体验了一波分表的操作!后来还问了相关的设计,在分库分表上优先考虑分表,原因是分表相对分库来说简单,减少多笔数据对一个表的访问压力就是分表的核心。若有更好的想法,欢迎小伙伴们留言区探讨!




●  python小课堂12 - 运算符篇

●   python小课堂11 - 变量篇

●  软文 | 谈谈核心竞争力!

●   生死一线 | 正确的急救知识

●  摄影小知识01 - 认识数码相机


长按关注


公众号名称:咪哥杂谈

一个咪咪怪的公众号

长按二维码关注哦!


来呀!来呀!关注我吧!!

Modified on

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存