Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Survey on how to protect PostgreSQL child proce...

syamauchi
September 07, 2023

Survey on how to protect PostgreSQL child process from OOM-killer

syamauchi

September 07, 2023
Tweet

More Decks by syamauchi

Other Decks in Technology

Transcript

  1. #RAKUSMeetup ©2023 RAKUS Co., Ltd. ©2023 RAKUS Co., Ltd. PostgreSQLで発生する

    OOM-Killerに対応した話 ラクスMeetUp 2023/09/06 山内覚
  2. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 自己紹介 • 2019/07 株式会社ラクス入社 •

    楽楽販売開発チームに所属 • 業務内容 ◦ 新バージョンのリリース準備 ◦ ミドルウェアバージョンアップ ◦ サービスのトラブル対応
  3. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 楽楽販売の紹介 • Webデータベースサービス • さまざまなデータとその関連を管理できる

    • 業務フローに合わせた販売管理システムを構築できる • 使用している技術 ◦ Linux + Apache + PHP + PostgreSQL
  4. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 楽楽販売の運用トラブルの例 • 通信障害 • 処理遅延(処理集中、アプリの問題)

    • リソース枯渇(HDD、メモリ) ⇒ メモリの枯渇によりOOM-Killerが発生する場合がある
  5. #RAKUSMeetup ©2023 RAKUS Co., Ltd. OOM-Killerとは • Linuxのカーネルの機能 • システム全体のメモリが不足する前に特定のプロセスを停

    止して空きメモリを確保する • どのプロセスを停止するかはOOMスコアによって決まる ⇒サービス停止を引き起こすやっかいな機能
  6. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 動的メモリ確保について プロセスが動的にメモリを使う場合は(1)メモリ確保、(2)メモリ使用という順で処理を行う (1)メモリ確保 malloc, realloc

    などでメモリを確保する 一度に大きなサイズのメモリを確保しておき、そのメモリを使いまわすプロセスがある ⇒ 確保したのに使用されないメモリ領域ができる (2)メモリ使用 memset, memcopy などで確保したメモリにデータを書き込む 使用済 100MB 未使用 100MB 未使用 200MB
  7. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 確保したのに使われないメモリの対策 システム全体のメモリ使用状況のイメージ OS カーネル、ドライバなど ・OS、デーモン1、デーモン2が確保したメモリ

    = 6GB ・OS、デーモン1、デーモン2が使用済のメモリ = 3GB ・システム全体で使えるメモリ = 4GB Linuxではシステム全体で使える以上のメモリを確保すること(オーバーコミット)を許可している ⇒メモリを有効活用し多くのプロセスが稼働できるようになる 使用済 1GB 未使用 1GB 使用済 1GB 未使用 1GB デーモン1 親プロセス、子プロセス 使用済 1GB 未使用 1GB デーモン2 親プロセス、子プロセス システム全体で使えるメモリ 使用済 2GB 使用済 1GB 未使用 1GB 物理メモリ SWAP
  8. #RAKUSMeetup ©2023 RAKUS Co., Ltd. メモリが枯渇した場合の動き システム全体のメモリ使用状況のイメージ OS カーネル、ドライバなど ・OS、デーモン1、デーモン2が確保したメモリ

    = 6GB ・OS、デーモン1、デーモン2が使用済のメモリ = 4GB ・システム全体で使えるメモリ = 4GB オーバーコミットしたメモリが実際に使われるとシステムのメモリが枯渇する ⇒ 特定のプロセスを停止して空きメモリを確保する仕組みがOOM-Killer 使用済 1GB 未使用 1GB 使用済 1GB 未使用 1GB デーモン1 親プロセス、子プロセス 使用済 2GB デーモン2 親プロセス、子プロセス システム全体で使えるメモリ 使用済 2GB 使用済 2GB 物理メモリ SWAP OOM-Killerがプロセ スを停止する
  9. #RAKUSMeetup ©2023 RAKUS Co., Ltd. OOM-Killerが発生した場合の影響について Apache 親プロセス × 子プロセス

    ←OOM-Killer により停止 PostgreSQL 親プロセス × 子プロセス ←OOM-Killer により停止 × × ←共有メモリが破損した 可能性があるため親プロ セスの命令で停止 ⇒PostgreSQLでOOM-Killerが発生した場合の影響が大きいため対策が必要
  10. #RAKUSMeetup ©2023 RAKUS Co., Ltd. PostgreSQLで発生するOOM-Killerへの対応 • やりたいこと ◦ OOM-Killerの発生頻度を減らす

    ◦ OOM-Killerが発生した場合の影響を減らす • 対応案 1. 設定変更でOOM-Killerに対応 設定でOOM-Killerの対策ができないか調査する 対応工数: 小 2. OOM-Killerの原因となっているSQLを修正 修正が必要なSQLは共通部品で使用しているため影響が大きい 修正の効果を測るには再現環境が必要だが複雑な設定と大量のレコードを準備する必要がある 対応工数: 大
  11. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 1. 設定変更でOOM-Killerに対応 No. 対象 対策

    説明 1 postgresql.conf なし 以下のような設定を調査したが見つからなかった • 関係ない子プロセスの停止を防ぐ • 子プロセスが使えるメモリ上限を設定する 2 カーネルパラ メータ OOMスコアの調整 OOMスコアを調整し特定のプロセスをOOM-Killerの対象 外にする • 親プロセスはOOM-Killerの対象外とすることが推奨 • 子プロセスはOOM-Killerの対象とすることが推奨 ※ 子プロセスも対象外にすると空きメモリを確保 する手段が無くなるため 3 カーネルパラ メータ メモリのオーバーコ ミットの動作を変える メモリのオーバーコミットを防ぐことでOOM-Killerの発 生を防ぐ ⇒ 解決したい問題に使えそうな No.3 の設定の効果を検証 (参考)19.4.4. Linuxのメモリオーバーコミット https://www.postgresql.jp/document/15/html/kernel-resources.html PostgreSQLのマニュアルからOOM-Killerの対策を調査
  12. #RAKUSMeetup ©2023 RAKUS Co., Ltd. オーバーコミットに関する設定の効果 No. 値 プロセスがメモリをオーバーコミット したときの動作

    OOM-Killerの発生 1 0 (default) ある程度許可する ※システムが使えるメモリを大きく越える場合は許可しない あり 2 1 無制限に許可する あり 3 2 許可しない ※メモリのオーバーコミットが起こらなくなる なし ⇒ vm.overcommit_memory を変更してPostgreSQLのメモリ使用量が増えた場合の動作を検証 (参考) overcommit-accounting https://www.kernel.org/doc/Documentation/vm/overcommit-accounting vm.overcommit_memory の値とメモリをオーバーコミットしたときの動作の関係
  13. #RAKUSMeetup ©2023 RAKUS Co., Ltd. PostgreSQLのメモリ使用量が増えた場合の動作 vm.overcommit_memory = 0 親プロセス

    × 子プロセス ←OOM-Killer により停止 × × ←共有メモリが破損した 可能性があるため親プロ セスの命令で停止 ⇒他の子プロセスへの影響については期待した通りの動作となっている vm.overcommit_memory = 2 親プロセス × 子プロセス ←メモリ確保に失 敗して子プロセス 自身がエラー終了 ←外部から停止されてい ないため他の子プロセス には影響なし
  14. #RAKUSMeetup ©2023 RAKUS Co., Ltd. オーバーコミットを許さない場合の副作用 vm.overcommit_memory = 2 にした場合

    OS カーネル、ドライバなど ・OS、デーモン1、デーモン2が確保したメモリ = 6GB ・OS、デーモン1、デーモン2が使用済のメモリ = 3GB ・システム全体で使えるメモリ = 4GB ⇒ 追加が必要なSWAPサイズを試算 使用済 1GB 未使用 1GB 使用済 1GB 未使用 1GB デーモン1 親プロセス、子プロセス 使用済 1GB 未使用 1GB デーモン2 親プロセス、子プロセス システム全体で使えるメモリ 使用済 2GB 使用済 1GB 未使用 1GB 物理メモリ SWAP システムで使える以上の メモリ確保(オーバーコ ミット)が許可されない 未使用 +?GB デーモン2を稼働させる にはSWAPを追加する必 要がある
  15. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 追加が必要なSWAPサイズの試算 vm.overcommit_memory = 2 の場合

    1. メモリ確保できる最大値 ◦ SWAPサイズ + 物理メモリサイズ × vm.overcommit_ratio で算出可能 ※ /proc/meminfo の CommitLimit でも確認可能 2. 過去に確保されたメモリの最大値 ◦ sar -r –f /var/log/sa/saXX の kbcommit の最大値で確認可能 ⇒ 楽楽販売で追加が必要なSWAPサイズ vm.overcommit_ratio 追加が必要なSWAPサイズ(GB) 0.5 (default) 7.4 0.9 1.3 設定変更でOOM-Killerに対応するには全サーバのSWAPサイズを追加する必要がある ⇒ 対応工数: 小→大
  16. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 2. OOM-Killerの原因となっているSQLを修正 • 対象のSQL ◦

    キーワード検索で使用する共通部品のSQL • メカニズム ◦ 結合するテーブル数が多くなるとSQLのパース処理でメモリ使用量が増える • 再現環境の作成 ◦ 大量のレコードが無くても事象が再現した ※メモリ使用量が増えるのはパース処理であったためレコードが無くても 再現した ⇒再現環境ができたことでSQLを修正した場合の効果も測れるようになった
  17. #RAKUSMeetup ©2023 RAKUS Co., Ltd. SQLの修正方法 マスタ1 マスタ2 売上情報 売上明細

    マスタ3 マスタ4 参照 参照 参照 参照 参照 キーワード検索のイメージ 検索対象 検索対象外 • 検索対象外のテーブルを結合対象から外すことでメモリ使用量を削減できる • 影響範囲は限定的 対応工数: 大→中 ⇒ こちらの対応を実施
  18. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 最終的に採用したOOM-Killer対策 • 対応案 1. 設定変更でOOM-Killerに対応

    全サーバへのSWAP追加が必要だった 対応工数: 小→大 ⇒ 不採用 2. OOM-Killerの原因となっているSQLを修正 共通部品のSQLの修正ではあるが影響範囲を限定できた 再現環境を作成し修正後の効果も検証することができた 対応工数: 大→中 ⇒ 採用 • 結果 ◦ OOM-Killerの発生頻度を減らすことができた
  19. #RAKUSMeetup ©2023 RAKUS Co., Ltd. 対策方法まとめ No. カテゴリ 対象 対策

    説明 1 設定変更 postgresql.conf なし • OOM-Killerの発生を抑制したり、発生した場 合の影響を緩和する設定はない 2 設定変更 カーネルパラ メータ OOMスコアの調 整 • 親プロセスの保護には有効 • 子プロセスの保護には有効ではない 3 設定変更 カーネルパラ メータ メモリのオー バーコミットの 動作を変える • オーバーコミットさせない動作にすることで OOM-Killerの発生を防ぐことができる • SWAPサイズを大きく取れる場合は有効な対策 4 SQL修正 SQL メモリ使用量の 削減 • メモリ使用量の削減によりOOM-Killerの発生 頻度を減らす OOM-Killer対策の参考になれば幸いです。