Agent Skills by ALSEL
Anthropic ClaudeDevOps・インフラ⭐ リポ 299品質スコア 89/100

run-jmh-benchmarks-hetzner

Hetzner CCX33サーバーをプロビジョニングし、プロジェクトをデプロイしてJMHベンチマークを実行し、結果を収集した後、サーバーを削除します。ユーザーがHetznerサーバーでJMHベンチマークの実行を明示的に要求した場合のみ使用してください。一般的なベンチマーク要求やローカルベンチマーク実行では自動実行しません。

description の原文を見る

Provision a Hetzner CCX33 server, deploy the project, run JMH benchmarks, collect results, and destroy the server. Use ONLY when the user explicitly asks to run JMH benchmarks on a Hetzner server. Do NOT trigger for general benchmark requests or local benchmark runs.

SKILL.md 本文

Hetzner で JMH ベンチマークを実行

専用の Hetzner クラウドサーバーをプロビジョニングし、現在の作業ツリーをデプロイして、任意のモジュールから JMH ベンチマークを実行し、結果をダウンロードして、サーバーを停止します。

前提条件

  • hcloud CLI がインストールされて認証されている (hcloud version で確認)
  • SSH キーペアが ~/.ssh/id_ed25519 (または ~/.ssh/id_rsa) に存在
  • ベンチマークモジュールがローカルでコンパイルできる

ワークフロー

ステップ 0: ベンチマークモジュールとパラメーターを決定

ユーザーに確認するか、コンテキストから推測して、どのベンチマークモジュールを実行するかを決定します。プロジェクトに複数の JMH ベンチマークモジュールが含まれることがあります。一般的な例:

  • jmh-ldbc — LDBC SNB 読み取りクエリベンチマーク(ユーザーが「ベンチマークを実行」と言った場合のデフォルト)
  • JMH 依存関係を持つ他のモジュール — pom.xmljmh-core 依存関係を確認

以下を決定します:

  • モジュール名 (-pl <module>)
  • JMH 正規表現フィルター (含める/除外するベンチマーク)
  • JMH パラメーター (フォーク数、ウォームアップ、測定反復)

デフォルト値(比較実行に適切):

  • -f 1 -wi 3 -w 5s -i 5 -r 10s

jmh-ldbc の場合:

  • 予想実行時間: -f 1 -wi 3 -w 5s -i 5 -r 10s で約 40 ベンチマーク(20 クエリ x 2 スイート)に対して約 90 分

ステップ 1: サーバーをプロビジョニング

命名規約: サーバーに jmh-bench-<branch>、SSH キーに jmh-bench-key-<branch> を使用します。ここで <branch> は現在の git ブランチ名です(サニタイズ: 小文字、スラッシュをダッシュに置換、合計名を 63 文字以下に切り詰め)。これにより、異なるブランチで複数のベンチマーク実行が同時に実行されるときの競合を回避できます。

# ブランチベースの名前を決定
BRANCH=$(git rev-parse --abbrev-ref HEAD | tr '[:upper:]/' '[:lower:]-' | cut -c1-40)
SERVER_NAME="jmh-bench-${BRANCH}"
KEY_NAME="jmh-bench-key-${BRANCH}"

# ローカル SSH 公開鍵をアップロード
hcloud ssh-key create --name "$KEY_NAME" --public-key-from-file ~/.ssh/id_ed25519.pub

# CCX33 を作成: 8 個の専用 AMD vCPU、32 GB RAM、Falkenstein DC
hcloud server create --name "$SERVER_NAME" --type ccx33 --image ubuntu-24.04 --location fsn1 --ssh-key "$KEY_NAME"

出力から IPv4 アドレスを記録します。SSH を試行する前に、サーバーがブートするまで約 15 秒待ちます。

SSH がホストキーの競合で失敗する場合は、古いキーを削除します:

ssh-keygen -f ~/.ssh/known_hosts -R <IP>

ステップ 2: JDK 21 をインストール

ssh -o StrictHostKeyChecking=no root@<IP> \
  'apt-get update -qq && apt-get install -y -qq openjdk-21-jdk-headless git tmux > /dev/null 2>&1 && java -version'

ステップ 3: プロジェクトをデプロイ

ワークツリーのルート(mvnwpom.xmlcore/ などを含むディレクトリ)を rsync で転送します。.gittarget.idea は除外します:

rsync -az --exclude='.git' --exclude='target' --exclude='.idea' <worktree-root>/ root@<IP>:/root/ytdb/

重要: 作業ディレクトリ(例: /workspace/ytdb/ldbc-jmh)は git ワークツリーの場合があります — ルートに mvnw を含む完全なプロジェクトツリーが含まれています。このディレクトリを rsync してください。親ディレクトリ /workspace/ytdb/ ではなく。

次に、サーバー上で git リポジトリを初期化します(Spotless に必要):

ssh root@<IP> 'git config --global --add safe.directory /root/ytdb && \
  git config --global user.email "bench@test" && \
  git config --global user.name "bench" && \
  cd /root/ytdb && git init && git add -A && git commit -m "baseline" --quiet'

ステップ 3b: Hetzner S3 からデータセットをダウンロード(jmh-ldbc のみ — 必須)

LDBC データセットはベンチマーク実行前にあらかじめダウンロードする必要があります。ベンチマークは SURF から自動ダウンロードしなくなりました(SURF 形式は互換性がありません)。Hetzner Object Storage (S3) からダウンロードします:

ssh root@<IP> 'apt-get install -y -qq python3-pip zstd > /dev/null 2>&1 && \
  pip install --break-system-packages boto3 -q && \
  mkdir -p /root/ytdb/<module>/target/ldbc-dataset/sf0.1 && \
  python3 -c "
import boto3, os
s3 = boto3.client(\"s3\",
    endpoint_url=os.environ[\"S3_ENDPOINT\"],
    aws_access_key_id=os.environ[\"S3_ACCESS_KEY\"],
    aws_secret_access_key=os.environ[\"S3_SECRET_KEY\"])
print(\"Downloading dataset from S3...\")
s3.download_file(\"bench-cache\", \"ldbc/ldbc-sf0.1-composite-merged-fk.tar.zst\", \"/tmp/dataset.tar.zst\")
print(\"Downloaded\")
" && \
  cd /root/ytdb/<module>/target/ldbc-dataset/sf0.1 && \
  zstd -d /tmp/dataset.tar.zst -o /tmp/dataset.tar && \
  tar xf /tmp/dataset.tar && \
  rm -f /tmp/dataset.tar.zst /tmp/dataset.tar && \
  echo "Dataset ready" && ls static/ dynamic/'

重要: 上記のコマンドはリモートサーバー上の環境変数として S3 認証情報を必要とします。SSH 経由で渡します:

ssh root@<IP> "export S3_ENDPOINT='<endpoint>' S3_ACCESS_KEY='<key>' S3_SECRET_KEY='<secret>' && ..."

認証情報は GitHub シークレットとして保存されています: HETZNER_S3_ACCESS_KEYHETZNER_S3_SECRET_KEYHETZNER_S3_ENDPOINT。GitHub から取得するか、ユーザーに確認してください。

<module> をベンチマークモジュール(例: jmh-ldbc)に置き換えます。

データセットは LDBC datagen v1.0.0 CsvCompositeMergeForeign 形式(約 19 MB)を使用します。Hetzner Object Storage バケット bench-cache のキー ldbc/ldbc-sf0.1-composite-merged-fk.tar.zst に保存されています。

S3 認証情報が利用できない場合、LDBC datagen Docker イメージを使用してデータセットをローカルで生成し、サーバーに rsync で転送します:

# ローカルマシン上
docker run --rm \
    -v "$(pwd)/jmh-ldbc/target/ldbc-dataset/sf0.1:/out" \
    ldbc/datagen:latest \
    --scale-factor 0.1 --mode raw --format CsvCompositeMergeForeign

# その後、データセットをサーバーに rsync
rsync -az jmh-ldbc/target/ldbc-dataset/ root@<IP>:/root/ytdb/jmh-ldbc/target/ldbc-dataset/

repository.surfsara.nl の SURF リポジトリを使用しないでください — CsvComposite 形式(v0.3.5)を提供しており、ベンチマークローダーが期待する形式と互換性がありません。

ステップ 4: コンパイル

ssh root@<IP> 'cd /root/ytdb && chmod +x mvnw && \
  ./mvnw -pl <module> -am compile -DskipTests -Dspotless.check.skip=true -q'

<module> をターゲットベンチマークモジュール(例: jmh-ldbc)に置き換えます。

BUILD SUCCESS を待ちます(通常 CCX33 で 60 〜 90 秒)。

ステップ 4b: LDBC データセットをプリロード(jmh-ldbc のみ)

jmh-ldbc の場合重要: LDBC データセットはダウンロードされ、JMH の @Setup(Level.Trial) メソッド内でデータベースにロードされます。これは最初のフォークのウォームアップ反復にデータセットダウンロード + DB 作成時間が含まれることを意味します。マルチスレッドベンチマークでは、スレッドが部分的にロードされたデータベース上でクエリ実行を開始し、非常に不正確な結果(例: 実際のスループットが約 3 ops/s のときに 300+ ops/s)を生成します。

実際のベンチマーク実行前に、常にデータセットをプリロードします:

ssh root@<IP> 'cd /root/ytdb && ./mvnw -pl <module> -am verify -P bench -DskipTests -Dspotless.check.skip=true \
  -Djmh.args="ic5_newGroups -f 0 -wi 0 -i 1 -r 1s -t 1" 2>&1 | tail -20'

これは単一のプロセス内反復(-f 0)を実行し、データセットダウンロードと DB 作成をトリガーします。その後のフォーク済み実行は、./target/ldbc-bench-db 既存の DB を見つけてロードをスキップします。

ステップ 3b 経由でデータセットをプリダウンロードした場合: プリロードステップはまだ必要です — CSV ファイルから YouTrackDB データベースを作成します。ただし、データセットファイルが既に target/ldbc-dataset/ に存在するため、ダウンロードフェーズは自動的にスキップされます。

2 つのコードバージョンを比較する場合(A/B テスト): バージョン A の実行後、バージョン B を実行する前にベンチマークデータベースを削除して、古いキャッシュされたデータを回避します:

ssh root@<IP> 'rm -rf /root/ytdb/jmh-ldbc/target/ldbc-bench-db'

データセットファイル(target/ldbc-dataset/)は保持できます — DB のみを再作成する必要があります。

ステップ 5: ベンチマークを実行

重要: 同じサーバー上で複数のベンチマークを同時に実行しないでください。常に 1 つのベンチマーク実行が完了するまで待ってから、次を開始します。

tmux セッションでベンチマークを開始して、SSH 切断後も実行し続けるようにします。

モジュールに bench Maven プロファイルがある場合(jmh-ldbc など):

ssh root@<IP> 'tmux new-session -d -s bench \
  "cd /root/ytdb && ./mvnw -pl <module> -am verify -P bench -DskipTests -Dspotless.check.skip=true \
  -Djmh.args=\"<jmh-args> -rf json -rff /root/results.json\" \
  2>&1 | tee /root/bench.log"'

モジュールが uber-jar を生成する場合:

ssh root@<IP> 'tmux new-session -d -s bench \
  "cd /root/ytdb && java -jar <module>/target/benchmarks.jar \
  <jmh-args> -rf json -rff /root/results.json \
  2>&1 | tee /root/bench.log"'

JMH パラメーターの説明:

  • -f 1 — 1 フォーク(比較実行に十分; 出版向けの結果には -f 3 を使用)
  • -wi 3 -w 5s — 3 ウォームアップ反復、各 5 秒
  • -i 5 -r 10s — 5 測定反復、各 10 秒
  • -e <pattern> — 正規表現に一致するベンチマークを除外
  • -rf json -rff /root/results.json — 結果を JSON として保存

ステップ 6: 進捗を監視

定期的に(5 〜 10 分ごと)ポーリングします:

# 完了したベンチマークをカウント
ssh root@<IP> 'grep "^Result" /root/bench.log 2>/dev/null | wc -l'

# 現在のベンチマークを確認
ssh root@<IP> 'tail -5 /root/bench.log'

# 完了したかどうかを確認
ssh root@<IP> 'grep "^# Run complete\|BUILD" /root/bench.log'

ステップ 7: 結果を収集

# Run complete がログに表示されたら:

# JSON 結果をダウンロード
scp root@<IP>:/root/results.json /tmp/claude-code-results.json

# サマリーテーブルを表示
ssh root@<IP> 'grep "^Benchmark\|thrpt\|avgt" /root/bench.log | head -60'

JSON をプロジェクトディレクトリにわかりやすい名前でコピーします:

cp /tmp/claude-code-results.json <module>/<name>-results-ccx33.json

ステップ 8: サーバーを破棄

常にクリーンアップして料金を回避します。ステップ 1 の同じブランチベースの名前を使用します:

hcloud server delete "$SERVER_NAME"
hcloud ssh-key delete "$KEY_NAME"

ステップ 9: 結果を比較

ベースラインデータが存在する場合(例: メモリファイルまたは前の JSON)、以下を含む比較テーブルを表示します:

  • ベンチマーク名
  • ベースラインスコア
  • 新規スコア
  • パーセント変化
  • 評価(回帰 / ノイズ / 改善)

マルチスレッドベンチマークでは、約 5 〜 7% 以内の変化は通常、測定ノイズです。シングルスレッドベンチマークはより安定しています(約 2 〜 3% のノイズフロア)。

トラブルシューティング

問題解決策
mvnw: No such file or directory間違ったディレクトリを rsync しました。mvnw を含むワークツリーのルートを rsync してください。
SSH ホストキー競合ssh-keygen -f ~/.ssh/known_hosts -R <IP>
detected dubious ownershipgit config --global --add safe.directory /root/ytdb
JMH がハングするか再起動が必要ssh root@<IP> 'rm -f /tmp/jmh.lock' 次に tmux で再実行
コアテストコンパイル失敗コンパイルコマンドに -Dmaven.test.skip=true を追加
リアルタイム出力が必要tmux + tee を使用(上記のコマンドに既に含まれています)
MT ベンチマークで ops/s がワイルドまたは不安定データセットがプリロードされていません。最初にステップ 4b を実行してください。最初のフォークはウォームアップ中に DB をロードし、MT スレッドは部分的にロードされたデータを見ます。
新規サーバーで apt-get ロックunattended-upgrades が終わるまで 30 秒待ってから、再試行します。
セットアップ中にデータセットが見つからないエラーデータセットは ステップ 3b(Hetzner S3)経由でプリダウンロードする必要があります。ベンチマークは SURF からの自動ダウンロードを行わなくなりました。

注記

  • サーバータイプ: CCX33 は 8 個の専用 AMD EPYC vCPU を提供します — 専用(共有ではない)コアは一貫したベンチマーク結果を保証します。より重いベンチマークの場合は、CCX43(16 vCPU)または CCX53(32 vCPU)を検討してください。
  • jmh-ldbc Threads.MAX: マルチスレッド LDBC ベンチマークは @Threads(Threads.MAX) を使用します — 利用可能なプロセッサーごとに 1 スレッド。CCX33 ではこれは 8 スレッドを意味します。
  • jmh-ldbc データセットローディング: LDBC データセットはステップ 3b(Hetzner S3)経由でプリダウンロードする必要があります — ベンチマークは SURF から自動ダウンロードしなくなりました。DB 作成は初回実行時に LdbcBenchmarkState.@Setup(Level.Trial) 内で行われます。実際のベンチマーク前に -f 0 でプリロード(ステップ 4b を参照)します。DB パスは ./target/ldbc-bench-db です。データセットキャッシュは ./target/ldbc-dataset/ です。
  • ベンチマークを同時に実行しない: 同じサーバー上の複数の JMH プロセスは CPU をめぐって競合し、信頼性の低い数値を生成します。常に一度に 1 つずつ実行します。
  • Ubuntu apt ロック(新規サーバー): 新しくプロビジョニングされた Ubuntu 24.04 サーバーは初回ブートで unattended-upgrades を実行します。apt-get install が「Could not get lock」で失敗した場合は、30 秒待ってから再試行してください。
  • メモリファイル: LDBC ベンチマークの場合、各実行後に自動メモリディレクトリの ldbc-jmh-benchmarks.md を新しい結果で更新します。
  • S3 データセットキャッシュ: LDBC データセットアーカイブ(ldbc-sf0.1-composite-merged-fk.tar.zst、約 19 MB、datagen v1.0.0 CsvCompositeMergeForeign 形式)は Hetzner Object Storage バケット bench-cacheldbc/ldbc-sf0.1-composite-merged-fk.tar.zst にキャッシュされています。認証情報は GitHub シークレット HETZNER_S3_ACCESS_KEY / HETZNER_S3_SECRET_KEY / HETZNER_S3_ENDPOINT に保存されています — コードにハードコードしたり、リポジトリにコミットしたりしないでください。
  • S3 アクセスなしでデータセット: S3 認証情報が利用できない場合は、LDBC datagen Docker イメージを使用してローカルでデータセットを生成します: docker run --rm -v "$(pwd)/jmh-ldbc/target/ldbc-dataset/sf0.1:/out" ldbc/datagen:latest --scale-factor 0.1 --mode raw --format CsvCompositeMergeForeign。次に、生成されたデータセットをサーバーに rsync します。詳細は jmh-ldbc/README.md を参照してください。
  • SURF を使用しない: SURF Data Repository(repository.surfsara.nl)は CsvComposite 形式(v0.3.5)を提供しており、ベンチマークローダーが期待する CsvCompositeMergeForeign カラムレイアウトと互換性がありません

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
majiayu000
リポジトリ
majiayu000/claude-skill-registry
ライセンス
MIT
最終更新
2026/5/4

Source: https://github.com/majiayu000/claude-skill-registry / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: majiayu000 · majiayu000/claude-skill-registry · ライセンス: MIT