分享好友 站长动态首页 网站导航

分库分表真的适合你的系统吗?聊聊分库分表和NewSQL如何选择

2022-07-18 09:00 · 头闻号数据库

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

面试官喜欢问,博主喜欢写,候选人也喜欢背,似乎已经形成了一个闭环。

但你有没有思考过,分库分表真的适合你的系统吗?

分表

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

后来,user 表的数据量越来越大了。

于是,你做了一次垂直拆分,将原来的 user 表拆分成了新的 user 表和 user_details 表。

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

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

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

分库

顾名思义,分库就是将一个库拆成多个库,让多个库分担流量的压力。

拆成多个库也意味着进行了分表,也就是说分库一定分表,分表不一定分库。

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

JDBC 代理模式

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

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

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

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

DB 代理模式

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

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

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

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

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

Sharding On MySQL

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

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

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

分库分表的成本

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

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

NewSQL

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

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

有。那就是 NewSQL。

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

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

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

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

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

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

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

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

底层利用了

NewSQL 平滑接入方案

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

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

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

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

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

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

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

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

整个方案的基础是:

这个方案是建立在

NewSQL 真的有那么好吗?

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

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

NewSQL 的应用

NewSQL 在国内其实已经发展了很多年,Oceanbase 诞生于 2010 年,TDSQL 可追溯到 2004 年,TiDB 诞生于 2015 年。

三者在国内外积累了不少的客户案例。

Oceanbase

TDSQL

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

TiDB

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

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

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

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

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

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

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

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

参考资料

https://shardingsphere.apache.org/document/current/cn/overview/

https://docs.pingcap.com/zh/tidb/stable/tidb-architecture

https://www.oceanbase.com/customer/home

https://dbaplus.cn/news-11-1854-1.html

免责声明:本平台仅供信息发布交流之途,请谨慎判断信息真伪。如遇虚假诈骗信息,请立即举报

举报
反对 0
打赏 0
更多相关文章

评论

0

收藏

点赞