谈谈分库分表的几个核心流程

一、背景介绍

移动互联网时代,随着软件用户量的不断增长,由此产生的数据量也在飞速增长,比如,用户表、订单表、聊天消息表等。据统计,MySQL单表可以存储10亿级数据,只是这时性能比较差,业界公认MySQL单表容量在1KW量级是最佳状态,因为这时它的BTREE索引树高在3~5之间

既然一张表无法搞定,那么就想办法将数据放到多个地方,目前比较普遍的方案有3个:

  1. 分区
    • 要求数据不是海量(分区数有限,存储能力就有限)
    • 业务并发能力要求不高
  2. 分库分表
    • 互联网行业处理海量数据的通用方法
    • 发展几十年的RDBMS(关系型数据库)具有生态完善、绝对稳定、事务特性的优点,只要有软件的地方,它都是核心存储的首选
  3. NoSQL/NewSQL
    • NoSQL/NewSQL宣传的无论多厉害,就现在各大公司对它的定位,都是RDBMS的补充,而不是取而代之

本文就分库分表的一些核心流程展开介绍:
在这里插入图片描述

二、是单库分表,还是分库分表

  • 单库分表适用场景:
    1. 单表数据量太大,查询时需要扫描的行数太多,SQL执行效率低下
    2. CPU出现瓶颈
  • 分库分表适用场景:
    1. 磁盘读IO到了瓶颈:热点数据太多,数据库缓存放不下,每次查询时会产生大量的IO,导致查询速度低下
    2. 请求的数据太多、网络带宽不够
    3. 数据库连接数超过了最大限定值

分库分表的复杂度要高于单库分表,如果数据量不是特别大,且QPS也不是特别高,首选单库分表,待某些指标有接近阈值的迹象时,再考虑分库分表。

分库分表相对单库分表来说,复杂的地方有:

  • 需要约定多个分片数据源
  • 需要定义多个分片数据源的事务管理器
  • 数据一致性的处理方案(强一致 or 最终一致)
  • 数据迁移、后续扩容

三、分布式数据库中间件选型

本文主要针对时下比较流行的两款数据库中间件产品做下介绍:

主要指标 Sharding-JDBC MyCat
所属 Apache 基于阿里 Cobar 二次开发,社区维护
活跃度
ORM支持 任意 任意
基于客户端还是服务端 客户端 服务端
分库 支持 支持
分表 支持 不支持单库分表
事务 自带弱XA、最大努力送达型柔性事务 自带弱XA
监控 无,可通过其它方式支持 自带
读写分离 支持 支持
限制 部分 JDBC 方法不支持、SQL语句限制 部分 JDBC 方法不支持、SQL语句限制
数据库连接池 任意 任意
MySQL交互协议 JDBC Driver 前后端均用 NIO
开发 开发成本高,代码入侵大 开发成本小,代码入侵小
运维 维护成本低 维护成本高
配置难度 一般 复杂
Sharding-JDBC
架构图:

在这里插入图片描述

简单介绍:
  • Sharding-JDBC是一款轻量级的框架,以工程依赖JAR的形式提供功能,无需额外部署和依赖,可以理解为增强版的JDBC驱动
  • 对于运维同事来说,只需要协助一些简单的配置及后续的扩容工作,无需关注底层代码与分片策略规则,相对MyCat,这是 Sharding-JDBC的优势,减少了部署成本以及运维同事的学习成本
MyCat
架构图

在这里插入图片描述

简单介绍:
  • MyCat并不是业务系统代码里面的配置,而是独立运行的中间件,所有配置都会交给运维同事执行
  • 对于运维同事来说,它是在数据库Server前增加的一层代理,MyCat本身不存数据,数据是在后端数据库上存储的,因此,数据可靠性以及事务等都是通过数据库保证的
  • MyCat down 掉的时候,系统不能对数据库进行操作,会对所有用户产生影响
  • MyCat比较适合大数据工作

通过以上分析,可见Sharding-JDBC相对MyCat来说,更轻量,首选肯定是Sharding-JDBC,只要代码层面做好防腐层(依赖倒置)的设计,就算以后数据量级达到了百亿、千亿,也可以更加灵活方便的替换其它中间件产品,甚至 NewSQL

四、分布式ID的生成方式

实现方式
  • 完全依赖数据源的方式:ID的生成规则,读取控制完全由数据源控制,常见的如数据库自增长ID、序列号、优雅的Flickr方案、基于Redis的原子操作incr/incrBy产生顺序号、MongodbObjectId、美团(Leaf)的号段模式…

  • 半依赖数据源的方式:ID的生成规则,有部分生成因子需要由数据源(或配置信息)控制,如百度的uid-generator、美团(Leaf)的Snowflake模式…

  • 不依赖数据源的方式:ID的生成规则完全由机器信息独立计算,不依赖任何配置信息和数据记录,如常见的UUID及变种、GUID

实践方案

实践方案适用于以上提及的三种实现方式,可作为这三种实现方式的一种补充,旨在提升系统吞吐量,但原有实现方式的局限性依然存在。

  • 实时获取方案:顾名思义,每次要获取ID时,实时生成。简单快捷,ID都是连续不间断的,但吞吐量可能不是最高的。

  • 预生成方案:预先生成一批ID放在数据池里,可简单自增长生成,也可以设置步长,分批生成,需要将这些预先生成的数据,放在存储容器里(JVM内存,Redis,数据库表均可以),可以较大幅度地提升吞吐量,但需要开辟临时存储空间,断电宕机后可能会丢失已有IDID也可能有间断。

选择分布式ID的生成方式时,需要特别注意以下几个地方:
  • 全局唯一:必须保证ID是全局唯一的

  • 高可用:无限接近于100%的可用性

  • 高性能:低延时,ID生成响应要快

  • 接入方便:遵循拿来主义原则,在系统设计和实现上要尽可能的简单

  • 长度适中:不要太长,最好64bit,使用long比较好操作。如果是96bit,需要各种移位,相当的不方便,还有可能有些组件不能支持这么大的ID

  • 分片支持:可以控制ShardingId,比如某一个用户的文章要放在同一个分片内,这样查询效率高,修改也容易,实现稍复杂

  • 信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞争对手可以直接知道我们一天的订单量,所以要结合自己的业务场景来考虑

如果系统要求的吞吐量不是极高,个人推荐了解下优雅的Flickr方案,如果系统要求的吞吐量极高,个人推荐了解下美团的(Leaf)项目,由于篇幅有限,这里不做过多展开。

五、分片/表键选择

分片键的定义

分片键即分库分表的拆分字段,是在水平拆分过程中用于生成拆分规则的数据表字段,根据分片键的值将数据表水平拆分到每个分库/分表

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值