原文链接是:https://www.percona.com/blog/2018/12/20/benchmark-postgresql-with-linux-hugepages/

Linux kernel提供了大量可以影响性能的配置参数。关键是针对你的应用程序和负载选择合适配置参数。像其他数据库一样,PostgreSQL 依赖于最优化的Linux kernel。糟糕的配置参数会导致糟糕的性能。因此,重要的是:在每次调整配置参数之后都要对数据库做benchmark,来避免性能降低。在我之前的博文中《Tune Linux Kernel Parameters For PostgreSQL Optimization》 https://www.percona.com/blog/2018/08/29/tune-linux-kernel-parameters-for-postgresql-optimization/ 我描述了一些最有用的Linux kernel配置参数以及这些配置参数如何提高你的数据库性能的。在这篇文章里面,我将会分享打开Linux大页之后,不同的工作负载的benchmark结果。针对不同大小的负载和并发访问客户端,我做了大量的benchmark。

benchmark 机器配置

超微服务器

  • CPU: Intel(R) Xeon(R) CPU E5-2683 v3 @ 2.00GHz
    2 sockets / 28 cores / 56 threads
  • 内存: 256GB of RAM
  • 存储介质: SAMSUNG SM863 1.9TB Enterprise SSD
  • 文件系统: ext4/xfs

操作系统: Ubuntu 16.04.4, kernel 4.13.0-36-generic

PostgreSQL: 11版本

Linux Kernel 配置

我使用了默认的操作系统配置,除了关掉了透明大页(Transparent HugePages)。透明大页是默认打开的,分配页的大小并不可控,对于数据库来说并不太推荐。通常,对于数据库来说,需要固定大小的大页,这个是透明大页所提供不了的。因此,通常推荐的是打开大页,并且要关闭透明大页。

PostgreSQL的配置

我使用了固定的PostgreSQL配置来做benchmark,主要是为了获得不同的负载和不同的配置的大页的测试结果。PostgreSQL配置如下:

  1. shared_buffers = '64GB'
  2. work_mem = '1GB'
  3. random_page_cost = '1'
  4. maintenance_work_mem = '2GB'
  5. synchronous_commit = 'on'
  6. seq_page_cost = '1'
  7. max_wal_size = '100GB'
  8. checkpoint_timeout = '10min'
  9. synchronous_commit = 'on'
  10. checkpoint_completion_target = '0.9'
  11. autovacuum_vacuum_scale_factor = '0.4'
  12. effective_cache_size = '200GB'
  13. min_wal_size = '1GB'
  14. wal_compression = 'ON'

benchmark测试方法

做benchmark的时候,测试的方法是非常重要的。所有的benchmark都会运行三次,每次都会运行30分钟。我取了这三次benchmark的中间值(去掉最低和最高,取中间)。我们使用了PostgreSQL的benchmark工具pgbench来进行测试。pgbench工作时使用了不同的比例因子(scaling fatctor),每个比例因子大概使用16M的内存。

大页 (HugePages)

Linux中大页默认使用的页大小是4K。BSD系统有Super Pages,Windows有Large Pages。PostgreSQL只支持Linux上提供的大页(HugePages).在内存使用率比较高的情况下,大页使用的页面大小太小会降低性能。通过设置大页,可以为应用程序指定内存,就可以降低分配内存和swap的操作开销,所以,可以通过使用大页来提高性能。
下面是使用1G大小的大页的配置。你可以通过从/proc获取这些信息。

  1. cat /proc/meminfo | grep -i huge
  2. AnonHugePages: 0 kB
  3. ShmemHugePages: 0 kB
  4. HugePages_Total: 100
  5. HugePages_Free: 97
  6. HugePages_Rsvd: 63
  7. HugePages_Surp: 0
  8. Hugepagesize: 1048576 kB

对于大页更细节的信息,可以看之前的博客:
https://www.percona.com/blog/2018/08/29/tune-linux-kernel-parameters-for-postgresql-optimization/
通常,大页的大小是从2M到1G,因此(实际生产环境中)合理的配置是使用1G的大小而不是更小的2M页面大小。
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-memory-transhuge
https://kerneltalks.com/services/what-is-huge-pages-in-linux/

benchmark 结果

这个benchmark展示了不同的大页大学的影响。第一组benchmark是使用了Linux默认的4K的页面大小,但是关闭掉了大页。注意,透明大页也关掉了,在下面的其他组的benchmark中也是关闭的。
第二组benchmark使用了2M大小的大页。最终,第三组使用的是1G的大页。
所有的benchmark都是使用了PostgreSQL 11来运行的。这些benchmark的集合实际是不同数据库大小和不同并发客户的组合。下面的图使用TPS来比较性能,Y轴是TPS,X轴是数据库的大小和并发的客户端数量。

很明显,从上图可以看出使用了大页之后,随着数据库的大小的增加、客户端数量的增加,性能也在不断增大,只要数据库的大小在预分配的共享内存(shared buffer)之内。
这幅图也表明TPS随着并发的客户端数量增大而增大,数据库的大小设置为48G的大小。Y轴是TPS, X轴是连接的客户端数量。数据库的大小足够小,能装入到64G的共享内存中。

当把大页设置成1G大小,随着客户端数量的增加,原本已经不错的性能又进一步提升了。
下面这幅图和上面这幅图基本上相同,除了数据库的大小是96G。这就超过了原本64G的共享内存的大小。

一个重要的发现就是:使用1G大页的时候,随着客户端数量的增加,性能最终超过了2M页面大小的情况和标准的4K页面的情况。
测试也表明,随着数据库大小的增加,TPS是逐渐降低的。在这个例子中,客户端的连接数量是32.Y轴是TPS,X轴是数据库大小。

和预期的一样,当数据库的大小超过shared buffer大小时,性能会明显降低。

总结

我首先推荐的一点是我们必须关掉透明大页。当打开大页、并且数据库都能放在共享内存时,你将会看到最大的性能增益。虽然确定大页的大小需要一些尝试和错误,但是设置大页依然可以获得更大的TPS,只要这个大的数据库仍然可以放到shared buffer中。

0 评论  
添加一条新评论