paint-brush
Delhivery 的数据集市 - 从 OLTP 到 HTAP 的迁移之旅经过@datadelhivery
1,018 讀數
1,018 讀數

Delhivery 的数据集市 - 从 OLTP 到 HTAP 的迁移之旅

经过 Delhivery9m2023/09/20
Read on Terminal Reader

太長; 讀書

Delhivery 是印度领先的履行平台,在管理用于运营决策的大量实时数据方面面临挑战。他们将数据集市从 Amazon Aurora 迁移到 TiDB(一种混合事务/分析处理 (HTAP) 数据库),以克服可扩展性、数据完整性和延迟问题。 TiDB 的架构将计算与存储分离,提供轻松扩展、ACID 合规性、高可用性和实时分析。 Delhivery 的 TiDB 基础设施跨越多个可用区,并经过关键调整以获得最佳性能。他们报告了查询性能的提高、数据迁移的简便性以及 PingCAP 的强大支持。事实证明,TiDB 在处理 Delhivery 实时数据集市的高数据吞吐量要求方面非常有效。
featured image - Delhivery 的数据集市 - 从 OLTP 到 HTAP 的迁移之旅
Delhivery HackerNoon profile picture
0-item

作为印度领先的数字商务履行平台,Delhivery 每年 365 天、每天履行 100 万个包裹。得益于庞大的物联网设备网络,其 24 个自动分拣中心、101 个枢纽、3,100 多个直接配送中心、1000 多个合作伙伴中心、11,000 多个车队和 60,000 多名团队成员平稳运行。每秒有数千个数据事件和消息进出我们的管道。这相当于每天以 TB 为单位的海量数据量,这使得运营可见性对于我们和我们的利益相关者至关重要。


认识到这些需求,我们决定构建数据集市——集中的、最终一致的数据库,使用户能够快速访问预先聚合的业务数据。这使我们的利益相关者能够快速访问业务见解,而无需搜索整个数据仓库。


然而,由于规模如此巨大,主要挑战之一是在提供分析工作负载容量的同时保持数据完整性和低延迟。


在这篇博客中,我将在将数据集市从 Amazon Aurora 迁移到 TiDB(一种混合事务/分析处理 (HTAP) 分布式 SQL 数据库)时阐述我的所有想法。希望这篇文章能为正在考虑向 TiDB 或任何其他 HTAP 数据库进行类似迁移的数据工程领导者、数据库管理员或数据架构师提供见解。


OLTP、OLAP 和 HTAP

为了更好地理解 Delhivery 的实时数据集市案例,我们首先熟悉我们用例的核心三个概念:OLTP、OLAP 和 HTAP:

  • OLTP:在线事务处理(OLTP)系统专为面向事务的应用程序而设计,通过ACID(原子性、一致性、隔离性、持久性)属性确保数据完整性。
  • OLAP:在线分析处理 (OLAP) 系统可以对大量数据进行高速、多维分析,有助于数据驱动的决策。
  • HTAP:混合事务/分析处理 (HTAP) 结合了 OLTP 和 OLAP 功能,允许对事务数据进行实时分析。


Delhivery 的实时数据集市用例

实时数据集市与传统数据集市的不同之处在于,它们实时获取数据,而不是按照特定的时间间隔。这些数据集市对于 Delhivery 的地面运营决策至关重要,因为我们不能承受同步这些事件的任何延迟。


我们的实时数据集市之旅始于 2020 年,当时我们发现需要集中式仪表板,特别是 EYE 仪表板。该仪表板的目的是为地面操作提供实时操作可见性,从而能够根据最新数据做出决策。用法示例包括:

  • 车辆规划和可见性:实时监控 Delhivery 枢纽的进出连接时间表。
  • 绩效跟踪: Delhivery 设施的持续绩效跟踪。
  • 集中控制可视性:为中央团队提供有关地面障碍物的精确信息,以采取适当的行动。这些可能是由于各种因素造成的,例如中心性能下降、货运老化或传入和传出连接拥塞。
  • 合规性:跟踪放置和挑选合规性指标


初步实施和挑战

我们考虑使用 Redshift 和 Snowflake 等数据仓库工具来解决我们的用例,但考虑到设计模式以及实时数据摄取和合并的要求,这些解决方案都不适合我们。


因此,我们最初选择 Aurora (PostgreSQL) 来服务我们的数据集市用例。


Aurora 周围的数据摄取过程

我们使用 Spark Streaming 和 Aurora 构建了实时数据集市。我们的流处理管道非常简单——从 Kafka 读取数据,以 Spark 微批次处理数据,并在 Aurora 中执行更新插入操作。


我们的数据库使用多层架构进行建模,其中包含原始层、分区层和数据集市层。用户无权查看或修改原始层中的数据。保留分区层来维护所有分区表(一般是维度表)。下面是我们数据库的简单架构设计:



数据集市的多层架构




我们在 Aurora 方面面临的挑战

该系统最初运行良好,直到它必须处理每秒超过 3K 消息的吞吐量。这标志着几个挑战的开始:


  • 可扩展性限制:当我们超过每秒 3K 消息的吞吐量时,Aurora 的每秒输入/输出操作数 (IOPS) 限制成为瓶颈。可扩展性限制已经开始影响我们的运营。


  • 膨胀问题:每次记录更新都会导致创建新记录和死元组(记录的先前版本)。当这些死元组的生成速度超过清理过程时,就会发生膨胀。由于 VACUUM FULL 无法声明存储空间,因此磁盘使用率不断增加。对于大约 5 TB 的数据,Aurora 使用了 30+ TB 的存储。


  • 维护负担:膨胀问题与我们的维护挑战直接相关。由于有超过 70 个管道,总写入 QPS 超过 5k 条消息/秒,我们发现 PostgreSQL 的自动清理过程 Auto Vacuum 无法跟上死元组生成的速度。因此,需要手动运行VACUUM或VACUUM FULL来恢复数据库。我们对 pg_repack 和 pgcompacttable 等 PostgreSQL 工具的尝试也被证明是不成功的。因此,维护变得越来越复杂和耗时。



磁盘膨胀


  • 成本:为了适应读写工作负载,我们必须扩展到最高的可用节点 (24XLarge)。这导致三节点 Aurora 集群每月的支出约为 100,000 美元。在这种规模下,Aurora 由于 IOPS 自动扩展而变得昂贵。


寻找替代方案

为了解决 Aurora 的局限性,我们开始寻找满足以下要求的更好替代方案:

  • 高写入QPS可扩展:数据库应支持至少10k+写入QPS,并且可水平扩展。
  • 实时分析:数据库应能够提供高速或实时的OLAP能力
  • 完全分布式:数据库应分布在多个站点以提供高可用性和容错能力。
  • 强一致性:数据库应保持强一致性,保证所有用户看到相同的数据。


考虑到上述所有要求,我们最初探索了许多 PostgreSQL 替代方案,包括 Spanner 和 Yugabyte,因为我们希望将变更管理保持在最低限度。


扳手

Spanner 是 Google 提供的分布式 SQL 数据库管理和存储服务。它完全在 Google Cloud Platform (GCP) 上进行管理。然而,我们发现 Spanner 可能不适合我们的架构,原因如下:


  • Spanner 不支持架构。
  • 我们没有找到合适的工具来加载历史数据。我们探索了 Harbourbridge,一个用于 Spanner 评估和迁移的开源工具。然而,它有大约 100 GB 数据加载的限制。


尤加字节

YugabyteDB 是由 Yugabyte 开发的用于云原生应用程序的高性能事务型分布式 SQL 数据库。该数据库非常接近我们的用例,因为它完全兼容 PostgreSQL、水平可扩展且完全分布式。不幸的是,由于其可扩展性的限制,它的工作效果不佳。我们的成功标准要求每秒处理 7k 以上的事务,但 Yugabyte 只能扩展到 5k。


我们还研究了其他可能的候选方案,例如 BigQuery,但它们都不能很好地满足我们的要求。


与 TiDB 落地

在上述 PostgreSQL 替代方案之后,我们决定将 HTAP 添加到我们的需求中,这导致我们选择了 TiDB。它支持开箱即用的可扩展性、一致性、可用性、多站点部署拓扑以及更多功能。 TiDB 作为一个分布式数据库,有多个组件相互通信,构成一个完整的 TiDB 系统。



TiDB 架构



  • TiDB:它是无状态 SQL 处理组件,为用户提供面向客户端的端点。它找到正确的 TiKV 节点从 PD 连接来获取数据。
  • TiKV:它是一个分布式事务型键值数据存储,将数据保持在左闭右开范围内。数据保存在具有多个副本的分片中。 TiKV 使用 Raft 协议进行复制。
  • PD:放置驱动程序(PD)保留集群的元数据,例如分片副本位置,并且它还负责跨 TiKV 节点调度分片。 PD 领导者处理此类任务,而其他节点则保持高可用性。
  • TiFlash:列式存储扩展,使用 Multi-Raft Learner 协议实时复制 TiKV 中的数据,保证 TiKV 行存储引擎之间数据的一致性。


TiDB 的以下功能解决了我们的关键挑战并满足了我们的运营需求:


  • 轻松扩展

    TiDB 架构设计将计算与存储分离,让您可以根据需要在线扩展或扩展计算或存储容量。扩展过程对于应用程序操作和维护人员来说是透明的。

  • 符合酸性

    TiDB 兼容 MySQL,并且支持开箱即用的事务。它支持乐观和悲观类型的交易。这使得它与其他数据库不同。

  • 高可用

    TiKV 将数据存储在多个副本中,并使用 Multi-Raft 协议来获取事务日志。仅当数据已成功写入大多数副本时才能提交事务。当少数副本出现故障时,这可以保证强一致性和高可用性。

  • 实时HTAP

    TiDB 将行存储 (TiKV) 和列存储 (TiFlash) 结合在同一架构中,形成了一个简化的技术堆栈,可以更轻松地对操作数据进行实时分析。


我们的 TiDB 基础设施

我们的 TiDB 基础设施部署在领先云服务提供商的虚拟机上。我们使用 TiDB 的包管理器 TiUP 来管理集群和所有管理操作。我们的集群部署在 3 个可用区域 (AZ) 上。


我们的集群配置如下:

  • PD: PD 层有 3 个节点,分布在多个可用区。 PD 领导者处理此类任务,而其他节点则保持高可用性。
  • TiDB: TiDB 层有 n2-highmem-8 系列的 9 个节点。这些节点是根据内存要求选择的,为每个 TiDB 节点分配了 64 GB RAM 和 8 核 CPU。
  • TiKV: TiKV 层有 n2-highmem-16 系列的 15 个节点,具有 128 GB RAM 和 16 个 vCORE CPU。


通过跨多个可用区部署 TiDB 集群并仔细选择节点类型来满足我们的处理和内存需求,我们创建了一个强大的、高度可用的基础设施,能够满足我们的高数据吞吐量要求。


针对我们的案例调整 TiDB

为了使其适用于我们的用例,我们与 PingCAP 团队密切合作来调整数据库。以下是我们做出的一些关键调整:


指数优化

在启动索引之前设置以下参数。

 SET @@global.tidb_ddl_reorg_worker_cnt = 16; SET @@global.tidb_ddl_reorg_batch_size = 4096;


创建索引后重置为默认值。

 SET @@global.tidb_ddl_reorg_worker_cnt = 4; SET @@global.tidb_ddl_reorg_batch_size = 256;


分区修剪

这对于分区表来说非常重要。它分析查询语句中的过滤条件,并在它们不包含任何所需数据时消除(修剪)分区。

 SET @@session.tidb_partition_prune_mode = 'dynamic';


调音分析

有时,如果摄入大量数据,TiDB 中的自动分析器会失败。在这种情况下,所有查询都可能使用错误的执行计划并最终扫描整个表。为了避免这种情况,我们对 TiDB 配置进行了以下更改:

 set global tidb_max_auto_analyze_time = 86400; set global tidb_enable_pseudo_for_outdated_stats = off; set global tidb_sysproc_scan_concurrency = 15;


如果您正在使用分区表,我们建议您一次针对一个分区手动运行分析表操作,以避免分析失败。


通过这样的调整,我们能够有效地简化 TiDB 的使用,从而使我们的实时数据集市达到最佳性能。


我们使用 TiDB 的经验

  • 改进的查询性能

    我们对 400 多个查询进行了基准测试,发现所有查询都在 SLA 内运行。我们甚至看到 P95 查询的性能提升了 15-20%。

  • 轻松迁移

    我们使用 TiDB Lighting 工具将表的所有历史数据从 Postgres 迁移到 TiDB。这个工具非常容易使用并且速度非常快。我们能够在大约 2-3 小时内加载 TB 级的数据。然而,值得注意的是,在加载如此庞大的数据之前需要进行大量的调整。

  • 大力支持

    我们在生产基础设施设置过程中遇到了一些问题,但 PingCAP 支持团队发挥了非常关键的作用,帮助我们根据工作负载的性质调整集群。


结论

在这篇文章中,我们通过实时数据集市的用例以及向 TiDB 的迁移之旅探讨了使用 Aurora 的挑战。我们还讨论了 Delhivery 如何大规模使用 TiDB。


尽管我们在 TiDB 方面取得了成功,但我们承认没有任何解决方案是完美的,并且有效性可能会根据用例而有所不同。在 TiDB 中,我们注意到一些需要改进的领域,包括缺乏对物化视图和本机配额管理的开箱即用支持。然而,通过适当的解决方法和调整,我们已经成功地解决了这些限制。


至此,我们已经在生产环境中部署了 TiDB。根据我们的基准测试,TiDB 使我们能够每秒处理数千个请求,且延迟低于 100 毫秒。展望未来,我们将继续探索更多需要强大、一致的分布式数据库的用例。


参考

https://docs.pingcap.com/tidb/stable/tidb-lightning-overview

https://reorg.github.io/pg_repack/

https://github.com/dataegret/pgcompacttable

https://cloud.google.com/spanner

https://www.yugabyte.com/yugabytedb/

https://cloud.google.com/bigquery/

https://docs.pingcap.com/tidb/dev/transaction-overview

https://proxysql.com/


作者:

Hari Kishan (高级工程经理 @ Delhivery)

Akash Deep Verma (Delhivery 技术总监)