优化高写入数据库工作负载实现低延迟

本文深入探讨高写入数据库工作负载的性能优化策略,涵盖存储引擎架构选择、负载大小影响、压缩与合并策略及批处理最佳实践,帮助实现毫秒级低延迟数据处理。

优化高写入数据库工作负载实现低延迟

高写入数据库工作负载带来与读取密集型工作负载截然不同的挑战。例如:

  • 扩展写入成本高昂,特别是按操作付费时,写入成本比读取高5倍
  • 锁定会增加延迟并降低吞吐量
  • I/O瓶颈可能导致写入放大并复杂化崩溃恢复
  • 数据库反压可能限制传入负载

虽然成本很重要,但在许多情况下,这不是我们在此要讨论的主题。相反,让我们关注团队常遇到的性能相关复杂性,并讨论应对选项。

什么是"实时高写入工作负载"?

首先,澄清"实时高写入"工作负载的含义。我们指的是:

  • 摄取大量数据(例如超过5万OPS)
  • 写入多于读取
  • 受严格延迟SLA约束(例如个位数毫秒P99延迟)

在现实世界中,它们出现在从在线游戏到实时证券交易所的各种场景中。一些具体示例:

  • 物联网工作负载:通常涉及小型但频繁的仅追加时间序列数据写入。此处摄取率主要由收集数据的端点数量决定。
  • 日志记录和监控系统:处理频繁数据摄取,但没有固定摄取率,可能不仅限于仅追加,并且容易出现热点。
  • 在线游戏平台:需要处理实时用户交互,包括游戏状态更改、玩家操作和消息传递。工作负载往往是尖峰式的。
  • 电子商务和零售工作负载:通常是更新密集型,通常涉及批处理。
  • 广告技术和实时竞价系统:需要瞬间决策,处理复杂竞价处理,同时监控用户交互。
  • 实时证券交易所系统:必须支持高频交易操作、持续股票价格更新和复杂订单匹配过程。

存储引擎架构

存储引擎架构的选择从根本上影响数据库的写入性能。存在两种主要方法:LSM树和B树。

已知能有效处理写入的数据库,如ScyllaDB、Apache Cassandra、HBase和Google BigTable,使用日志结构合并树。这种架构非常适合处理大量写入。由于写入立即追加到内存中,这允许非常快速的初始存储。

使用B树结构,每个写入操作都需要定位和修改树中的节点,这涉及顺序和随机I/O。随着数据集增长,树可能需要额外节点和重新平衡,导致更多磁盘I/O,从而影响性能。B树通常更适合涉及连接和临时查询的工作负载。

负载大小

负载大小也会影响性能。对于小负载,吞吐量良好,但CPU处理是主要瓶颈。随着负载大小增加,整体吞吐量降低,磁盘利用率也增加。小写入通常适合所有缓冲区,一切都可以快速处理。这就是为什么容易获得高吞吐量。对于较大负载,需要分配更大缓冲区或多个缓冲区。负载越大,服务这些负载所需的资源(网络和磁盘)就越多。

压缩

对于高写入工作负载,需要密切监控磁盘利用率。尽管存储不断变得更便宜,但仍然不是免费的。压缩有助于控制情况,因此请明智选择压缩策略。更快的压缩速度对于高写入工作负载很重要,但也要考虑可用的CPU和内存资源。务必查看压缩块大小参数。压缩基本上将数据分成较小块,然后分别压缩每个块。调整此设置时,要认识到较大块更适合读取,而较小块更适合写入,并考虑负载大小。

合并

对于基于LSM的数据库,选择的合并策略也会影响写入性能。合并涉及将多个SSTable合并为更少、更有组织的文件,以优化读取性能、回收磁盘空间、减少数据碎片并保持整体系统效率。

选择合并策略时,可以瞄准低读取放大,使读取尽可能高效。或者,可以通过避免合并过于激进来瞄准低写入放大。或者,可以优先考虑低空间放大,并让合并尽可能高效地清除数据。

对于高写入工作负载,我们警告用户不惜一切代价避免分层合并。该策略专为读取密集型用例设计。使用它可能导致令人遗憾的40倍写入放大。

批处理

在像ScyllaDB和Cassandra这样的数据库中,批处理实际上可能是一个陷阱,特别是对于高写入工作负载。如果习惯关系数据库,批处理可能看起来是处理大量写入的好选择。但如果不小心操作,它实际上会减慢速度。主要是因为大型或非结构化批处理最终会在节点之间产生大量协调和网络开销。

在处理重写入时,以下是关于批处理的思考方式:

  • 按分区键批处理:按分区键分组写入,使批处理转到也拥有数据的协调器节点。
  • 保持批处理小而目标明确:通过分区将大批处理分解为较小批处理保持效率。
  • 坚持使用未记录批处理:考虑到遵循前面的要点,最好使用未记录批处理。

因此,如果处于高写入情况,请仔细构建批处理,以避免大型跨节点批处理可能引入的延迟。

总结

我们提供了相当多的警告,但不用担心。很容易编译经验教训列表,因为许多团队在处理实时高写入工作负载时非常成功。现在您知道了他们的许多秘密,而不必经历他们的错误。:-)

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计