Skip to content

Latest commit

 

History

History
96 lines (60 loc) · 8.26 KB

How to benchmark.md

File metadata and controls

96 lines (60 loc) · 8.26 KB

How to benchmark

我每天都会发布一篇新的 PostgreSQL "howto" 文章。加入我的旅程吧 — 订阅、提供反馈、分享!

基准测试是一个很大的话题。此处,我们介绍了 Postgres 基准测试所需的最少步骤,使其信息丰富、有用且正确。

在本文中,我们假设遵循以下原则:

  1. 独占环境:整个机器只供我们独自使用 (没有其他人在使用),我们旨在研究 Postgres 的整体行为及其所有组件 (而非微观基准测试,如通过使用 EXPLAIN 研究特定查询或专注于底层组件如磁盘和文件系统的性能)。
  2. 高质量:我们追求诚实 (没有"营销式的基准测试"目标)、透明 (共享所有细节)、精确,并在发生错误时修正它们。每次基准测试运行应足够长,以考虑缓存的冷状态或各种波动等因素。通常,每种基准测试应该运行多次 (通常,进行 4-5 次),以确保测试的可重复性。学习现有经验是很有意义的:Brendan Gregg 的 "System Performance" 书中有一章关于基准测试的章节;此外,从其他领域 (如物理学等) 学习成功实验的原则和方法论也是有益的。
  3. 准备学习:我们有足够的专业知识来理解瓶颈和局限性,或准备利用他人的帮助,在必要时重新进行基准测试。

基准测试结构

基准测试是一种数据库实验,一般情况下,我们使用多个 DBMS 会话,研究系统的整体行为以及它的所有或特定组件 (比如缓冲池、检查点、复制情况等)。

每个基准测试都应该有一个明确定义的结构。总的来说,它包含两大部分:

  • 输入:我们在执行基准测试之前定义的一切 — 我们在何处运行基准测试、系统如何配置、使用什么数据库和工作负载、我们研究的变化是什么 (用于比较变化前后的行为)。
  • 输出:各种可观测的数据,例如日志、观察到的错误、统计数据等等。

Database Benchmark

每个部分都应有良好的文档记录,以便任何人都可以重现实验、理解主要指标 (延迟、吞吐量等),理解瓶颈,并在需要时进行额外的、修改后的实验。

数据库基准测试的所有方面的描述可能需要写一本书 — 在此,我仅提供基本建议,帮助你避免错误并提高基准测试的总体质量。

当然,某些内容可以根据需要省略。但通常建议,自动记录所有实验的文档和生成的文件,以便日后方便研究细节。你可以在这里找到一些为特定目的进行的基准测试的优秀示例 (例如,研究病态的子事务行为或衡量启用wal_compression的好处)。

输入: 环境


  • 确保你使用的机器规格合适,不要在笔记本电脑上运行 (除非绝对必要)。AWS Spot 实例或 GCP 的Preemptible 实例在短时间内使用时价格非常便宜,非常适合实验。例如,具有 128 个 Intel 或 AMD 虚拟 CPU 和 256-1024 GiB 内存的 VM 的 Spot 实例每小时价格低至 5-10 美元 (good comparison tool),按秒计费 — 这使得在大机器上进行非常经济高效的实验成为可能。
  • 获取 VM 后,使用 fio、sysbench 等微基准测试工具快速检查 CPU、内存、磁盘和网络是否按预期工作。如果有疑问,可以与其他同类型 VM 进行比较并进行选择。
  • 记录 VM 的技术规格、磁盘和文件系统 (这两个对于数据库非常重要!)、操作系统的选择和非默认设置。
  • 记录使用的 Postgres 版本和任何额外的扩展 (即使只是安装了某些扩展,它们也可能会产生 "观察者效应")。
  • 记录所有非默认的 Postgres 设置。

输入: 数据库

记录你使用的模式和数据。理想情况下,应该以完全可重现的形式 (SQL /转储文件) 记录。


输入: 工作负载

  • 记录你所使用的工作负载的所有方面 — 理想情况下,也应以完全可重现的形式记录 (SQL、pgbench、sysbench 等细节)。
  • 理解你基准测试的类型以及你想进行的负载测试类型:是极限负载测试(压力测试),旨在"全速"运行,还是常规负载测试,模拟现实场景下的负载,例如 CPU 使用率通常远低于 100%。请注意,默认情况下,pgbench 倾向于为你进行"压力测试" (不限制 TPS 数量 — 要限制它,请使用-R选项)。

输入: 差异

可能有各种类型的"差异" (定义测试运行之间差异的研究对象)。以下是一些示例:

  • 不同的 Postgres 次要或主要版本
  • 不同的操作系统版本
  • 不同的设置,如 work_mem
  • 不同的硬件
  • 规模变化:不同数量的客户端与数据库进行交互或不同的表大小
  • 不同的文件系统

不建议将 SQL 查询中更改的模式更改视为"差异",因为:

  • 此类工作负载变化通常发生得非常快
  • 完整的基准测试非常昂贵
  • 可以在共享环境中研究模式和查询的更改,专注于 IO 指标 (如BUFFERS!),以实现高效的时间和成本效益(参考 @Database_Lab)

输出: 收集成果

收集各种成果,并确保它们不会丢失 (例如,将它们上传到对象存储中)。

  • 每次运行前,使用 pg_stat_reset()pg_stat_reset_shared(..) ,其他标准的pg_stat_reset_***() 等函数 (docs)、pg_stat_statements_reset()pg_stat_kcache_reset() 等重置所有统计信息。
  • 每次运行后,将所有 pg_stat_*** 视图以 CSV 格式导出。
  • 收集所有 Postgres 日志及任何相关日志 (如 pgBouncer、Patroni、系统日志)。虽然 Postgres、pgBouncer 或其他配置文件属于"输入",但创建所有实际观察到的配置值的快照 (例如,select * from pg_settings;),并将此数据也视为成果。
  • 收集查询分析信息:pg_stat_statementspg_stat_kcachepg_wait_sampling / pgsentinel 等的快照。提取关于错误的所有信息,来源于 (a)日志,(b) pg_stat_database (如xact_rollback) 等类似指标的 SQL,并将其视为分析的重要成果类型。可以考虑使用一个名为 logerrors 的小扩展,它将注册所有错误代码并通过 SQL 暴露它们。
  • 如果使用了监控,收集监控图表。对于实验特别方便的是 Netdata ,因为它非常容易安装在新机器上,并且具有仪表盘导出/导入功能 (不幸的是,它们位于客户端一侧,因此始终需要手动操作;但在进行数据库实验时,我个人认为它们非常方便)。

分析

以下是一些建议 (远不完整):

  • 始终检查错误。基准测试运行时,很常见的是得出某些结论,而后来才意识到错误计数过高,使得测试无效。
  • 理解瓶颈在哪里。我们常常在磁盘 IO 上饱和,认为我们观察的是数据库系统的行为,但实际上我们看到的是云磁盘限速或文件系统限制的表现。在这种情况下,我们需要思考如何调整输入,避免这种瓶颈,以进行有用的实验。
  • 在某些情况下,反之亦然,达到某种饱和状态是非常理想的 — 例如,如果我们研究 pg_dump pg_restore 的速度,我们可能希望观察磁盘系统的饱和情况,并调整输入 (例如,我们如何进行 pg_dump — 使用多少个并行工作进程,是否涉及压缩,是否涉及网络等),以便确实达到预期的饱和状态,并展示它。
  • 理解你在测试运行之间要比较的主要指标 — 延迟、吞吐量、查询分析指标 (如 pg_stat_statements 中的指标,等待事件分析等)。
  • 开发一个良好的总结格式并遵循这个格式。它可以包括对各种输入部分的简短描述,包括工作负载差异和主要比较指标。以这种结构良好的形式保存所有运行的总结。