分库分表和 NewSQL 到底怎么选?


文章来源:【公众号:CoderW】

目录

  • 背景

  • 分表

  • 分库

  • 分库分表的成本

  • NewSQL

  • NewSQL 平滑接入方案

  • NewSQL 真的有那么好吗?

  • NewSQL 的应用

  • 分库分表和 NewSQL 到底怎么选?

背景

曾几何时,“并发高就分库,数据大就分表”已经成了处理 MySQL 数据增长问题的圣经。

面试官喜欢问,博主喜欢写,候选人也喜欢背,似乎已经形成了一个闭环。但你有没有思考过,分库分表真的适合你的系统吗?

分表

在业务刚刚发展起来的时候,流量全部打到了一个 MySQL 上,用户信息全落到了 user 表。

a8a5a0b55bebfe4c64f305e186869887.png

后来,user 表的数据量越来越大了。于是,你做了一次垂直拆分,将原来的 user 表拆分成了新的 user 表和 user_details 表。

2ff2bdc0d99703fe7138b735754a84ee.png

这样一拆之后,用户的信息分散到两个表,user 表的数据量一下就变小了,user 表数据量过大的问题暂时就解决了。

但随着业务的发展,线上的流量越来越大,单个 MySQL 已经扛不住流量的压力了。

2eba49ba35a0a55c2548a7ced6a7afa8.png

单个库承受不住压力的时候,就需要分库了。

分库

顾名思义,分库就是将一个库拆成多个库,让多个库分担流量的压力。拆成多个库也意味着进行了分表,也就是说分库一定分表,分表不一定分库。

我们可以根据偏应用还是偏 DB,将分库分表的实现方式分成三种类型:

  • JDBC 代理模式

  • DB 代理模式

  • Sharding On MySQL 的 DB 模式


| JDBC 代理模式

JDBC 代理模式是一种无中心化的架构模式。ShardingSphere-JDBC 就是 JDBC 代理模式的典型实现。

通常以 jar 包形式提供服务,让客户端直连数据库,这种模式无需额外部署和依赖,可理解为增强版的 JDBC 驱动。

e166169ad09f019b0c184d57da2d512b.png

JDBC 代理模式虽然简单,但违背了 DB 透明的原则,侵入性比较高,需要针对不同的语言编写不同的 Driver。

美团的 Zebra、MTDDL,阿里 TDDL 都是基于这种模式的实现。

| DB 代理模式

DB 代理模式是中心化的架构模式。ShardingSphere-Proxy 就是 DB 代理模式的经典实现。

这种模式旨在实现透明化的数据库代理端,并独立于应用部署,因为独立部署,所以对异构语言没有限制,不会对应用造成侵入。

c09bd6912cf179b0b0ae5ff870c4b837.png

DB 代理模式比 JDBC 代理模式消耗的连接数会少,相对来说性能也会更好。

但中心化的设计也带来了单点的问题,为了保持高可用和高性能,还需要引入 LVS/F5 等 VIP 来实现流量的负载均衡,如果跨 IDC,还依赖诸如 DNS 进行 IDC 分发,大大拉长了应用到数据库的链路,进而提高了响应时间。

阿里的 MyCat、美团的 Meituan Atlas 和百度 Heisenberg 就是基于 DB 代理模式的实现。

| Sharding On MySQL

Sharding On MySQL 相当于屏蔽了分库分表的操作,是运维和中间件结合的沉淀,比较典型例子是阿里的 DRDS。

a05674b88922485f8ac875b60833a847.png

这种模式让分库分表变得模糊,对应用来说,更像是一个封装了 MySQL 的新型数据库。

虽然用户使用变得更简单了,但简单的背后是运维的沉淀,分库分表该存在的问题它依然存在。

分库分表的成本

实现分库分表的方式有很多,但不同模式的实现似乎都是在弥补 MySQL 不支持分布式的缺陷。

分库分表这种强行让 MySQL 达到一个伪“分布式”的状态,也带来了一些新的问题。

比如:

  • 功能限制问题:分库分表后跨维度 join、聚合、子查询不复存在,唯一键、外键等全局约束也只能靠业务保障,DB 慢慢弱化为存储。

  • 运维复杂度问题:分库分表后的多个库表的管理麻烦,运维成本非常高,数据查询也很麻烦。

  • Sharding Key 问题:非 Sharding key 的查询需要做额外的冗余处理,需要引入 Elasticsearch、ClickHouse 等其他节点,进一步提高了系统的复杂度。

  • 唯一 ID 问题:分库分表后唯一 ID 得不到保障,需要对唯一 ID 进行改造。

  • 分布式事务问题:MySQL 自带的 XA 柔性事务性能太低,需要引入新的分布式事务解决方案。


NewSQL

从上文得知,分库分表需要牺牲 MySQL 的一些功能,还带来许多新的问题。

那有没有一种方案,既能拥有 MySQL 的功能,又能支持数据的可扩展?有。那就是 NewSQL。

NewSQL 是一类关系数据库管理系统,旨在为在线事务处理(OLTP)工作负载提供 NoSQL 系统的可扩展性,同时保持传统数据库系统的 ACID 保证。

国内比较知名的 NewSQL 有阿里的 OceanBase、腾讯的 TDSQL、PingCAP 的 TiDB。它们既有 MySQL 的功能,又有分布式可扩展的能力。

笔者对阿里的 OceanBase 只能说是略懂皮毛,就不过多描述。

我们重点看一下腾讯的 TDSQL 和 PingCAP 的 TiDB。

5d700d66ee03f3d458f9aa00517f03d0.png

从两者的架构图(省略了部分模块)上可以看出,TDSQL 和 TiDB 的架构只有一些命名差别,可以说几乎一模一样。

两者整体来说分为三个部分:

  • 计算:负责接受客户端的连接,执行 SQL 解析和优化,最终生成分布式执行计划转发给底层的存储层执行。(TDSQL:SQL Engine 、TiDB:TiDB-Server)

  • 存储:分布式KV 存储,类似 NoSQL 数据库,支持弹性扩容和缩容。(TDSQL:TDStore 、TiDB:TiKV)

  • 管控:整个集群的元信息管理模块,是整个集群的大脑。(TDSQL:TDMetaCluster 、TiDB:Placement Driver )

两者核心的存储模块(TDStore/TiKV),都是基于 RocksDB 开发而来,都是KV 存储的模式。

RocksDB 是由 Facebook 基于 LevelDB 开发的一款提供键值存储与读写功能的 LSM-tree 架构引擎。

底层利用了WAL(Write Ahead Log)技术和 Sorted String Table,比 B 树类存储引擎更高的写吞吐。

NewSQL 平滑接入方案

因为笔者落地过 TiDB,所以会以 TiDB 为例描述如何接入 NewSQL,做到不影响线上使用的平滑迁移。

437d33a6e35b032324292ea3986ec84f.png

第一步:初始状态,所有线上读和写都落到 MySQL。

第二步:将 TiDB 作为 MySQL 的从节点接入系统,所有线上读写还是都落到 MySQL,日末通过脚本或者任务验证 MySQL 的数据和 TiDB 的数据是否一致,这一步主要验证 MySQL 数据同步到 TiDB 没有问题。

第三步:将部分读切换到 TiDB,这一步主要验证 TiDB 同步的数据读没有问题,验证系统 SQL 能正常在 TiDB 执行。

第四步:断掉 MySQL 和 TiDB 之间的同步,双写 MySQL 和 TiDB,所有的线上读流量都落到 MySQL。

第五步:将部分读流量切到 TiDB,验证 TiDB 写入的数据能够正常读取。这一阶段可以将部分幂等任务同时在两个数据源上执行,验证两者数据是否一致。

第六步:将所有的线上读流量切到 TiDB,同时保持双写,如果出问题随即切到 MySQL。

第七步:断掉 MySQL 的写流量,将 MySQL 作为 TiDB 的一个从库,作为降级使用。

整个方案的基础是:TiDB 兼容 MySQL 协议和 MySQL 生态。

这个方案是建立在完全不信任 TiDB的基础上设计的,验证了 TiDB 和 MySQL 的契合点,所以整体会比较繁琐,实际落地的时候可以根据情况省略一部分步骤。

NewSQL 真的有那么好吗?

NewSQL 并是不万能的,也不必去过于神化 NewSQL,国内比较知名的几种 NewSQL 或多或少都存在部分功能缺陷。

以 TiDB 为例:

  • TiDB 的自增 ID 只能保证单个 TiKV 上的自增,并不能保证全局自增。

  • 由于 TiKV 存储是根据 key 的二进制顺序排列的,使用自增 ID 可能会造成热块效应。

  • TiDB 默认 RC(读已提交)的事务隔离级别,并且不支持 RR(可重复读)隔离级别,虽然提供了基本等价于RR的SI(Snapshot Isolation),但还是存在写偏斜问题

  • TiDB 的点查(select point)性能比 MySQL 要差不少,在几个亿级别的数据量才能勉强和 MySQL 打平。

  • 因为底层基于 Raft 协议做数据同步,所以 TiDB 延迟会比 MySQL 要高。

  • ...

所以说,NewSQL 也并不是屠龙刀,需要根据实际应用去评估这些缺陷带来的影响。

NewSQL 的应用

NewSQL 在国内其实已经发展了很多年,OceanBase 诞生于 2010 年,TDSQL 可追溯到 2004 年,TiDB 诞生于 2015 年。三者在国内外积累了不少的客户案例。

OceanBase:

  • OceanBase 已经覆盖蚂蚁集团100%核心链路,支撑全部五大业务板块。目前运行数十亿条不同的 SQL、数据量达数百 PB、服务器核数过百万。

  • 中国工商银行全行业务都使用 OceanBase,包含不限于存、贷、支付结算及创新业务等。

  • OceanBase 凭借混合云架构、高可用、Oracle 兼容等特性,通过分布式中间件、金融套件、移动开发平台集成解决方案,支撑网商银行核心系统数字化转型。

  • 招商银行的“海量行情系统”和“历史收益系统”就是采用 OceanBase 作为底层数据库。


TDSQL:

  • 微众银行实现了 TDSQL 私有化部署,是一个典型的两地多中心架构。

  • 富途证券的港股交易系统、东吴证券新一代核心交易系统底层存储都是 TDSQL。

  • 数字广东粤省事、深圳地铁码上乘车等业务都是在 TDSQL 上面跑的。

  • 平安银行、中国农业银行、华夏银行、中国银行都有相关业务在 TDSQL 上。


TiDB:

  • 北京银行的网联支付业务,所有北京银行的银行卡绑定在比如支付宝、微信上的支付操作,后端的数据库就是运行在 TiDB,而且是一个典型的两地三中心同城双活的架构,这个业务非常的关键,如果业务中断超过一定时间,就是需要上报银监会的。

  • 日本排名第一的支付公司——Paypay,钱包和支付的业务都在 TiDB 上面。

  • 中国人寿的寿财险业务,正在用 TiDB 陆续替换 Oracle 。

  • 肯德基所有的会员登录系统,包括 KFC 的 APP 以及第三方登录,后台数据库都是用的 TiDB ,这套业务 2020 年 4 月份上线,已经经历过多次肯德基的大促等活动,目前肯德基的后台支付系统也已经切换到 TiDB 上。

  • 麦当劳的账户以及订单系统全部基于 TiDB,如果 TiDB 出问题了,那么国内所有的麦当劳门店,包括线上和线下的点单系统都将没法正常运行。

  • 微众银行最核心和最赚钱的微粒贷业务,后台的全量批处理业务就运行在 TiDB 上面。


分库分表和 NewSQL 到底怎么选?

分库分表是一个重量级的方案,它会带来很多新的问题,对基建和运维的要求也很高。

NewSQL 功能强大但也有功能缺陷。

如何去抉择需要根据系统现状和公司情况去综合判断。

6c3fd3c656eed6d3072ca43d84bf7a6a.png

分库分表是一个重量级的方案,如果读写分离、冷热分离等轻量级方案能解决的问题就没必要上分库分表。

如果缓存分流和读写分离都扛不住了,且你身处互联网企业,基建尚可且运维也跟得上,分库分表仍然是第一选择。

但如果你身处一个传统的企业,基建很差甚至没有基建,那么你可以考虑考虑NewSQL。

技术没有高低之分,能解决问题的技术就是好技术,技术方案选择上切莫炫技,也切勿过度设计!

-------------  END  -------------
扫码免费获取600+页石杉老师原创精品文章汇总PDF



原创技术文章汇总


点个在看你最好看
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值