Edited at

[postgres]大容量メモリかつOSがRHEL(CentOS)6系をお使いの方、THPのdefragは止めた方が良いですよ

More than 3 years have passed since last update.


概要

とある日、postgresが稼働しているサーバのリプレースを行ったところ、

CPUのsysがスパイクしてpostgresが数十秒ほど処理不可となり、ひどい目にあったという話です。

※この環境はCentOS6.8で、postgresは9.4でも8.2でも同現象が発生しました

原因は"THP(Transparent Huge Page)"というOSの機能に関連したdefrag(compaction alloc)処理により、CPUリソースが枯渇したためでした。

SYSmax.png

検証したところ、以下の状況が重なるとsysスパイク現象が起きてしまう様です。


  • サーバの搭載メモリが大きい(たとえば200GB以上)

  • 継続的にトランザクションが発生する

  • THPが有効である(OSのデフォルトで有効)


THP(Transparent Huge Page)のざっくり説明

通常4KBのページを2MBという大きな単位で扱うことで、

ページ管理コストを削減し、効率改善による性能向上を図ることが目的の機能。

Postgresの場合手動でHugePageを指定できるが、THPはOSが動的(トランスペアレント)にHugePageを割り当てる。


対策

オンラインでTHPのデフラグを停止する

# echo madvise > /sys/kernel/mm/transparent_hugepage/defrag

永続的にTHPのデフラグを停止する(もっとスマートな方法がありそう...)
# vi /etc/rc.local
echo madvise > /sys/kernel/mm/transparent_hugepage/defrag を追記


調査方法

■ 現行設定確認

# cat /sys/kernel/mm/transparent_hugepage/defrag
⇒alwayであれば対象

■ あれ?sys高いなと思ったときに打つ
# perf top
⇒以下のように出たらすぐにTHPのdefrag設定を見直しましょう
~~~
Samples: 2M of event 'cycles', Event count (approx.): 908733026153
42.59% [kernel] [k] compaction_alloc  ←★これ (圧縮_再配置)
8.09% [kernel] [k] __reset_isolation_suitable
2.32% [kernel] [k] compact_zone
...
~~~


起きたこと


  1. CPU使用率のsysが張り付く

  2. postgresの処理が止まる

  3. postgresのプロセスが大量生成(セッションが処理されないので)

  4. PG-REX構成だったのでpacemakerによるF/Oが発生、また発生、またまた発生....


参考:THPにまつわるDB界隈の情報

調べてみると、THPに関してデータベース界隈で情報が見つかりました。個人のまとめとして記載させて頂きます。


・ガチャピン先生こと 小崎資広 大先生のTHPに関するまとめ

http://mkosaki.blog46.fc2.com/blog-entry-1291.html


・RHEL6マニュアル

「THP はデータベースのワークロードには推奨されません」

https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/s-memory-transhuge.html


・Postgresの主要開発者Mr.Robert Haasの記事

「(意訳)CPUのSYSが高負荷になる場合、THPを無効化を推奨している」

http://rhaas.blogspot.jp/2014/03/back-from-lsfmm-and-collab.html


・NTT Data社の大規模環境postgresでの事例

「THPを無効にすることによりCPUのsys高騰が解消した」

http://www.slideshare.net/hadoopxnttdata/ntt-data-postgresql

※エンジニア魂を揺さぶって頂ける素晴らしいスライド


・Oracleマニュアル

「パフォーマンスの問題を回避するために、透過的なHugePagesはすべてのOracle Databaseサーバーで無効にすることをお薦めします」

https://docs.oracle.com/cd/E57425_01/121/CWLIN/memry.htm#CHDFBJAH


・MySQLでの事例

「(意訳)THPはOSの”問題”として劇的な効果を見せた……OFFにしたので安定した」

http://developer.okta.com/blog/2015/05/22/tcmalloc/

※デフォルトのglibc mallocではなく、チューニングでTCMallocを採用したケースのようです


・MongoDB

「(意訳)THPは良いものだがDB処理ではひどい状況になることがある、MongoDBでベストパフォーマンスを保証したければOFFにするべきだ」

https://docs.mongodb.org/manual/tutorial/transparent-huge-pages/


Hadoop

「(意訳)THPはHadoopの処理に深刻なダメージを与える可能性がある」

http://www.cloudera.com/documentation/enterprise/5-2-x/topics/cdh_admin_performance.html


最後に

THPの思想・機能はとても素晴らしいものと考えています。

実際にバイナリデータを多用するトランザクションをpgbenchで負荷がけしたところ、THP有効時とTHP無効時ではCPUのSYSの上がり方が有効時の方が抑えられる結果を得られました。(defrag発生時はsysがスパイクしてしまいますが)

その一方で、OSのバージョンアップを機にデフォルトで有効になったという点で、SYSスパイクトラップとしてその機能を体験してしまったことは、個人として残念な結果でした。。