亿级大表的拆分思路
公众号:杨建荣的学习笔记 · 作者:杨建荣 · 发布:2019-01-19 00:01:04 · 原文链接
这是学习笔记的第 1863篇文章
线上环境有一个表,数据量比较稳定,有近5亿,这个表存储的是状态型数据,从增长率来看,和流水型数据不同,数据量不会有爆发式增长,但是还是有一定幅度的增长。这个表的业务模型比较简单,没有关联,只有查询和修改的数据需求。
而这个环境是一个MySQL,MySQL支撑亿级别的单表数据,虽然数据模型简单,但是从性能上来说,这个损耗会比较明显。
在初步的业务对接改造中,和业务商议,是改造为了hash的方式,把原本一个表拆成了256个子表,按照这个数据量来算,每个字表近200万的数据量。
对于业务来说,这种模式是不透明的,从业务逻辑来看,它是直接面向的是这256个表。查取数据的时候会在业务层做一个hash计算,得到相应的表名,然后完成相关的数据操作。
这种方式有一些缺点,IO压力无法水平扩展,因为拆分都是在单个库里面,所以尽管拆分开了,有了一定的效果,但是IO的吞吐量和压力是不变的,同时这种方式有一个潜在的隐患,就是对于后续的数据增长,比如大概一年的时间,从5亿数据涨到了8亿,那么单表的数据量就会变为400多万,按照这种增长,也会达到瓶颈,当然只是时间的差异。
按照已有的数据操作模型,我们对已有的表做了后续的改造,把这个表拆分为分布式架构,拆分为16个分片,即有16个数据库来承载这些数据的IO压力。 按照这种分片来算,单个分片有3000多万的数据,其实这样的效果是有,但是还是粒度太粗。 不能我分了256个分片,要用256个节点吧。
其实我们可以下钻一层,在db层面做一些改进,我们可以对库里的表做一次hash,即有16个db,比如:
score01-score16
score01里面的表user_score可以拆分为50份,这样score01里面就是50个子表:
user_score00-user_score49
按照这种拆分方法,会有50*16=900个分片,单表的数据量会大大降低,而且后续扩容也会更加容易。
