知乎,意思是“你知道吗?”在文言文中,是中国的Quora,一个问答网站,用户社区可以在这里创建、回答、编辑和组织各种问题。图片来自Pexels作为中国最大的知识共享平台,我们目前拥有2.2亿注册用户,网站上有3000万个问题和超过1.3亿个答案。随着用户群的增长,我们的应用程序的数据量已经无法承受。我们的Moneta应用程序中存储了大约1.3万亿行数据(存储用户已阅读的帖子)。每月累计产生约1000亿行数据并且还在不断增长,这个数字将在两年内达到3万亿行。在保持良好用户体验的同时,我们在扩展后端方面面临严峻挑战。在本文中,我将深入探讨如何在如此大的数据量上保持毫秒级的查询响应时间,以及开源的MySQL兼容NewSQL混合事务/分析处理(HTAP)数据库TiDB如何支持我们实时了解我们的数据。我将介绍我们选择TiDB的原因、我们如何使用它、我们学到了什么、最佳实践以及对未来的一些想法。我们的痛点本节介绍我们Moneta应用程序的架构,我们尝试构建的理想架构,以及作为我们主要痛点的数据库可扩展性。系统架构需求知乎的PostFeed服务是用户接收网站发布内容的关键系统。后台的Moneta应用存储用户阅读过的帖子,并在知乎推荐页面的帖子流中过滤掉这些帖子。Moneta应用程序具有以下特征:需要高可用性数据:发布消息是出现的第一个屏幕,它在推动知乎用户流量方面发挥着重要作用。处理海量写入数据:例如高峰期每秒写入4万多条记录,每天增加近30亿条记录。历史数据长期存储:目前系统中存储了约1.3万亿条记录。每月约1000亿条记录,并且还在不断增长,大约两年后,历史数据将达到3万亿条记录。处理高吞吐量查询:在高峰时段,系统处理平均每秒执行1200万个帖子的查询。将查询的响应时间限制在90毫秒或更短:即使对于执行时间最长的长尾查询,也会发生这种情况。容忍误报:这意味着系统可以为用户拉出许多有趣的帖子,即使有些帖子被错误地过滤掉了。考虑到以上事实,我们需要一个具有以下特点的应用架构:高可用性:当用户打开知乎的推荐页面时,发现大量已阅读的帖子是一种糟糕的用户体验。出色的系统性能:我们的应用具有高吞吐量和严格的响应时间要求。易于扩展:我们希望我们的系统能够随着业务的增长和应用程序的增长而轻松扩展。探索为了构建具有上述功能的理想架构,我们在之前的架构中集成了三个关键组件:Proxy:它将用户的请求转发到可用的节点上,保证系统的高可用性。缓存:这暂时在内存中处理请求,所以我们并不总是需要在数据库中处理请求。这可以提高系统性能。存储:在使用TiDB之前,我们在单独的MySQL上管理我们的业务数据。随着数据量的爆炸式增长,一个独立的MySQL系统是不够的。然后我们采用了MySQLsharding和MasterHighAvailabilityManager(MHA)的解决方案,但是当每月有1000亿条新记录涌入我们的数据库时,这种解决方案并不可取。MySQLSharding和MHA的缺点MySQLsharding和MHA都不是一个好的解决方案,因为MySQLsharding和MHA都有它们的缺点。MySQL分片的缺点:应用代码变得复杂,难以维护。更改现有的分片键很麻烦。升级应用程序逻辑会影响应用程序可用性。MHA的缺点:我们需要通过编写脚本或使用第三方工具来实现虚拟IP(VIP)配置。MHA只监控主数据库。要配置MHA,我们需要配置PasswordlessSecureShell(SSH)。这可能会导致潜在的安全风险。MHA不提供从服务器的读负载均衡。MHA只能监控master(不是slave)的可用性。在我们发现TiDB并将数据从MySQL迁移到TiDB之前,数据库的可扩展性仍然是整个系统的弱点。什么是TiDB?TiDB平台是一组组件,当它们一起使用时,将成为具有HTAP功能的NewSQL数据库。TiDB平台架构在TiDB平台内部,主要组件如下:TiDB服务器是一个无状态的SQL层,处理用户SQL查询,访问存储层的数据,并将相应的结果返回给应用程序。它与MySQL兼容并位于TiKV之上。TiKV服务器是数据持久化的分布式事务键值存储层。它使用Raft共识协议进行复制,以确保数据的强一致性和高可用性。TiSpark集群也位于TiKV之上。它是一个ApacheSpark插件,可与TiDB平台配合使用,为商业智能(BI)分析师和数据科学家支持复杂的在线分析处理(OLAP)查询。PlacementDriver(PD)服务器是一个由etcd支持的元数据集群,用于管理和调度TiKV。除了这些主要组件之外,TiDB还有一个工具生态系统,比如用于快速部署的Ansible脚本,用于从MySQL迁移的Syncer,以及TiDB数据迁移。TiDBBinlog用于收集对TiDB集群所做的逻辑更改并提供增量备份。复制到下游(TiDB、Kafka或MySQL)。TiDB的主要特性包括:横向可扩展性。MySQL兼容语法。具有强一致性的分布式事务。云原生架构。使用HTAP的最小提取、转换、加载(ETL)。容错和Raft恢复。在线架构更改。我们如何使用TiDB在本节中,我将向您展示如何在Moneta的架构中运行TiDB以及Moneta应用程序的性能指标。TiDBinourarchitecture知乎Moneta应用中的TiDB架构我们在系统中部署了TiDB,Moneta应用的整体架构变为:顶层:无状态可扩展的客户端API和代理。这些组件很容易扩展。中间层:以软态组件和分层Redis缓存为主。当服务中断时,这些组件可以通过恢复保存在TiDB集群中的数据来自我恢复服务。底层:TiDB集群存储所有有状态数据。它的组件具有高可用性,如果节点崩溃,它可以自行恢复其服务。在该系统中,所有组件都具有自愈性,整个系统具有全局故障监控机制。然后,我们通过Kubernetes来协调整个系统,保证整个服务的高可用。TiDB性能指标自从我们在生产环境中应用TiDB以来,我们的系统具有高可用性和易扩展性,系统性能得到了显着提升。例如,2019年6月,Moneta应用程序采用了一组性能指标。高峰时段每秒写入40,000行:每秒写入的行数(千)高峰时段每秒检查30,000个查询和1200万个帖子:每秒写入的行数second(thousands)99th百分位响应时间大约为25ms,第999个百分位响应时间大约为50ms。实际上,平均响应时间远小于这些数字,即使对于需要稳定响应时间的长尾查询也是如此。99thPercentileResponseTime999thPercentileResponseTimeWhatWeLearned我们迁移到TiDB并不顺利,在这里我们想分享一些经验教训。导入数据更快我们使用TiDBDataMigration(DM)收集MySQL增量Binlog文件,然后使用TiDBLightning快速将数据导入TiDB集群。令我们惊讶的是,将这1.1万亿条记录导入TiDB仅用了4天时间。如果我们按逻辑将数据写入系统,可能需要一个月或更长时间。如果我们有更多的硬件资源,我们可以更快地导入数据。减少查询延迟迁移完成后,我们测试了少量读取流量。当Moneta应用刚上线时,我们发现查询延迟不符合我们的要求。为了解决延迟问题,我们与PingCap工程师合作调整系统性能。在此过程中,我们积累了宝贵的数据和数据处理知识:一些查询对查询延迟敏感,而另一些则不敏感。我们部署了一个单独的TiDB数据库来处理对延迟敏感的查询。(其他非延迟敏感的查询在不同的TiDB数据库中处理。)这样,大查询和延迟敏感的查询在不同的数据库中处理,前者的执行不会影响后者。对于没有理想执行计划的查询,我们编写SQL提示帮助执行引擎选择最佳执行计划。我们使用低精度时间戳Oracle(TSO)和准备好的语句来减少网络往返。评估资源在我们尝试TiDB之前,我们并没有分析在MySQL端支持相同数量的数据需要多少硬件资源。为了降低维护成本,我们采用单主单从拓扑部署MySQL。相比之下,TiDB中实现的Raft协议至少需要三个副本。因此,我们需要更多的硬件资源来支撑TiDB中的业务数据,需要提前准备好机器资源。一旦我们的数据中心搭建好了,我们就可以快速完成对TiDB的评估。对TiDB3.0的期待在知乎,反垃圾和Moneta应用具有相同的架构。我们在生产数据的反垃圾邮件应用程序中尝试了TiDB3.0候选版本(TiDB3.0.0-rc.1和TiDB3.0.0-rc.2)中的Titan和TablePartition。①Titan降低延迟反垃圾邮件应用程序一直受到严重查询和写入延迟的困扰。听说TiDB3.0会引入Titan,一个key-value存储引擎,用于减少RocksDB(TiKV中的底层存储引擎)在使用大值时的写放大。为了尝试这个特性,我们在TiDB3.0.0-rc.2发布后启用了Titan。下图分别显示了与RocksDB和Titan相比的写入和查询延迟:这真太了不起了!当我们看到统计数据时,我们简直不敢相信自己的眼睛。②分表提高查询性能我们在反垃圾应用中也使用了TiDB3.0的分表特性。利用这个特性,我们可以按时间将表拆分成分区。当查询进来时,它将在覆盖目标时间范围的分区上执行。这大大提高了我们的查询性能。让我们考虑一下如果我们将来在Moneta和反垃圾邮件应用程序中实现TiDB3.0会发生什么。③Moneta应用中的TiDB3.0TiDB3.0具有gRPC中的批处理消息、多线程Raftstore、SQL计划管理、TiFlash等特性。我们相信这些将为Moneta应用程序增光添彩。④gRPC和多线程Raftstore中的批量消息Moneta的写入吞吐量超过每秒40,000个事务(TPS),TiDB3.0可以批量发送和接收Raft消息,并且可以在多线程中处理RegionRaft逻辑。我们相信这些特性将显着提高我们系统的并发能力。⑤SQL计划管理如前所述,我们编写了大量的SQL提示,使查询优化器能够选择最佳的执行计划。TiDB3.0增加了SQL计划管理功能,可以直接将查询绑定到TiDB服务器中的具体执行计划。使用此功能,我们无需修改查询文本即可注入提示。⑥TiFlash在TiDBDevCon2019上,我第一次听说TiFlash是TiDB的扩展分析引擎。采用面向列的存储技术实现数据的高压缩比,在数据复制中应用扩展的Raft共识算法保证数据安全。由于我们的数据量大,写吞吐量高,所以我们不能每天用ETL把数据拷贝到Hadoop中进行分析。但是有了TiFlash,我们很乐观地认为我们可以轻松地分析我们庞大的数据量。⑦TiDB3.0在反垃圾应用中的应用相对于Moneta应用庞大的历史数据规模,反垃圾应用具有更高的写入吞吐量。但是,它只查询过去48小时内存储的数据。在此应用程序中,数据每天增长80亿条记录和1.5TB。由于TiDB3.0可以批量收发Raft消息,并且可以多线程处理RegionRaft逻辑,我们可以用更少的节点来管理应用。以前,我们使用七个物理节点,但现在我们只需要五个。即使我们使用商用硬件,这些功能也能提高性能。What'snextTiDB是一个MySQL兼容的数据库,所以我们可以像MySQL一样使用它。得益于TiDB的水平扩展能力,现在我们可以自由扩展我们的数据库,即使我们有超过一万亿的记录要应对。到目前为止,我们已经在我们的应用程序中使用了相当多的开源软件。我们也学到了很多关于使用TiDB来处理系统问题的知识。我们决定参与开源工具的开发,参与社区的长远发展。基于我们与PingCAP的共同努力,TiDB将变得更加强大。作者:孙晓光简介:知乎搜索后台负责人,目前负责知乎搜索后台架构设计和工程团队管理。多年从事私有云相关产品开发,专注云原生技术,TiKV项目committer。
