MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

24卒インフラ研修:自作PC編

はじめに

初めまして。マイクロアド24年新卒インフラエンジニアの齊藤( id:saitoperf )です。 今回は、インフラ研修で取り組んだ「自作PCの性能評価」について紹介します。

インフラ研修では、パーツ選定 → 組み立て → WordPressのデプロイ → 評価実験までの流れを体験しました。 マイクロアドではオンプレが主流のため、 インフラエンジニアは「コストを意識したサーバ調達 → ラッキング → 構築後のパフォーマンスチェック」の一連に対応できる必要があります。 また、これらの作業が終わった後にも、メモリやストレージの故障といった断続的に発生するインシデントにも対応していく必要があります。

そこで本研修では、今後これらのタスクへ対応できるようになるため、以下の素養を習得することを目的としています。

  • 調達の予算を10万円に設定することで、コストへの意識を育む
  • 実際に組み立てを行うことで、計算機を構成する装置の概要や設置方法を知る
  • パフォーマンスをチェックすることで、収集すべきメトリクス・チューニング方法・テストに関する技術を養う

環境構築

自作PCパーツの選定

24卒のインフラ配属は2人で、1人10万円以内の予算での好きにパーツを選定できたので、異なる特徴を持ったPCを2台組むことにしました。

  • 案1: とにかくCPUに予算を全振りする
  • 案2: メモリとSSDに予算を全振りする

コンピュータを構成する5大装置は、 演算装置、制御装置、記憶装置、入力装置、出力装置ですが、性能に大きく影響を及ぼすのは演算装置(CPU)と記憶装置(メモリ・SSD)になります。 そこで今回は、演算装置と記憶装置にそれぞれ性能を特化させて、パフォーマンスを比較することにしました。

パーツの購入は、基本的には価格.comを使って価格の安いショップ順にソートして購入しました。 途中で案2のSSDの価格が5千円上昇するなどのトラブルもありましたが、少しスペックダウンさせた別の商品を選ぶなどして無事10万円以内に収めました。 こちらは購入したパーツと購入時の値段になります。

表. 購入パーツ

案1(CPU性能重視案) 案2(I/O性能重視案)
CPU Intel Core i7-13700K/64,480円 Intel Core i5 12400/24,980円
メモリ ADATA AD4U266616G19-RGN/4,550円 Kingston KVR48U40BS8-16/6,280円
SSD ADATA LEGEND 700 ALEG-700-256GCS/3,480円 CFD PG5NFZ CSSD-M2M1TPG5NFZ/23,210円
CPUグリス MoneyQiu HY-883-2g/509円 JLJ TP-133/799円
電源 MSI MAG A650BNL/6,980円 玄人志向 KRPW-L5-400W/80+/REV2.0/6,045円
CPUクーラー Thermalright Assassin X 120 V2/2,049円 Thermalright Assassin X 120R SE/2,299円
マザーボード MSI PRO B760M-G DDR4/14,300円 ASRock Z790 Steel Legend WiFi/30,885円
PCケース ZALMAN T8 ミドルタワーPCケース/3,506円 ZALMAN T8 ミドルタワーPCケース/3,506円
合計価格 99,854円 98,004円

案1のCPUはコンシューマ向けとしてはかなり高性能で、価格も64,980円と案2の倍以上の金額でした。 一方案2では、SSDとメモリの世代を最新にしました。 また、マザーボードはメモリとSSDの世代に対応するものを使わないと性能を充分に発揮出来ないので、案1の倍の金額になりました。

下記の表はスペックの比較になります。 CPU性能を比較すると、案1は案2より最大クロック周波数が1 GHz高く、コア数も倍以上あります。 一方で、メモリ性能は案2の方が2倍弱高く、ストレージ性能はRead/Writeともに5倍高いです。

表. 自作のスペック比較

案1(CPU性能重視案) 案2(I/O性能重視案)
CPUモデル Core i7 13700K Core i5 12400
クロック周波数 5.4 GHz 4.4 GHz
物理コア数/スレッド数 16/24 6/12
L3キャッシュサイズ 30 MB 18 MB
メモリ DDR4-2666 16 GB DDR5-4800 16 GB
ストレージ
(read/write)
M.2 SSD Gen3
(1.9/1.6 GB/s)
M.2 SSD Gen5
(9.5/8.5 GB/s)

OSとWordPressのインストール

OSはUbuntu 24.04を使います。マイクロアドのインフラにはUbuntuとCentOSが使われていますが、現在は全面的にUbuntuへの移行を進めています。 マイクロアドではデータセンタに自社サーバを所有しており、 基本的にMAASを使ってベアメタルのサーバにOSをインストールしています。 しかし、今回の自作PCは渋谷のオフィスに設置するためMAASが使えないことから、USBでOSをインストールしました。 OSのインストールが完了したら、Ansibleを使って環境を構築します。 また、AnsibleのPlaybookを適用する前に、作成したPlaybookが期待した動作になるかテストするためにMolecule1を使いました。

※作業の様子です。

実験では、自作PC(以下TargetServer)の他に、負荷をかけるためのサーバ(以下RequestServer)とAnsibleを実行するTestServerを用意します。

  • TargetServer: Dockerエンジンを入れてWordPressコンテナを起動させる
  • RequestServer: K6というOSSの負荷テストツールを入れて、TargetServerに対して負荷テストを実施する
  • TestServer: Ansibleを実行したり、各サーバに対して実験のコマンドを流す

評価実験

実験ケース

K6は、実験のシナリオを記載したJavaScriptのコードを基に、負荷テストを実施します。 スクリプトには「リクエストを送るURL」「仮想ユーザ数(リクエストを送るスレッドのような概念)」「実験時間」のような様々な情報を記載することができます。 案1(CPU性能を重視)と案2(ディスクI/Oを重視)のパフォーマンスを比較するため、4つの実験ケースを用意しました。 ケース1から3は、データをアップロードすることでディスクへの書込みを発生させるため、 CPUとディスクの両方に負荷がかかるような実験となっています。 またケース1から3では、ディスクの読込みが発生しないので、ケース4でディスク読込みが発生するような実験を実施します。

  • ケース1
    • 実験名: submit_article (記事の投稿)
    • API: http://<TargetServer URL>/wp-json/wp/v2/posts
    • 概要: タイトルが「Sample articles」、コンテンツが「テスト投稿」という記事を投稿
  • ケース2
    • 実験名: submit_comment (コメントの投稿)
    • API: http://<TargetServer URL>/wp-json/wp/v2/comments
    • 概要: ある記事に対して、20文字のランダム文字列のコメントを投稿
  • ケース3
    • 実験名: submit_picture (画像のアップロード)
    • API: http://<TargetServer URL>/wp-json/wp/v2/media
    • 概要: 画像(2MB)をWordPress上にアップロード
  • ケース4
    • 実験名: download_picture (画像のダウンロード)
    • API: http://<TargetServer URL>/wp-content/uploads/2024/06/image-xxx.png
    • 概要: 予め投稿しておいた1000枚の画像をランダムでダウンロード

WordPressでは、デフォルトのパーマリンク設定ではAPIが叩けないのでPost nameに変更します。 パーマリングの設定はWebの管理画面からでも変更できますが、 WordPressのCLIツールのwp使って変更することもできます。

wp option update permalink_structure '/%postname%/'

実験の流れ

各実験ケースに対して以下の処理を実施します。

  • まず、TargetServerでページキャッシュをクリアしてから、sarコマンドを実行して1秒置きにリソース状況をresult_sar.binに記録する
  • 次に、K6でRequestServerからTargetServerに1分間負荷をかける
  • K6の負荷テストが終わったらsarコマンドを終了させ、TargetServer上でresult_sar.binをjson形式に成型してscpでTestServerにコピーする

TargetServer上でjsonへの変換まで実施する理由は、sarコマンドが入っているsysstatパッケージのバージョンが異なると、 バイナリファイルから正しくjsonに変換できないためです。

また、vm.dirty_ratioというページキャッシュに関するカーネルパラメータをデフォルトの20から0に変更した場合の実験も実施します。 ページキャッシュ内のダーティなデータの割合がvm.dirty_ratioを超えるとディスクへの書込みが発生します。 TargetServer2台、4つの実験ケース、2つのvm.dirty_ratioで、計16回の負荷テストを行いました。

事前調査

K6による負荷テストを実施する前に、メモリI/OとディスクI/Oを調べます。

メモリI/Oの計測にはsysbenchを使いました。 メモリI/Oは、案1の方が良いパフォーマンスとなりました。 メモリは案1がDDR4なのに対して案2がDDR5なので、案2の方が高いメモリI/O性能となることが予想されましたが、予想とは異なる結果となりました。 原因として、CPUキャッシュ容量が大きい事や、CPUクロックに引張られて性能が出ていない、といったことが考えられます。 また、BlockSizeを大きくするとスペック値を超えることが分かりました。 これは、シーケンシャルなアクセスが増えるため、CPUキャッシュにヒットしている可能性が考えられます。

表. メモリI/O [GiB/sec](Read/Write)

スペック値 BlockSize=64B BlockSize=1kiB BlockSize=1MiB
案1 (CPU性能重視) 20.8 0.94/0.93 13.8/11.7 57.2/43.8
案2 (I/O性能重視) 37.5 0.76/0.76 11.3/9.64 53.6/36.4

ディスクI/Oは、案2の方が良いパフォーマンスとなりました。 案1のhdparmbonnie++の結果がスペック値を超えている原因は、メモリのページキャッシュを使っている可能性が考えられます。

表. ディスクI/O [GiB/sec](Read/Write)

スペック値 hdparm dd seq dd rand bonnie++
案1 (CPU性能重視) 1.9/1.0 2.2/- -/0.82 -/0.49 1.8/1.6
案2 (I/O性能重視) 9.5/8.5 3.7/- -/1.5 -/0.49 3.4/2.7

K6による負荷実験

リクエスト・レスポンスの時間

submit_picture以外のリクエストでは、案1の方が良いパフォーマンスとなりました。 特にsubmit_commentでは、ほとんどの統計値に置いて倍近くの差がありました。 事前調査では、案1の方がCPU性能とメモリI/O性能の実測値においてパフォーマンスが優れていたので妥当な結果でした。

表. 応答時間の統計値 [ms] (CPU性能重視案/I/O性能重視案)

中央値 平均値 最小値 最大値 p(95)
submit_article 32.4/40.5 36.6/42.8 22.9/25.3 130/150 61.0/62.3
submit_comment 26.5/51.3 27.8/52.0 13.8/33.0 82.4/146 43.0/64.8
submit_picture 586/714 586/716 520/642 726/912 612/782
download_picture 53.4/63.6 72.0/71.8 17.7/23.7 682/730 183/118

CPU使用率

download_pictureは、他と比べてCPUリソースを使わないことが分かりました。 そのために、前述のリクエスト・レスポンス時間が案1と案2で唯一拮抗していたと考えられます。

案1: CPU使用率
案2: CPU使用率

ロードアベレージ

ロードアベレージ一般的に、以下のように言われています。

  • コア数の半分: 穏やか
  • コア数と同じ: フル活用
  • コア数より多い: 過負荷

案1はロードアベレージがコア数の半分程度なのでCPUは穏やかに稼働している一方で、 案2ではコア数よりロードアベレージが2~3多くCPUは過負荷状態でした。

案1: ロードアベレージ
案2: ロードアベレージ

メモリ使用量

メモリはどちらの案においてもほとんど使われないことが分かりました。

ページキャッシュは、download_picturesubmit_pictureで大きく使われることが分かりました。 download_pictureは、予めアップロードしてある1000枚の画像をランダムにダウンロードするので、 最初の30秒程度で、ディスク上にあるほとんどの画像データがキャッシュされています。 submit_pictureは、次々に画像をアップロードするリクエストなので、線形的に増加しています。

案1: メモリ使用量
案2: メモリ使用量
案1: ページキャッシュ使用量
案2: ページキャッシュ使用量

ディスクI/O:読込み

download_picture以外のリクエストでは、ディスク読込みはほとんど発生しませんでした。 一方で、download_pictureでは、ディスク読込みが開始30秒あたりまで発生しています。 これは、実験開始から30秒程度でページキャッシュにキャッシングされたことが原因だと考えられます。 また、どのリクエストにおいてもTargetServer間での差は見られませんでした。

案1: ディスク読込み
案2: ディスク読込み

ディスクI/O:書込み

submit_pictureに関しては、案1の方が10 [kB/sec] 程度大きくなりました。 これは、K6で送ったリクエスト数が単純に多かったことが考えられます。 K6の仮想ユーザは、レスポンスを受け取ってから次のリクエストを発行するため、 応答時間が長いとその分送るリクエスト数も減少します。

特定のタイミングでスパイクしているのは、ある程度メモリ(ページキャッシュ)に書き込まれたタイミングで一気にストレージに書込むためです。 カーネルパラメータvm.dirty_ratioの値を変更することで、 ページキャッシュとストレージの齟齬が何%になったらストレージへ書込むかを変更できます。 vm.dirty_ratioを0にすると、スパイクは発生せず継続的にストレージへの書込みが発生しました。

案1: ディスク書込み (vm.dirty_ratio=20)
案2: ディスク書込み (vm.dirty_ratio=20)
案1: ディスク書込み (vm.dirty_ratio=0)

表. リクエスト・レスポンス数

案1: 成功 案2: 成功 案1: 失敗 案2: 失敗
submit_article 13063 11189 0 0
submit_comment 17098 9199 0 0
submit_picture 822 673 0 0
download_picture 6615 6615 0 7

実験のまとめ

WordPressを動作させる場合、CPU性能重視案(案1)の方がI/O性能重視案(案2)よりもパフォーマンスが良くなるという結果になりました。 ただし今回の場合、CPU性能が低くメモリ性能を充分に発揮できていない可能性があるため、 一概にI/O性能よりもCPU性能の方が重要だとは断言できません。

また、画像ダウンロードなどのストレージ読込みが多く発生するようなワークロードの場合、 ページキャッシュの恩恵が大きいということが分かりました。 ただし、ページキャッシュに乗り切らなくなるような状況は、本実験では実現できなかったので、 そのようなケースディスクI/O性能がどのように効いてくるのかは要調査です。

おわりに

インフラ研修では、自作PCのパーツ選定から負荷実験までを行いました。 自作PCを組み立てるのは初めてだったので、楽しく作業を進めることができました(最近はノートパソコン生活です)。 パーツの選定では、限られた予算の中で最良のパーツを選んでいくという作業を経験したので、 今後業務でサーバ選定をする機会に役立てられたら良いです! 実は、組み立ての際にCPUピンを曲げてしまったり、PCケースが不良品でボタンが押せなかったり色々ありましたが、 最終的には結果のグラフ化までできてこうしてブログが書けてよかったです!

新卒インフラエンジニア絶賛採用中

マイクロアドでは技術への探究心があり、最新の技術・動向について積極的に学び活かす意欲を持った仲間を募集しています! またインフラエンジニアだけでなく、サーバサイド、機械学習エンジニアなど幅広く募集しています! 気になった方は以下からご応募ください!

recruit.microad.co.jp


  1. Moleculeは、コントロールノード(Ansibleコマンドを実行するノード)上にコンテナや仮想マシンを起動して、これらに対してAnsibleコマンドを実行してテストするツールです。