本記事は「SAP (unofficial) Advent Calendar 2024」の2024 の12月23日分の記事として執筆しています。SAP (unofficial) Advent Calendarは初参加になりますので、よろしくお願い致します。
はじめに
本記事内の情報は出来る限りSAP公式の情報を元に記述していますが、正確に公開されていない情報も多々あり、事実と異なっている情報も含まれている可能性があります。もし情報の誤りに気づかれた場合は、Xにてご連絡いただけますと幸いです。
文字情報だけでは理解が難しい内容のため、画像に変換したスライドを中心の記事としてます。文章は補足程度に追加しています。
お題について
今回のお題は「アプリコンサルも必見!図解S/4HANAメモリ障害と対策まとめ」としました。
昨今のこの手のSAP関連記事は、SAP BTP、SaaSの製品、S/4HANA移行、この辺りの記事が多いかと思います。インメモリーデータベースのHANAが最初にリリースされたのは2011年で、13年も経過した今さらメモリの話?と思われるかもしれません。ではなぜ敢えてHANAメモリの話に切り込んだのか?
その理由は、、、ズバリ!S/4移行後にHANAメモリ障害が発生しやすいためです!(すみませんが、エビデンスはございません。筆者の妄想である点をご留意ください。<(_ _)>)
こんな経験ありませんか?
ところで、こんな経験ありませんか?
HANAのUsed Memory(使用メモリ)に対して空き容量が十分にあるにも関わらず、突然Used Memoryが100%近くに達してシステムが止まるか強制再起動が発生する障害です。
HANA DBのおさらい
さて、本題に入る前に少しHANA DBのおさらいをしたいと思います。
SAP HANAが登場する前の従来のDBでは、データ処理をアプリケーションサーバー側で行うため、大量のデータ転送が発生し、処理が遅くなることがありました。一方、SAP HANAのCode pushdownでは、データ処理をデータベース内で直接実行することで、処理スピードと効率性で従来のDBを大きく上回ります。
と言うことは・・・ですよ?
クエリの書き方を間違えると、HANA側で大量メモリを消費する処理が爆誕!!すると言うことです。特にBIGサイズの会計系テーブルに対し、結合を重ねたりすると… (数TB消費する可能性も)
本題に入る前の前提
それでは本題に入りたいと思います。まず前提として、理解しやすいようにHANAの物理メモリを1TBとし、1TB=1000GB(本来は1024GB)として扱います。また、通常時の使用メモリは半分の500GB程度で推移すると仮定します。
global_allocation_limitというHANAのメモリパラメータも重要ですので、スライドの解説をご確認ください。
その他のHANAメモリ概念もザックリ書いておきます。絵がゴチャゴチャするので次スライドから省略していますが、これも重要なので抑えておいて下さい。詳細はSAP Learningの記事等をご参考いただければと思います。
障害ケース①②:600GBの大量メモリを要求する処理が発生した場合
ここからは障害ケースと対策を解説していきます。
障害ケース①では、600GBの大量メモリを要求する処理が発生した場合、必要なメモリを確保できないため、処理が長時間化し、全体の使用メモリが逼迫します。
その結果、SAPの動作が重くなりパフォーマンスが低下し、他の処理が必要なメモリを確保できずエラーが発生します。
障害ケース②では、600GBの大量メモリを要求する処理が発生した場合、物理メモリとglobal_allocation_limitの差が「OSが必要とするメモリ」を下回ると、global_allocation_limitの限界までメモリが使用され、HANAが必要なメモリを確保できなくなり、強制再起動が発生します。
その結果、強制再起動後、しばらくの間ユーザーはSAPにログインできない、またはほとんど操作ができない状態が発生します。
障害ケース①②の対策:statement_memory_limit
障害ケース①および②でstatement_memory_limitが設定されていた場合、1つのSQLがstatement_memory_limitで指定されたメモリ容量を超えると、処理はエラーで終了します。
エラーの対策としては、SQLのチューニングを行い効率的なクエリに改善する、statement_memory_limitの値を調整する、または物理メモリの増設を検討することが挙げられます。
障害ケース③:statement_memory_limitを下回る大量メモリ(200GB)を要求する処理が複数同時発生した場合
障害ケース③では、statement_memory_limitを下回る大量メモリ(200GB)を要求する処理が複数同時に発生した場合、各処理が互いにメモリを奪い合い、全体の使用メモリがglobal_allocation_limitに到達します。
その結果、障害ケース①のように処理が長時間化しパフォーマンスが低下する、または障害ケース②のようにHANAが必要なメモリを確保できず強制再起動が発生する影響が生じます。
障害ケース③の対策:total_statement_memory_limit
障害ケース③でtotal_statement_memory_limitが設定されていた場合、1つ目のSQLはstatement_memory_limitとtotal_statement_memory_limitの値をどちらも下回っているため、正常に実行されます。
一方、2つ目のSQLはstatement_memory_limitの値を下回っているものの、total_statement_memory_limitの値を上回っているため、エラーで終了します。
total_statement_memory_limitは、システム全体で同時に実行可能なSQLステートメントが使用できるメモリ量の上限を定義する設定です。これにより、複数のSQLが並行して実行される際に、メモリ使用量が過剰にならないよう制御します。(初期設定は0(無効))
障害ケース④:必須処理のメモリ量(300GB)がstatement_memory_limitを上回る場合
障害ケース④では、必須処理が必要とするメモリ量(300GB)がstatement_memory_limit(243GB)を上回るため、エラーが発生し、処理が実行できず業務に支障をきたします。
この状況では、メモリの空きに余裕がある場合にのみ処理を実行したいものの、物理メモリは予算の都合で増設できず、さらにリスクを考慮してstatement_memory_limitの値も増やせないという課題があるとします。
障害ケース④の対策:statement_memory_limit_threshold
障害ケース④でstatement_memory_limit_thresholdが設定されていた場合、1つ目のSQL実行時には使用メモリがstatement_memory_limit_thresholdを下回っているため、statement_memory_limitが無効となり、正常に実行されます。
一方、2つ目のSQL実行時には使用メモリがstatement_memory_limit_thresholdを上回るため、statement_memory_limitが有効となり、処理はエラーで終了します。
statement_memory_limit_thresholdはstatement_memory_limitを有効にする閾値を決めるパラメータです。使用メモリが閾値を超過している時のみstatement_memory_limitが有効となります。(初期値は0(GB))
まとめ
最後にまとめです。
本記事のような障害に出くわした際は、statement_memory_limit、total_statement_memory_limit、statement_memory_limit_thresholdの設定を検討してみて下さい。
このようなメモリ障害は、アプリ担当とBasis担当の双方が仕組みを理解した上で対策を決める必要があります。とはいえ図解している情報がほとんどなく理解が難しいので、今回は図解にしてみました。システム安定化のヒントになれば幸いです。(もし間違っていたことを書いていたらゴメンなさい)
おまけ①:SE16/SE16NからCDS viewを開かないでください
おまけです。SAP Note 3251583で公開されている通り、SE16/SE16NからCDS viewを開かないでください。普通に数100GB〜数TBのメモリを消費して、本記事の障害を起こす可能性があります。(本記事の対策済みであれば単にエラーとなります)
https://userapps.support.sap.com/sap/support/knowledge/en/3251583
おまけ②:メモリを増設すれば良いのでは?
ちまちまメモリのパラメータをチューニングするのではなく、メモリを増設すれば良いのでは?と思う方もいらっしゃるかもしれません。
しかし、1TBで足りないから少し増やして1.2TBみたいなことはできず、クラウドで用意されているVMのメモリ単位は、大きくしたい場合は2TB、2TBより増やしたい場合は4TBだったりします。そして利用料も月額100万円だとすると、メモリを倍にすると200万円になったりします。すると年間の差額が単純計算で1200万円なってしまうため、簡単な話ではありません。
また、そもそも本記事例の数百GBの処理であればともかく、数TBも喰うような処理があるとすれば明らかにクエリに問題があります。そのような処理は日増しにメモリ使用量が増える傾向にあるので、いくらメモリを増やしたところでイタチごっこになってしまいます。
おまけ③:Workload classes(ワークロードクラス)
本記事のメモリパラメータはシステム全体に対しての設定になりますが、Workload classes(ワークロードクラス)という機能を用いると、クライアントセッション毎に設定することができるようです。ただし、この機能はかなり前から存在するものの、実際にはそこまで細かな運用をされているケースは少ないと思われます。少なくとも日本語の記事は見当たりませんでした。
おまけ④:もっと詳しく知りたい方へ
本記事のメモリパラメータやSAP HANAのメモリーワークロードについて知りたい方は、以下のSAP Learningの記事が図解なのでおすすめです。
コメント