共计 7056 个字符,预计需要花费 18 分钟才能阅读完成。
作者:伴鱼技术团队
技术选型是由技术方向和业务场景 trade-off 决定的,脱离业务场景来说技术选型是没有任何意义的,所以本文只是论述了伴鱼技术团队数据库选型的过程,这并不是 MySQL、MongoDB 和 TiDB 之间间接的比拟,只能阐明 TiDB 更适宜伴鱼的业务场景和技术布局,另外因为 TiDB 是十分新的数据库技术,所以这也能体现出伴鱼技术团队对新技术的态度、技术后发优势的了解、老本与效率的衡权和技术生态与红利的思考。
为什么放弃 MongoDB?
伴鱼是 2015 年成立的,那个时候 NoSQL 还如日中天,关系型数据库为了应酬海量的数据只能业务侵入式的分库分表,尽管 Google 在 2012 年公布了 NewSQL 数据库 Spanner 的论文,然而工业界还没有一款能够应用的 NewSQL 数据库,综合过后的各种状况,伴鱼抉择的是 MongoDB。
不过,在 2015 年到 2017 年之间,对于伴鱼来说 MongoDB 的确是一个上佳之选,次要有以下几个方面的起因:
- 开发更高效 :公司初期处于探索期,产品迭代十分快,MongoDB 是 NoSQL 数据库,不须要做建库建表等 DDL 操作,特地在产品疾速迭代,须要频繁增减字段的时候就更高效,当然这个也是有代价的,从实质上来说,MongoDB 是读模式,它简直不查看写入的内容是否非法,对数据 Schema 的解释是在应用程序的代码中,导致写入数据的约束性是没有保障的。
- 运维更高效 :过后公司研发非常少,这段时间整个后端只有两个工程师,没有专职的运维和 DBA,然而 MongoDB 的单机性能比 MySQL 要高不少,岂但对数据库的运维老本要低不少,并且过后除了几个热点库外,其余的库 MongoDB 能够间接扛住流量压力,省去了两头的 Cache 层,让开发和运维都更高效。
- 有事务需要的场景不多 :过后应用的是 MongoDB 2.x 和 3.x,只提供了数据一致性的抉择(强一致性、枯燥一致性和最终一致性)和原子操作,在多数的几个场景,比方交易相干的场景,通过抉择强一致性和原子操作,再在应用层实现 MVCC 的机制,能够满足简略的事务需要。
总体来说,在伴鱼产品的探索期,为了效率就义一点数据约束性和事务能力是值得的,然而 2017 年底伴鱼产品方向比拟明确后,业务场景从探索期转变到疾速发展期,对数据库的需要从效率优先转变为效率、事务能力与生态并重:
- 有事务需要的场景急增 :事务场景从最后与钱相干的交易扩大到一些虚构货币,并且因为并发量的减少,之前没有事务保障的场景呈现竞争的状况越来越多,还在应用层通过 MVCC 机制实现简略的事务是十分低效的,并且在应用层实现事务的正确性也是很难保障的。(一个乏味的故事:Jeff Dean 已经说过本人对 Bigtable 最悔恨的事件是没有提供跨行事务反对,导致业务就会在下层希图本人搞事务,并且业务实现的分布式事务大部分都是错的,所以在起初的 Spanner 数据库中 Jeff Dean 间接提供了官网分布式事务反对。)
- 对大数据生态的需要急增 :在产品探索期的时候,也有很强的数据分析需要,不过过后数据总量小,在 MongoDB 的暗藏从库中间接剖析就足够了,然而产品疾速发展期,数据量急剧减少,在 OLTP 数据库中进行 OLAP 操作曾经力不从心了。然而通过大数据生态来进行数据分析,对于 MongoDB 来说有一个十分残暴的事实,根本所有的大数据生态都是围绕 MySQL 生态打造的,如果想接入 MongoDB 的数据,意味着须要从新大量造轮子。
- 对数据约束性的要求更高 :因为业务疾速的倒退,服务可能会呈现多人保护和移交的状况,如果存储的数据没有束缚,意味着存储的数据 Schema 是不可控的,这很容易让前面参加的工程师解体和掉进坑里,这个时候数据的约束性变成是一个更高优良级的需要,关系数据库的写模式变成更好的抉择。
到产品疾速发展期,因为业务场景对数据库的需要曾经产生了很大的扭转,所以在这个时候,伴鱼技术团队开始审慎思考数据库从新选型的问题,咱们现实型的数据库是这样的:
- 高可用;
- 高吞吐;
- 反对 ACID 事务;
- 大数据生态敌对;
- 有程度扩张能力,并且尽量做到不侵入业务;
基于下面这些需要,咱们开始了数据库的从新选型之路。
初识 TiDB
早在 2015 年的时候我就十分关注分布式数据库,过后曾经经验过高并发高 QPS 的场景,利用分布式架构解决无状态高并发高 QPS 场景是不简单的,然而分布式存储因为波及到一致性问题是十分有挑战的,如果还想反对 ACID 事务那就更难了,所以过后就对分布式数据库技术特地感兴趣,开始关注 OceanBase 并且收集和钻研相干的实践和架构文档。
起初共事举荐说有个叫 TiDB 的数据库,目前有些公司也在用了,反馈也不错,所以咱们决定调研一下。TiDB 官网的文档做的十分敌对,不论是实践还是架构的文章都十分齐全,简直一口气就把所有的文章都看了一遍(过后文章比当初要少),齐备的实践反对、优雅的架构设计、与 Google Spanner 一脉相承的设计思路让咱们对 TiDB 的前景十分看好,并且性能上齐全满足咱们的要求,所以过后就决定长期关注 TiDB,并且筹备进行初步验证。
初步验证
通过调研咱们发现,TiDB 是通过 raft 协定来保障多正本数据的一致性(ACID 中的 C),通过 2PC 协定来保障事务的原子性(ACID 的 A),通过乐观锁加 MVCC 来实现可反复读的事务隔离级别(ACID 中 I),这意味着 TiDB 每一次事务的老本是比 MySQL 要高很多的,特地是有事务抵触的时候(乐观锁的起因),所以性能是须要验证的关键点。
过后伴鱼所有的业务都部署在阿里云上(当初有自建机房),就间接在阿里云下面按 TiDB 的配置要求购买了机器,过后装置的是 TiDB 1.x 的版本。因为 TiDB 官网曾经有 Sysbench 的压力测试数据,这个性能数据是合乎咱们需要的,所以决定对咱们的业务场景进行一次齐全模仿的长期测试:伴鱼 IM 的并发比拟高,并且采纳写扩散的设计,对数据库的要求会比拟高,所以适宜进行验证。通过对 IM 业务的 inbox 表进行双写,业务同步写 MongoDB 和异步写 TiDB,业务读只读 MongoDB,这样如果 TiDB 有问题也不会影响线上业务。
在低峰期对 IM 业务开启双写后,TiDB 监控的 999 线和 99 线还满足要求,然而所有 TiKV 节点的 io 使用率始终在 90% 左近稳定,这个如果到高峰期是相对会有问题的,通过重读 TiKV 的配置,在批改配置项 sync-log = false 后,TiKV 的 io 使用率维持在 5% 以下,当天的高峰期也一切正常,没有呈现问题。
在这之后,咱们对 IM 的双写察看 2-3 个月的工夫,在确认一切正常后,再将同步读写都批改为 TiDB 并且异步写 MongoDB,一切正常并且继续察看。
sync-log 配置是管制 TiKV 数据多正本进行 raft 协定同步的时候,如果 sync-log=false,则内存中解决实现就返回 ack,对于 3 正本来说,单节点故障是不会失落数据的,同一个 raft 集的 2 个正本同时故障可能会呈现丢数据的状况,这个问题除了金融等对数据安全性要求十分高的场景外,其余的业务场景是能够承受的,并且 MySQL 等其余数据库的集群计划在 master 节点故障的时候问题更大。
深度交换
在后面初步验证 TiDB 的过程中,一个看似很重大的问题然而调整一个配置就能够解决,这让咱们发现了咱们对 TiDB 的了解和控制力还不够,在对每一个配置都进行了解钻研外,还有一些咱们十分关怀的问题但没有官网答案。如果对这些问题没有官网答案,那么咱们间接应用 TiDB 就是有很大危险的,所以咱们决定和 TiDB 团队进行一次深度的交换。
咱们过后十分关怀的问题列表为:
- T- iKV 的线性扩大能力怎么样?
- 两地三核心架构,TiDB 能够容忍数据中心之间的提早是多少?
- 目前业界 TiDB 最大的一个集群的 TiKV 和 TiDB 的节点数、数据量、QPS 最高是多少?
- TiDB 哪一些配置是须要特地关注和调整的?
- …
收集了大略 20 多个问题,得益于伴鱼和 TiDB 都在北京,离得还十分近,在线上分割上并且约好工夫后,和 TiDB 进行了第一次深度的交换。
大略是 2018 年上半年的一天,我和 TiDB 的 3-4 个共事聊了一整个上午,根本都是我将收集到的问题一个个抛出来,大家一起探讨。整个交换过程解答了很多咱们关怀的问题,也理解到以后业界对 TiDB 的应用状况,大大加强了咱们对 TiDB 的信念,对于数据库的选型来说,这是十分要害的事件。
为什么不抉择 MySQL?
通过对 TiDB 的调研、试用和深刻交换后,在传统的关系型数据库 MySQL 和 NewSQL 数据库 TiDB 之间,咱们须要做出本人的抉择了,这不仅仅是两个数据库之间的抉择,这其实也体现了伴鱼对新技术的态度、技术后发优势的了解、老本与效率的衡权和技术生态与红利的思考。
对新技术的态度
伴鱼对新技术的态度是十分踊跃的,如果业务场景须要的新技术咱们都会去理解它、钻研它和把握它,咱们置信咱们对新技术趋势的判断能力和掌控能力,所以在 TiDB 和 MySQL 的选型的过程中,MySQL 的确是十分稳的抉择,并且对咱们的需要目前都有现成的解决方案,比方高可用,比方程度扩大能力,只不过不是十分优雅的解决方案,然而 TiDB 无论是实践层面和架构层面都比 MySQL 高出一个时代(MySQL 是面向单机数据库设计的,是这个畛域十分优良的数据库,只是当初伴鱼想要解决的是单机无奈存储的海量数据场景,在这个维度上比拟的确 TiDB 更好一些,然而这并不是 MySQL 的问题,是因为它们的设计指标不同而已),然而稳定性和成熟度会比 MySQL 要差一些,这个时候,咱们抉择置信咱们对 NewSQL 技术方向的判断力和掌控力,置信 TiDB 的进化能力,置信工夫站在咱们这边,让子弹再飞一会。
技术后发优势的了解
伴鱼在之前用的数据库是 MongoDB,MySQL 和 TiDB 都没有用过,如果咱们判断 TiDB 更面向未来的数据库,那么咱们是先从 MySQL 开始,走一遍 MySQL 的路线,在前面可预感的将来再迁徙到 TiDB 上来;还是间接深入研究和把握 TiDB,间接 All in TiDB?
初创公司在技术积淀和积攒上是远远不迭一些成熟公司的,这些积淀和积攒就是成熟公司在技术上的先发劣势,当技术没有呈现改革的时候咱们没有抉择,然而当技术正呈现重大改革的时候,如果咱们还做同样的技术选型,那么也须要花同样的工夫和老本能力达到成熟公司的程度,而后等大家都开始迁徙到新的技术上的时候,这些技术积淀和积攒就可能会变成技术债权。
所以初创公司应该去预判技术趋势,抉择面向未来的技术,在技术上弯道超车,防止本人的技术债权,这个是伴鱼技术团队对技术后发优势的了解。
老本与效率的衡权
老本和效率是技术选型绕不过的关键点,对于数据库来说更是如此,因为数据库须要的机器等资源老本会占总资源老本的很大一部分,所以伴鱼技术团队在 TiDB 和 MySQL 做抉择的时候,对老本与效率进行了深度的评估。
Unix 哲学是通过工夫和实际的锻炼设计准则,很多时候也是伴鱼技术团队的实际准则,比方 Rule of Economy:「宁花机器一分,不花程序员一秒」。在技术选型上,咱们是总是冀望根底软件做更多的事件,业务研发做更少的事件,如果业务研发须要在业务层去做本来根底软件应该做好的事件,那其实就是根底软件的形象透露了。如果根底软件形象透露,必然会导致业务层反复去解决这个问题,这个其实是十分大的隐性老本。
MySQL 相比拟 TiDB 而言,集群的高可用和大表须要分库分表其实就是 MySQL 在对面以后需要的形象透露,MySQL 的集群高可用须要 DBA 和基础架构团队花老本去解决,MySQL 的大表分库分表计划须要 DBA、基础架构团队和业务研发团队花老本去解决,只不过这些都是隐性老本,不像在搭建数据库集群的时候,TiDB 比 MySQL 可能须要更多的机器来的简略间接,所以很容易被忽略了。
所以,对于老本与效率的衡权,伴鱼技术团队更关注工程师的效率,更关注工程师的情绪(在业务下层反复解决一些底层软件形象透露的问题是很影响情绪的),更关注隐性老本,而不仅仅是账面显著能够比拟的资源数字,特地是在机器越来越便宜,人才越来越值钱的趋势下。
技术生态与红利的思考
抉择一个技术,其实也是抉择了这个技术的生态,如果技术生态欠缺,做事件往往会事倍功半,极大地提高研发效率。TiDB 在这个方面做的十分好,全面兼容 MySQL 协定,让 TiDB 的用户享受到 NewSQL 的能力的同时也享受到 MySQL 的生态,这个是十分正确的决定,MySQL 生态是几十年的积攒,不是久而久之能够做到的。
另一方面,在抉择面向未来、优雅高效的解决方案,还是抉择成熟的但不够优雅和高效的解决方案,如果抉择成熟的解决方案,对技术的掌控会比拟高,然而会在效率方面继续的进行付出;如果抉择面向未来的解决方案,须要花工夫和精力来把握新技术,然而新技术会优雅和高效的解决问题,咱们认为这个就是技术的红利。比方对于大表的解决方案,MySQL 提供的解决方案是分库分表,业务研发和 DBA 一起配合十分低效地解决这个问题,然而对于 NewSQL 的 TiDB,单表简直能够了解为无限大的(业界曾经存在 100 亿以上的表),从根本上解决了这个问题。当初伴鱼的大表都从 MongoDB 迁徙到 TiDB 下面,业务研发和 DBA 不再为数据的减少而不停地进行分库分表,这个就是微小的技术红利。
所以,基于下面的一些探讨与思考,伴鱼决定 All in TiDB,MongoDB 不再减少新的库和表,正在应用 MongoDB 的业务持续应用,并且对 MongoDB 上的大表进行有打算的迁徙,防止进行分库分表操作。
踩过的坑
在齐全把握一项新技术前,享受新技术的红利是有代价的,特地是伴鱼在 TiDB 比拟晚期的时候就决定 All in,这很考验技术团队的学习和进化能力、新技术的社区和官网提供的技术支持的能力。在 TiDB 这件事件上,伴鱼技术团队和 TiDB 的技术支持团队都做的十分优良了,然而咱们从 TiDB 1.x 到目前的 3.x 的过程中仍然还是踩了一些坑。
优化器抉择索引问题
单表数据 30W+,查问申请并发约 10+,某次业务上线,新增一个索引后,导致原有的查问索引抉择谬误,TiKV 实例所在机器 cpu 迅速被打满,引发故障。
线上某张大表,申请量比拟大,偶然呈现个别条件走不到索引,导致全表扫描,从而引发接口响应工夫的抖动,影响业务。
线上某张 14 亿的大表,查问条件区分度很高,某天呈现特定条件忽然走不到索引,导致全表扫描,引发故障。前面通过 TiDB 同学排查,系 bug 导致。
优化器抉择索引问题,TiDB 从 1.x 到 3.x 的过程中,优化器体现越来越好,同时伴鱼 DBA 团队通过性能监控和慢日志监控提前疾速地发现问题,并且对大表采纳强制索引的形式防止隐患,目前这个问题曾经比拟彻底的解决了。
大数据同步问题
为了进行数据分析,咱们把上游各 TiDB 集群的数据通过 Pump / Drainer 汇聚到一个 TiDB 集群供大数据分析应用,在应用过程中,遇到数据不统一、数据同步慢和编码不统一导致同步失败等问题。
随着伴鱼的 DBA 团队深度钻研 TiDB 并且和 TiDB 的同学进行继续的深刻沟通,目前对 TiDB 的掌控力越来越强,大数据同步问题目前曾经失去解决。
当初的状况
当初伴鱼有 10 套 TiDB 数据库,110+ 数据库实例,6 个 TPS 过万外围集群,999 线根本维持在 16ms 左右,响应工夫和稳定性都达到预期。从目前的状况来看,伴鱼抉择 TiDB 是一次十分正确的抉择,咱们在数据库技术方面弯道超车,防止了对 MySQL 技术的反复建设与积攒,享受了 NewSQL 数据库 TiDB 在高可用和程度扩大等方面的技术红利,大大提高了业务研发和 DBA 的工作效率。 当然,这是伴鱼技术团队(特地是 DBA)和 TiDB 技术团队共同努力的后果。
这里还要特地提一点,TiDB 每一次版本升级都会带来惊喜,这是一个能够继续享受的技术红利。
写在前面的话
目前,在摩尔定律生效、业务的高可用要求和老本优化等综合的大环境下,分布式架构是技术潮流的大势所趋,流量路由策略加多正本部署(微服务是其中的一种架构模式)解决了无状态服务的分布式架构问题,Redis Cluster 和 Codis 等计划解决了缓存的分布式架构问题,Kubernetes 实现了操作系统的分布式进化,数据库畛域天然也不会例外,它的分布式架构趋势肯定是不可阻挡的。要特地阐明一下,这里所说的解决问题是指系统性的解决问题,MySQL 业务侵入式的分库分表的确是一个能够解决问题的分布式架构计划,然而须要业务研发配合一个业务场景一个业务场景的去解决,这就不能称之为系统性的解决方案,因为在解决这个问题形式上,业务侵入式的分库分表计划将本应由数据库解决好的大表形象透露给业务层了,在这个问题上,咱们认为 NewSQL 是一个系统性的解决方案,而 TiDB 就是当下十分不错的一个抉择。
另外还须要阐明一点的是,这是一篇数据库选型的文章,所以只记录了与之相干的内容,比方详细描述了伴鱼技术团队在将数据库迁徙到 TiDB 后踩的坑,因为这是咱们数据库选型 TiDB 付出的代价,所以肯定要具体记录;没有记录在应用其余数据库踩的坑,这并不代表咱们没有踩到,比方在应用 MongoDB 的过程中也踩过一些坑,然而因为这并不是咱们决定从新做数据库选型的起因(决定从新选型的起因见文章「为什么放弃 MongoDB」局部),所以就没有在文章中记录。
本文转载自 InfoQ 微信公众号,点击查看原版文章《咱们为什么放弃 MongoDB 和 MySQL,抉择 TiDB》。