イベントに記録されるデータには、「常時採取するもの」と「異常時だけ採取するもの」と2タイプあります。「常時採取するもの」はイベントの種類が多いので実機計測、「異常時だけ採取するもの」は、設定やアプリケーションに依存するのでトラブル時を想定した机上見積りが必要です。
また、見積りが難しい場合の対処と定期的な保存についてもあわせて説明します。
平常時での実機計測
平常時に単位時間あたりどれくらいのサイズになるかを実機計測します。
実際に運用するのと同様の環境で、数時間から数日間アプリケーションを動作させ、その際に作成されたチャンクファイルの日時とサイズから、単位時間あたりに必要なディスクバッファのサイズを求めます。
以下の例は、18時間実行後に作成されたチャンクファイルのリストになります。
2023/01/31 13:09 16,107,777 2023_01_31_11_40_52.jfr 2023/01/31 14:39 12,931,360 2023_01_31_13_09_02.jfr 2023/01/31 16:10 13,155,206 2023_01_31_14_39_29.jfr 2023/01/31 17:41 13,089,031 2023_01_31_16_10_28.jfr 2023/01/31 19:11 13,027,578 2023_01_31_17_41_29.jfr ・・・
約1.5時間毎に、12-3MBのファイルが生成されていることが分かります。このことから、1日当たりのディスク使用量は、約192MBと見積ることができます。
測定時間をM(日)、生成ファイルの合計サイズをA(バイト)、とすると、単位時間あたりのディスク使用量P(バイト/日)は、以下で求められます。
P = A / M |
何日間分のデータをディスクバッファに記録保持しておくかを決めます。
これは、トラブルが発生した場合に、過去何日分さかのぼってデータ分析をするかという、該当システムにおけるトラブル対処ポリシーに基づいて決めます。
保存期間をN(日)とすると、ディスクバッファに必要なサイズS(バイト)は、以下で求められます。
S = P × N |
異常時を想定した机上見積り方法
異常発生時は、異常を検知するイベントが増えるため、平常時に比べてディスクバッファの消費量が増えます。本手順では、異常時に発生する主なイベントのうち、特にディスクバッファ消費量に大きく影響を与える“ThreadDump”イベントのサイズ見積りを説明します。
異常発生時のプロセス状態を事前に予測することは一般的には難しいため、簡易的な見積り方法として、平常時に採取した“ThreadDump”イベントの内容をベースに算出することを推奨します。
“ThreadDump”イベントにおけるサイズにインパクトを与える要因は、以下です。
スレッド数 [T]
スレッド情報の平均サイズ [H]
スタックの平均的深さ [D]
メソッド名・ソースファイル名の平均的長さ [L]
異常時に“ThreadDump”イベントがE(回)発生するとした場合、異常時に増加するイベントサイズI(バイト)は以下で求められます。
I = T × ( H + ( D × L ) ) × E |
(注)“HighCPULoad”イベント/“HighThreadCPULoad”イベント発生時に記録する“ThreadDump”イベントは、1つの“HighCPULoad”イベント/“HighThreadCPULoad”イベントに対して3回発生します。
ポイント
以下の“ThreadDump”イベントのデータ(抜粋)例を基に見積り方法を説明します。
“ThreadDump”イベントデータは、イベントのヘッダー情報(1)とスレッドごとの情報[(2)、(3)、(4)]から構成されています。
ヘッダー部分のデータサイズは小さいため、見積りではスレッドごとの情報に着目します。
スレッドのデータは、スレッド情報[(2)、(5)、(7)]とスタックトレース情報[(6)(8)]から構成されています。
スレッド数 [T] : 3スレッド
上記例では、3つのスレッド数[(2)、(3)、(4)]のデータを示していますが、一般的なスレッドダンプイベントのデータには、多数のスレッドが含まれています。
スレッド情報の平均サイズ [H] : 216バイト
スレッド情報とは、各スレッドのスタックトレースに表示される、スレッド名・スレッドID・スレッドの状態などの情報です。
(2)(5)(7)では、58文字、133文字、133文字が含まれています。JFRのデータには、1文字あたり2バイトを使用して格納するため、合計648バイト(324文字×2バイト) 、その平均は216バイト(648バイト÷3 )となります。
スタックの平均の深さ [D] : 1.3
スタックの深さとは、スタックトレースで表示されるメソッド数の合計です。上記例の3スレッドは、以下になります。
スレッド名 | メソッド数 |
---|---|
DestroyJavaVM [図内(2)] | 0 (注) |
Thread-2 [図内(4)] | 2 |
Thread-1 [図内(6)] | 2 |
(注)スレッドによっては、スタックトレースが表示されない場合があります。
全スレッドで合計4つになり、3スレッドの平均は1.3(4メソッド ÷ 3スレッド)となります。
メソッド名・ソースファイル名の平均の長さ [L] : 202バイト
スタックトレースで1行あたりに表示されるメソッド名・ソースファイル名の長さを計算します。
上記例では、(6)の2行(202文字)と(8)の2行(202文字)の合計4行に含まれる404文字になります。JFRのデータには、1文字あたり2バイトを使用して格納するため、合計808バイト(404文字×2バイト)、4行の平均は202バイト(808バイト÷4)となります。
異常時に“ThreadDump”イベントが例えば6(回)発生したとすると、異常時に増加するイベントサイズIは、3011.4バイトとなります。
8614.8[I] = 3[T] × ( 216[H] + ( 1.3[D] × 202[L] ) ) × 6[E] |
平常時のディスクバッファに必要なサイズS +異常時に増加するイベントサイズI |
必要に応じて、この値に安全係数を乗じ、“-XX:FlightRecorderOptions”の“maxsize”パラメータに指定してください。
見積りが難しい場合の対処
サイズの見積りが難しく、ディスクに余裕がある場合は、ディスクバッファの保存期間だけを指定することで、異常時に記録されたイベント情報の削除を防ぐことが可能です。
保存期間を、R(日)に設定する場合は、以下のように指定します。
-XX:StartFlightRecording=maxage=Rd |
定期的な保存
ディスクバッファに記録するデータサイズが“maxsize”パラメータの値を超えた場合、データは削除されます。削除される前に、データを残す場合は定期的に保存してください。
以下のコマンドで、ディスクバッファを定期的にJFRログファイルにダンプしてください。
<OpenJDKインストールパス>/bin/jcmd <JavaアプリケーションのPID> JFR.dump name=<JFRの識別子> filename=<JFRログファイルの生成先> |