クライアントから報告された長期間未解決の問題の一つは、Ceph クラスターが HEALTH_OK ステータスに戻るまでの全体的な回復時間が遅いことでした。実際のハードウェアやセットアップ(主にディスクの数)によって、この時間は、電源障害や計画的なメンテナンスがあった場合、1時間から数時間にわたって変動することが報告されていました。このチケットを確認し、再現することができました。いくつかの観察の結果、ceph-osd(オブジェクトストレージデーモン)を再起動するという単純なアクションが、このような長時間の回復プロセスを引き起こす可能性があると結論できました。
3ノードのクラスターの例として、最初のノードで全てのceph-osdを再起動しました。
画像出典:Bigstack CubeCOS
10分後、私はまだ上記のHEALTH_WARNステータスを確認していました。警告は14のosdがダウンしており、pgが不足していることを訴えていました。この警告は理にかなっています。このストレージクラスターはホストを障害ドメインとして3つのレプリケーションを構成していたため、3つのノードのうち1つのosdがダウンすると、cephは3番目のレプリカを完了できず、pgが不足することになります。問題は、ノード数が多い大規模なクラスターではさらに悪化し、cephはピアリングを開始して、別のノードで3番目のコピーを作成しようとします。これはディスクI/Oを無駄に使うことになります。なぜなら、これらの14個のosdが再びアップ状態になると、cephは4つのコピーがあることに気付き、余分なコピーを削除するためにさらに作業を行うからです。これらの不必要なディスクアクティビティは、ディスクの寿命を短くし、特にSSDの寿命を縮めるだけでなく、osdプロセスのメモリ使用量も増加させます。それだけではありません。このクラスターは稼働中であり、cephはストレージリクエストを処理し続けています。cephは引き続きデータを書き込み、pgを残りのosdに配布します。これにより、これらの14個のosdがクラスターに再参加すると、同期とpgの再バランスが必要となることを意味します。osdが早期にアップ状態に復帰すれば、ストレージクラスター全体にとってはその方が良いことは明白です。
ログを詳しく確認するために、起動に時間がかかったosdプロセスの1つを停止し、手動でデバッグフラグを付けて実行しました。
# systemctl restart ceph-osd@7
# /usr/bin/ceph-osd -d --cluster ceph --id 7 --setuser ceph --setgroup ceph --debug_bluefs 10 --debug_bluestore 10
膨大なメッセージがありましたが、全体的には問題はなさそうでしたが、次のステップで以下のような現象が発生しました。
bluestore(/var/lib/ceph/osd/ceph-7) _open_db_and_around read-only:0 repair:0
そしてこのステップの後、rocksdbへの読み取り活動が圧倒的に増加しました。これはディスクのiostatで確認できました。いくつかのGoogle検索と試行錯誤を経て、いくつかのosdが他のosdよりも速く回復するように見えました。手がかりは、bluestoreのrocksdbに過剰な読み取りが行われていることを示していました。それでは、そこに格納されている最も大きなデータは何だったのでしょうか?
画像出典:Bigstack CubeCOS
cephのディスク空き容量を確認したところ、怪しいと思われる列はMETAでした。一部のosdは比較的小さなサイズ(MB)で、他の多くはGB単位でした。METAのサイズが大きいほど、osdのブート完了に時間がかかることが分かりました。このことは、METAがbluestoreのrocksdbに格納されていることと一致しました。
幸いにも、cephにはMETAデータを削減するツールが備わっています。
画像出典:Bigstack CubeCOS
そして、それで全てです!METAがコンパクト化され、サイズが数十MBに減少した後、osdはブートを完了し、数秒で「up」として認識されるようになりました。
この簡単な手順をスクリプトに追加することで、今後はosdを再起動してもパフォーマンスに影響を与えたり、リカバリーのオーバーヘッドが発生することを心配する必要はなくなりました。これにより、サポートとメンテナンスコストの大幅な削減と、クライアント体験の向上が実現しました。