7千万加分库分表思考
公司需要存储7000万+会员数据
背景
起初会员数据由数据侧存储,因为业务的发展,需要将会员数据存放至业务侧,所以需要应用技术方案来实现会员数据的增删改查
方案设计阶段
- 采用数据库读写分离,写库操作在主库,读库操作在从库(当有大量的写操作),加一个Master不能解决问题,因为数据要一致性,写操作需要2个甚至多个Master之间同步,相当于重复
- 考量数据库分库分表方案(sharding),对写操作进行切分
简单的读写分离
mysql的主从复制,结局了数据库的读写分离,提升了读的性能
读写分离造成的性能瓶颈
- 写入无法扩展,需要扩展master
- 写入无法缓存
- 锁表率上升
- 表变大,缓存率下降
分库分表
单库太大
单个数据库处理能力有限;单库所在服务器上磁盘空间不足;单库上操作的IO瓶颈 解决方法:切分成更多更小的库
单表太大
CRUD都成问题;索引膨胀,查询超时 解决方法:切分成多个数据集更小的表。
分库分表方式
分库分表的顺序应该是先垂直分,后水平分
- 垂直拆分
- 垂直分表
- 大表拆小表,基于列字段,将不常用的,数据较大,长度较长的字段拆分到扩展表,一般针对几百列的大表。
- 垂直分库
- 一个系统中不同业务进行拆分,比如user库,product库,order库,切分放在多个服务器上,而不是同一个服务器。单数据服务器上的性能瓶颈会将用户订单的crud会让当个服务器的磁盘空间,内存,tps等资源不足。高并发场景下,垂直分库一定程度上能够突破IO,连接数及单机硬件资源的瓶颈
- 垂直分表
- 水平拆分
- 水平分表
- 针对数据量巨大的单张表,按照某种规则(hash,range等),切分到多张表,但是表仍然在同一个库,所以库级别的操作还是IO瓶颈
- 水平分库分表
- 将单张表数据切分到不同的服务器上,每个服务器有相应的库表,能够有效缓解单机和单库的性能瓶颈和压力
- 水平分库分表切分规则
- range:从0-10000一个表,10001-20000一个表
- Hash取模:将用户,订单作为主表,然后将和它们相关的作为附表,这样不会造成跨库事务之类的问题。取用户id,然后hash取模,分配到不同的数据库上
- 地理区域:按照华东、华南、华北这样来区分
- 时间:按照时间切分,一年前数据切分放到另外的表,冷热数据分离
- 水平分表
分库分表产生的问题
- 维度问题 假如用户购买商品A,需要保存交易记录,如果按照用户维度拆分,则每个用户交易记录都在同一个表,所以可以很快查询某个用户维度的交易记录;但是要查某件商品的被购买情况,则比较麻烦。常见解决方案:1.记录两份数据,一份按用户维度,一份按商品维度。2.搜索引擎
- 联合查询问题 基本不可能,因为关联表可能不在同一个库
- 避免跨库事务,避免在修改db1的时候同步修改db2的操作,效率会有影响
分库分表多少合适
单表1000万条记录一下,写入读取性能是比较好的.这样在留点buffer,那么单表全是数据字型的保持在800万条记录以下, 有字符型的单表保持在500万以下。 如果按 100库100表来规划,如用户业务:500万100100 = 50000000万 = 5000亿记录
----------------------------再更分割线----------------------------------
llh