曾几何时,“并发高分库,数据大分表”成为了应对MySQL数据增长问题的圣经。面试官喜欢提问,博主喜欢写,候选人喜欢死记硬背。似乎形成了一个闭环。但是你有没有想过分库分表是否真的适合你的系统呢?刚做分表业务的时候,所有的流量都到一个MySQL,所有的用户信息都落到用户表里面。后来,user表的数据量越来越大。所以,你做一个垂直拆分,把原来的user表拆分成新的user表和user_details表。这样拆分之后,用户信息分布到两个表中,用户面的数据量一下子变小了,暂时解决了用户面数据量过大的问题。但是随着业务的发展,线上的流量越来越大,单一的MySQL已经无法承受流量的压力。当一个仓库无法承受压力时,就需要分仓。分库顾名思义就是把一个库拆分成多个库,让多个库分担流量的压力。分库也就是分表,也就是说分库一定是分表,分表不一定是分库。我们可以把分库分表的实现按照是面向应用还是面向DB分为三种:JDBC代理模式DB代理模式ShardingOnMySQLDB模式JDBC代理模式JDBC代理模式是一种去中心化的架构模式。ShardingSphere-JDBC是JDBC代理模式的典型实现。通常,jar用于提供服务,让客户端直接连接到数据库。这种模式不需要额外的部署和依赖,可以理解为JDBC驱动的增强版。JDBC代理模式虽然简单,但是违背了DB透明的原则,侵入性比较强。需要为不同的语言编写不同的驱动程序。美团的斑马、MTDDL、阿里的TDDL都是基于这个模型。DB代理模式DB代理模式是一种集中式架构模式。ShardingSphere-Proxy是DB代理模式的经典实现。该模式旨在实现透明的数据库代理,独立于应用部署。因为独立部署,没有异构语言的限制,也没有对应用的侵入。DB代理模式比JDBC代理模式消耗的连接更少,性能相对更好。但是集中式设计也带来了单点的问题。为了保持高可用和高性能,需要引入LVS/F5等VIP来实现流量负载均衡。如果跨IDC,也依赖DNS进行IDC分发,大大延长了应用到数据库的链路,从而提高响应时间。阿里的MyCat、美团的美团图集和百度海森堡都是基于DB代理模型实现的。ShardingOnMySQLShardingOnMySQL相当于屏蔽了分库分表的操作。是运维与中间件结合的沉淀。一个典型的例子就是阿里的DRDS。这种模式使得分库分表变得模糊,对于应用来说,更像是一种封装了MySQL的新型数据库。虽然用户变得更易用了,但是简单的背后是运维的沉淀,分库分表本该存在的问题依然存在。分库分表的代价分库分表的实现方式有很多种,但是不同方式的实现似乎弥补了MySQL不支持分布式的缺陷。分库分表迫使MySQL实现了伪分布式状态,这也带来了一些新的问题,例如:功能限制问题:分库分表后跨维join、聚合、子查询不复存在表,唯一键、外键等全局约束只能由业务来保证,DB逐渐弱化为存储。运维复杂度:分库分表后多张数据库表的管理比较麻烦,运维成本很高,数据查询也很麻烦。ShardingKey问题:非Shardingkey的查询需要额外的冗余处理,还需要引入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。从两者的架构图(省略了部分模块)可以看出,TDSQL和TiDB的架构只有一些命名上的差异,可以说几乎一模一样。两者作为一个整体分为三个部分:计算:负责接受客户端连接,进行SQL解析和优化,最终生成分布式执行计划并转发到底层存储层执行。(TDSQL:SQLEngine,TiDB:TiDB-Server)存储:分布式KV存储,类似NoSQL数据库,支持弹性扩缩容。(TDSQL:TDStore,TiDB:TiKV)控制:整个集群的元信息管理模块,是整个集群的大脑。(TDSQL:TDMetaCluster,TiDB:PlacementDriver)两者的核心存储模块(TDStore/TiKV)都是基于RocksDB开发的,都是KV存储模型。RocksDB是Facebook基于LevelDB开发的LSM-tree架构引擎,提供key-value存储和读写功能。底层采用WAL(WriteAheadLog)技术和SortedStringTable,写入吞吐量高于B-tree存储引擎。NewSQL平滑接入解决方案由于笔者已经登陆TiDB,所以这里以TiDB为例,介绍如何在不影响线上使用的情况下,接入NewSQL实现平滑迁移。第一步:在初始状态下,所有在线读写都落到MySQL。第二步:TiDB作为MySQL的从节点接入系统。所有在线读写仍然落在MySQL身上。最后通过脚本或者任务验证MySQL数据和TiDB数据是否一致。这一步主要是验证MySQL数据同步到TiDB没有问题。第3步:将部分读取切换到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(ReadCommitted)事务隔离级别,不支持RR(RepeatableRead)隔离级别。虽然它提供了SI(SnapshotIsolation),基本等同于RR,但是仍然存在写倾斜的问题。TiDB的点查询(select点)性能比MySQL差很多,亿级数据量勉强能和MySQL匹敌。因为底层是基于Raft协议进行数据同步,所以TiDB的延迟会比MySQL高。……因此,NewSQL并不是一把屠龙刀,这些缺陷的影响需要根据实际应用来评估。NewSQL的应用NewSQL在中国已经发展了很多年。OceanBase诞生于2010年,TDSQL可以追溯到2004年,TiDB诞生于2015年,三者在国内外都积累了大量的客户案例。OceanBaseOceanBase已经100%覆盖了蚂蚁集团的核心链路,支撑了五大业务板块。目前,数十亿条不同的SQL在运行,数据量达数百PB,服务器核心数超过百万。工行全行业务均使用OceanBase,包括但不限于存款、贷款、支付结算、创新业务等。OceanBase以混合云架构、高可用、Oracle兼容等特性,通过分布式中间件、金融套件、移动开发平台一体化解决方案,支撑网商银行核心系统的数字化转型。招商银行的“海量行情系统”和“历史盈利系统”使用OceanBase作为底层数据库。TDSQL微众银行实现了TDSQL的私有化部署,是典型的两地多中心架构。富途证券港股交易系统底层存储和东吴证券新一代核心交易系统均采用TDSQL。数字广东省务、深圳地铁代码登机等业务均运行在TDSQL之上。平安银行、农业银行、华夏银行、中国银行在TDSQL上都有相关业务。TiDB北京银行线上支付业务,北京银行所有银行卡都绑定了支付宝、微信等支付业务。后端数据库运行在TiDB上,是典型的双站点三中心同城双活架构。这项业务非常关键。业务中断超过一定时间的,需向银监会报告。日本第一大支付公司——Paypay,钱包和支付业务都在TiDB上。中国人寿寿险和财险业务正在逐步用TiDB替代Oracle。肯德基所有的会员登录系统,包括肯德基的APP和第三方登录,都使用TiDB作为后台数据库。这套服务将于2020年4月上线,经历过多次肯德基促销等活动。目前,肯德基的后台支付系统也已经切换到TiDB。麦当劳的账号和订单系统都是基于TiDB的。如果TiDB出现问题,麦当劳在中国的所有门店,包括线上线下的点餐系统,都将无法正常运营。WeBank最核心也是最赚钱的小额信贷业务,后台全批处理业务跑在TiDB上。分库分表和NewSQL如何选择?分库分表是一个重量级的解决方案,会带来很多新的问题,对基础设施和运维都有很高的要求。NewSQL功能强大,但也存在功能缺陷。如何做出选择,需要结合系统现状和公司情况综合判断。分库分表是一个重量级的解决方案。如果可以通过读写分离、冷热分离等轻量级方案解决的问题,就没有必要使用分库分表。如果无法忍受缓存卸载和读写分离,而你身处互联网企业,基础设施尚可,运维跟得上,分库分表仍然是首选;但是如果你在传统企业,基础设施差甚至没有基础设施,那你可以考虑NewSQL。技术没有高低之分,能解决问题的技术就是好技术。在选择技术方案时,不要炫技,也不要过度设计!
