美文网首页mysqlmysql分布式
分表分库方案实现

分表分库方案实现

作者: HannahLi_9f1c | 来源:发表于2021-05-22 22:08 被阅读0次

前言:之所以要研究分表分库这个技术点,是因为在开发的过程中,因为分表分库踩了个小坑,虽然坑不算大,但是还是调试了很久。就是我在做推荐文章进入好友动态需求的时候,这个文章本身是一种type=51存储在数据库中,对应地转发这篇文章的feed的type也是51,只不过src_fid字段需要存储源文章的feed_id。


image.png

而推荐文章这个需求需要给feed表新增一种类型type=56,对应地在feed的分库新增一种类型type=302。后面就发现遇到坑了,因为我把分库的类型放到interaction_types中


image.png ,然后sync_feed_db.insert_data新增一种类型的时候
渲染的时候就查不到源文章,导致读取数据库失败。然后调试了很久,发现在读取源文章的时候读取不到,然后这条数据读取就失败了
image.png
image.png

在往上找,发现是这里读取失败了,这里是feed封装的方法,怎么会读取不到呢,于是我就进去看了看里面的代码

        if (table == conf.TBNAME_FEEDS and id_field in ('id', 'src_fid')) or \
                (table != conf.TBNAME_FEEDS and id_field == 'fid'):
            for global_fid in ids:
                if is_explore_fid(global_fid):
                    explore_fids.append(self.convert_global_fid_to_fid(global_fid))

                elif is_interaction_fid(global_fid):
                    interaction_fids.append(self.convert_global_fid_to_fid(global_fid))
                elif is_generalcard_fid(global_fid):
                    generalcard_fids.append(self.convert_global_fid_to_fid(global_fid))
image.png

因为源文章的类型是e_id,所以在查询出来某一条feed之后,会给src_fid自动拼装上前缀,如果一条feed是e_开头,会给他的src_fid拼上e_,但是由于前面把分库的类型写成i_类型,所以去expolore库查询就会查不到。还有一个坑就是explore类型的type不能大于300,大于300就会insert失败,这里也还没找到根因。
从这个bug中我就产生了很多疑问,为什么文章的src_fid需要放到一个库上呢?以及为什么要在代码中加上这种前缀呢?feed为什么要做分表分库,它是怎么做的呢?数据如何同步的?

一、分表分库的原理

当然第一步我们需要先了解一下分表分库的基本概念,分表分库上解决写请求越来越多的问题,以及数据量暴增的问题,因为对于读请求频繁的场景,可以加缓存或者用一主多从来解决,但是如果写请求过于频繁,那么压力都会集中在master上,master上面的IO,网络,连接池都会成为一种瓶颈。或者如果单表一直膨胀,那么对于磁盘来说压力山大,而且很容易带来慢查询。所以需要分表分库来解决这个问题。

分表的方式

  1. 垂直拆分
    垂直拆分分为两种,垂直分库和垂直分表。如果单库写请求多,并且分散在多张表的情况,这种情况可以把库里面的表分散到多个库中,每个库放在不同机器上,不然还是会遇到机器的瓶颈问题。如果压力集中到一张表,那么可以大表拆小表,把不常用较长的字段迁移到扩展表,避免跨表查询的压力
  2. 水平拆分
    水平拆分是将单表的数据水平拆分到不同服务器上,可以是按照Hash、地理位置、或者用户id进行分表。水平拆分的难度比垂直拆分更大一些。
    分表分库需要解决的问题
  3. 事务支持
    在单库或者单表中,可以用MySQL的事务解决一致性问题,但是分表分库的话,就需要解决分布式事务的问题了。
  4. order by ,group by,join
    分表分库之后order by 和group by要怎么实现?以及跨库的join问题
    相关产品


    image.png

二、实名分表分库

为什么实名要做分表分库

  1. feed库硬盘将满,单表过大,性能下降。
  2. 慢sql难以优化

遇到的问题怎么解决的?

  1. 如何拆分
    备选方案有几种,其中一种按照fid做hash,然后查询的时候并行地读取集群,跟业务无关。优点是逻辑简单,易于扩展,缺点是存在无fid的表,而且有fid和无fid的跨库join难以实现。还有一种是按照type来拆分,按照业务的type分在不同的库,互动类型等等,优点是业务逻辑清晰,易于拆分,缺点是跨业务的查询需要查询多个集群。最终是选择了按照type来拆分,对于同一种业务来说,很少会跨集群,这里也解释了为什么src_fid和fid的前缀要一致,这是因为要避免跨集群访问。
  2. 如何数据同步
    数据双写->老库数据迁移到新库->下掉老库的写入逻辑
  3. join,order by ,group by怎么做

代码实现细节

  1. 将存在badge的互动消息以及渲染的数据迁移到Redis,减轻数据库压力,能够给分表分库,提供一些时间。
  2. view层新增一个fid到gfid的转换,保证在后端的代码,都是带前缀(e表示探索类型,i表示互动类型)的gfid,这样能够区分是在哪个集群。
  3. 新增一个feed_manager,提供分表分库后的数据读写方法
  4. 将对新老数据库进行数据双写封装成api,方便调用,保持数据一致。
    三、mycat的一些实现

相关文章

  • 分库分表

    【分库、分表】MySQL分库分表方案 - MrSunny - 博客园 总结下Mysql分表分库的策略及应用 - 周...

  • 分表分库方案实现

    前言:之所以要研究分表分库这个技术点,是因为在开发的过程中,因为分表分库踩了个小坑,虽然坑不算大,但是还是调试了很...

  • 订单表的分库分表方案设计(大数据)

    订单表的分库分表方案设计(大数据) 一、两种方案分库分表 一般业界,对订单数据的分库分表,笔者了解,有两类思路:按...

  • mysql优化

    Mysql分库分表方案 Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时...

  • 分库分表

    Reference 分库分表需要考虑的问题及方案

  • [MySQL]MySQL分区与传统的分库分表

    传统的分库分表 传统的分库分表都是通过应用层逻辑实现的,对于数据库层面来说,都是普通的表和库。 分库 分库的原因 ...

  • 面试必备:我们为什么要分库分表?

    目录 什么是分库分表 为什么需要分库分表呢 如何分库分表 什么时候开始考虑分库分表 分库分表会导致哪些问题 分库分...

  • (转载)MySQL数据库之互联网常用分库分表方案

    MySQL数据库之互联网常用分库分表方案 一、数据库瓶颈 1、IO瓶颈 2、CPU瓶颈 二、分库分表 1、水平分库...

  • 分库分表方案

    为什么分库分表?单库单表性能时延扛不住,或者存储空间扛不住 分库和分表有区别吗?存在批量查询的情况下,分表只能徒增...

  • 分库分表方案

    -分表方案-数据迁移 1.分表计算。根据数据量现有量和递增量评估。表中字段不太多,字段长度适中的表,默认页大小为1...

网友评论

    本文标题:分表分库方案实现

    本文链接:https://www.haomeiwen.com/subject/ftanjltx.html