`
海浪儿
  • 浏览: 271644 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

分库分表对老业务功能带来的冲击

阅读更多

本文为原创,转载请注明出处

分库分表对老业务功能带来的冲击

 

         当业务量发展到一定的程度时,不可避免的需要对数据进行分库分表。以用户的签约数据为例,当用户量很少时,单库单表是可以满足的,但当用户量达到某个级别,譬如亿级,那么单库就会成为瓶颈,需要根据某种维度(譬如userId)来进行分库分表。

分库分表如何实现本文就不阐述了,可以参考一下淘宝的tddl。本文主要阐述分库分表过程中对老业务逻辑带来的冲击以及如何改造,因为有些原来单库单表中很容易实现的功能,一经分库分表后,就变的很棘手,譬如:

      a)根据主键ID(非userId)查询签约信息:

      b)插入数据时,userId为空

      c)联表查询,多个表不在同一个库里

 

1、首先来分析第一个问题:根据主键ID(非userId)查询签约信息。

由于根据userId来进行分库,那么根据ID是无法知道该去哪个库查询,当然可以采取全库扫描,但一般这在性能上是无法接受的,违背了分库分表的初衷。可以采取以下几种方案:

      1.1、在进行查询前,如果能拿到userId,则改造为根据userIdid两个条件去查询。

      1.2、如果拿不到userId,那么对于老数据,需要建立一个前置表,该表存储iduserId的映射关系(即:该表只有两个字段,id和userId)。根据ID查询前,先根据ID去查询前置表,得到userId,然后再根据userIdid两个条件查询。



 

分库分表前



 

分库分表后

需要注意的是,该前置表只需要存储老数据的映射关系(该表的数据由系统发布上线前对老数据迁移得到,发布上线后,不会再有新数据写入),对于新数据,在生成ID时,ID需要包含所属库和所属表的标示,这样根据ID查询新数据时就可以直接路由到具体的库和表了,不需要再查询前置表。那么根据ID如何区分新老数据呢,可以根据ID的长度(一般分库后的ID位数会扩容)

        

2、接着分析第二个问题:插入数据时,userId此时为空

在分库分表前,有些业务流程在执行过程中,插入数据时没有分库分表的维度信息譬如userId,只有执行某个业务操作譬如用户登陆后才能得到userId,然后更新这条记录以补全userId




分库分表前

那么分库分表后,在插入数据的那个时刻,就无法知道该把数据插入到哪个库哪个表。针对这种情况,需要对插入数据的流程进行改造。

先将数据进行临时存储,譬如存储在集中式缓存(tairmemcache等)等用户登陆后拿到userId后,再从缓存中查询出数据,然后再插入数据到DB中。



 

分库分表后

3、再来看第三个问题:联表查询,多个表不在同一个库里

         对联表查询进行拆分,保证被拆分过后的原子查询都落在相同的库里。当然,对于左联结或右联结查询,要特备注意拆分前后结果的一致性,很有可能会出现拆分后结果记录数减少的情况,需要重点测试。

 

 

  • 大小: 5 KB
  • 大小: 15.7 KB
  • 大小: 9.7 KB
  • 大小: 22.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics