智湖,在古典汉语中意为”你知道吗?” ,是中国的Quora:一个问答网站,由用户社区创建、回答、编辑和组织各种问题。作为中国最大的知识共享平台,我们目前拥有2.2亿注册用户,3000万问题,超过1.3亿个答案。
随着用户群的增长,我们应用程序的数据量也逐渐增长。我们的 Moneta 应用程序中存储了大约 1.3 万亿行数据(存储用户已经阅读的帖子)。每月累积大约 1000 亿行数据,并且还在增长,这个数字将在两年内达到 3 万亿。我们在扩展后端同时保持良好的用户体验方面面临着严峻的挑战。
您可能还喜欢:大数据和分析集成。
在本文中,我将深入探讨我们如何在如此大量的数据上保持几毫秒的查询响应时间,以及 TiDB(一个开源与 MySQL 兼容的 NewSQL 混合事务/分析处理(HTAP)数据库如何授权我们获取我们数据的实时洞察。我将介绍我们选择 TiDB 的原因、如何使用它、我们学到了什么、最佳实践以及对未来的一些想法。
我们的痛点
本节介绍我们的 Moneta 应用程序的体系结构、我们尝试构建的理想体系结构以及数据库可扩展性作为我们的主要痛点。
系统架构要求
志虎的后馈送服务是一个关键的系统,通过该系统,用户接触到网站上发布的内容。在后端的 Moneta 应用程序存储用户已阅读和过滤出这些帖子在智湖的建议页面的帖子流。
Moneta 应用程序具有以下特征:
- 数据要求高可用性:后馈送是第一个显示的屏幕,它在推动用户流量到智湖中起着重要的作用。
- 处理巨大的写入数据:例如,高峰时间每秒写入超过 4000 个记录,记录数量每天增加近 30 亿条记录。
- 长期存储历史数据:目前,系统中存储了大约1.3万亿条记录。每月累积约1000亿条记录,并且还在增长,历史数据将在大约两年内达到3万亿条记录。
- 处理高通量查询:在高峰时间,系统处理每秒平均对 1200 万个帖子执行的查询。
- 将查询的响应时间限制为 90 毫秒或更少:这甚至发生在长尾查询中,执行时间最长也是如此。
- 容忍误报:这意味着系统可以为用户回忆许多有趣的帖子,即使有些帖子被错误过滤掉。
考虑到上述事实,我们需要一个具有以下功能的应用程序体系结构:
- 高可用性:当用户打开智虎的建议页面时,发现大量已阅读的帖子是糟糕的用户体验
探索
为了构建具有上述功能的理想体系结构,我们在以前的体系结构中集成了三个关键组件:
- 代理:这将用户的请求转发到可用的节点,并确保系统的高可用性。
- 缓存:这暂时处理内存中的请求,因此我们并不总是需要处理数据库中的请求。这提高了系统性能。
- 存储:在使用TiDB之前,我们在独立的MySQL上管理我们的业务数据。随着数据量的飙升,独立的 MySQL 系统是不够的。然后,我们采用了MySQL 分片和主高可用性管理器(MHA) 的解决方案,但当每月有 1000 亿条新记录涌入我们的数据库时,这个解决方案是不可取的。
MySQL 碎片和 MHA 的缺点
MySQL 分片和 MHA 不是一个好的解决方案,因为 MySQL 分片和 MHA 都有其缺点。
MySQL 分片的缺点
- 应用程序代码变得复杂且难以维护。
- 更改现有的分片键是麻烦的。
- 升级应用程序逻辑会影响应用程序的可用性。
MHA 的缺点
- 我们需要通过编写脚本或使用第三方工具来实现虚拟 IP (VIP) 配置。
- MHA 仅监视主数据库。
- 要配置 MHA,我们需要配置无密码安全外壳 (SSH)。这可能会导致潜在的安全风险。
- MHA 不为从服务器提供读取负载平衡功能。
- MHA 只能监视主服务器(而不是从主服务器)是否可用。
在找到 TiDB 并将数据从 MySQL 迁移到 TiDB 之前,数据库可伸缩性仍然是整个系统的弱点。
什么是 TiDB?
TiDB 平台是组件的集合,当一起使用时,这些组件将成为具有 HTAP 功能的 NewSQL 数据库。
在 TiDB 平台内,主要组件如下:
- TiDB 服务器是一个无状态 SQL 层,用于处理用户的 SQL 查询、访问存储层中的数据并将相应的结果返回给应用程序。它与 MySQL 兼容,位于 TiKV 的顶部。
- TiKV 服务器是数据持续存在的分布式事务键值存储层。它使用Raft共识协议进行复制,以确保强大的数据一致性和高可用性。
- TiSpark群集也位于 TiKV 的顶部。它是一个 Apache Spark 插件,与 TiDB 平台配合使用,支持商业智能 (BI) 分析师和数据科学家的复杂在线分析处理 (OLAP) 查询
com/pingcap/pd”rel=”nofollow”目标\”\blank”_放置驱动程序(PD)服务器是由etcd支持的元数据群集,用于管理和调度TiKV。
除了这些主要组件之外,TiDB 还拥有一系列工具,例如用于快速部署的Ansible 脚本、用于从 MySQL 迁移的同步和TiDB 数据迁移以及用于收集逻辑更改的TiDB Binlog向 TiDB 群集提供增量备份和复制到下游(TiDB、Kafka 或 MySQL)。
TiDB 的主要功能
TiDB 的主要功能包括:
- 水平可扩展性。
- MySQL 兼容语法。
- 具有强一致性的分布式事务。
- 云原生体系结构。
- 使用HTAP最小提取、 转换 、 负载 (ETL).
- 容错和通过 Raft 恢复。
- 在线架构更改。
我们如何使用 TiDB
在本节中,我将向您展示 TiDB 如何在 Moneta 的体系结构中运行,以及其针对 Moneta 应用程序的性能指标。
TiDB 在我们的体系结构中
我们在系统中部署了 TiDB,Moneta 应用程序的整体体系结构变成了:
- 顶层:无状态和可扩展的客户端 API 和代理。这些组件易于横向扩展。
- 中间层:软状态组件和分层Redis缓存作为主要部分。当服务崩溃时,这些组件可以通过还原保存在 TiDB 群集中的数据来自我恢复服务。
- 底层:TiDB 群集存储所有有状态数据。其组件是高度可用的,如果节点崩溃,它可以自行恢复其服务。
在此系统中,所有组件都是可自行恢复的,整个系统具有全局故障监控机制。然后,我们使用Kubernetes来协调整个系统,以确保整个服务的高度可用性。
TiDB 的性能指标
由于我们在生产环境中应用了 TiDB,我们的系统高度可用且易于扩展,并且系统性能显著提高。
例如,在 2019 年 6 月为 Moneta 应用程序提供一组性能指标:
高峰时间每秒写入 40,000 行数据。
高峰时间每秒检查30 000个查询和1 200万个员额cheeli.com.cn/wp-content/uploads/2019/09/12375728-queries-and-posts-examined-per-second-at-peak-time.png”标题=”每秒检查的查询数(千次)”宽度=”300″/*
第 99 个百分位响应时间约为 25 毫秒,第 999 百分位响应时间约为 50 毫秒。事实上,平均响应时间远低于这些数字,即使对于需要稳定响应时间的长尾查询也是如此。
我们学到的
我们迁移到 TiDB 并非一帆风顺。在这里,我们想分享一些经验教训。
更快地导入数据
我们使用 TiDB 数据迁移 (DM) 来收集 MySQL 增量 binlog 文件,然后使用TiDB 闪电快速将数据导入 TiDB 群集。
令我们惊讶的是,仅用了四天时间就将这些1.1万亿条记录导入到TiDB。如果我们从逻辑上将数据写入系统,则可能需要一个月或更长时间。如果我们有更多的硬件资源,我们本来可以更快地导入数据。
减少查询延迟
完成迁移后,我们测试了少量读取流量。当 Moneta 应用程序首次联机时,我们发现查询延迟不符合我们的要求。为了解决延迟问题,我们与 PingCap 工程师合作来调整系统性能。
在此过程中,我们积累了宝贵的数据和数据处理见解:
- 有些查询对查询延迟很敏感,有些则不敏感。我们部署了单独的 TiDB 数据库来处理对延迟敏感的查询。(其他不区分延迟的查询在不同的 TiDB 数据库中处理。这样,大型查询和延迟敏感的查询在不同的数据库中处理,并且前者的执行不会影响后者。
- 对于没有理想执行计划的查询,我们编写 SQL 提示以帮助执行引擎选择最佳执行计划。
- 我们使用低精度时间戳 Oracle (TSO) 和准备语句来减少网络往返。
评估资源
在尝试 TiDB 之前,我们未分析需要多少硬件资源来支持 MySQL 端的相同数量的数据。为了降低维护成本,我们在单个主和单从拓扑中部署了 MySQL。相反,在 TiDB 中实现的Raft协议至少需要三个副本。因此,我们需要更多的硬件资源来支持 TiDB 中的业务数据,并且我们需要提前准备计算机资源。
一旦我们的数据中心设置得当,我们就可以快速完成对 TiDB 的评估。
对 TiDB 3.0 的期望
在志湖,反垃圾邮件和莫内塔应用程序的架构是一样的。我们试过泰坦0 (TiDB 3.0.0-rc.1和TiDB 3.0.0-rc.2) 在我们的反垃圾邮件应用程序中用于生产中的数据。
泰坦减少延迟
反垃圾邮件应用程序总是受到查询和写入的高延迟的折磨。
我们听说TiDB 3.0将引入Titan,一个键值存储引擎,以减少在RocksDB(TiKV中的基础存储引擎)中的写入放大。
为了尝试此功能,我们在 TiDB 3.0.0-rc.2 发布后启用了 Titan。下图显示了与 RocksDB 和 Titan 相比,写入和查询的延迟:
统计数据显示,启用 Titan 后,写入和查询延迟都急剧下降。太惊人了!当我们看到统计数字时,我们简直不敢相信自己的眼睛。
表分区改进了查询性能
我们还在反垃圾邮件应用程序中使用了 TiDB 3.0 的表分区功能。使用此功能,我们可以按时间将表划分为多个分区。当查询出现时,它将在覆盖目标时间范围的分区上执行。这大大提高了我们的查询性能。
让我们考虑一下,如果我们将来在 Moneta 和反垃圾邮件应用程序中实现 TiDB 3.0,会发生什么情况。
莫内塔应用程序中的 TiDB 3.0
TiDB 3.0 具有 gRPC 中的批处理消息、多线程 Raftstore、SQL 计划管理和 TiFlash 等功能。我们相信,这些将增加光泽的莫内塔应用程序。
gRPC 和多线程筏存储中的批处理消息
Moneta 的写入吞吐量超过每秒 40 000 个事务 (TPS)。TiDB 3.0 可以批量发送和接收 Raft 消息,并且它可以在多个线程中处理区域 Raft 逻辑。我们相信这些功能将显著提高我们系统的并发能力。
SQL 计划管理
如上所述,我们编写了相当多的 SQL 提示,以使查询优化器选择最佳执行计划。TiDB 3.0 添加了一个 SQL 计划管理功能,该功能直接在 TiDB 服务器中将查询绑定到特定的执行计划。使用此功能,我们不需要修改查询文本来注入提示。
TiFlash
在 TiDB DevCon 2019 上,我第一次听说了 TiFlash,一个用于 TiDB 的扩展分析引擎。它采用面向列的存储技术来实现较高的数据压缩率,并在数据复制中应用扩展的Raft共识算法,以确保数据安全。
由于我们拥有具有高写入吞吐量的海量数据,因此我们负担不起每天使用 ETL 将数据复制到Hadoop进行分析的费用。但是,使用 TiFlash,我们乐观地认为,我们可以轻松分析我们巨大的数据量。
反垃圾邮件应用程序中的 TiDB 3.0
与 Moneta 应用程序庞大的历史数据大小相比,反垃圾邮件应用程序具有更高的写入吞吐量。但是,它只查询过去 48 小时内存储的数据每天5TB。
由于 TiDB 3.0 可以批量发送和接收 Raft 消息,并且它可以在多个线程中处理区域 Raft 逻辑,因此我们可以用更少的节点来管理应用程序。以前,我们使用 7 个物理节点,但现在我们只需要 5 个物理节点。即使我们使用商用硬件,这些功能也能提高性能。
下一步
TiDB 是一个与 MySQL 兼容的数据库,因此我们可以像使用 MySQL 一样使用它。由于 TiDB 的水平可扩展性,现在即使我们有超过一万亿条记录需要处理,我们也可以自由扩展数据库。
到目前为止,我们已经在我们的应用程序中使用了相当多的开源软件。我们还学到了很多关于处理TiDB的系统问题的知识。我们决定参与开源工具的开发,并参与社区的长期成长。在我们与PingCAP的共同努力下,TiDB将变得更加强大和强大。