【翻訳】Aerospike on Amazon EC2 で 100万TPS をたった 1.68 ドル/時 で実現する方法
2020/08/31
原文: http://highscalability.com/blog/2014/8/18/1-aerospike-server-x-1-amazon-ec2-instance-1-million-tps-for.html (2014-9-25)
Amazon EC2のようなクラウドインフラストラクチャサービスは、特筆すべき成功を収めてその価値を証明しています。必要な時に時間単位の課金でスケールアップできるその容易さは、開発者の創造性を解き放ちました。しかし、仮想化環境は高性能なアプリケーションとデータベースを実行するための場所としては広く考えられていません。
クラウド·プロバイダーは、その製品が長い道のりを経たとはいえ、彼らのパフォーマンスを再び審査する必要が出てきました。ベアメタルサーバー上の Aerospike で100万 TPS を達成した後、私たちは、クラウドのパフォーマンスを調査し、その過程で「クラウド != ハイパフォーマンス」という神話を打ち破ることを決めました。
私たちは、様々な Amazon インスタンスを検討し、1台の C3.8xlarge インスタンスの 1 Aerospike サーバーで、100万 TPS を RAM で処理するための設定を発見しました。たった 1.68ドル/時間 です!
internetlivestats.com によると、毎秒 7.5k の新しいつぶやき、毎秒 45K グーグル検索、毎秒 230 万件の電子メール送信があります。たった 1.68ドル/時間で毎秒100万のデータベーストランザクションを処理することができれば、あなたは何を構築しますか?
この投稿には、前例のないレベルのコストパフォーマンスをあなた自信が実現するため、私達の数多の Amazon EC2 インスタンス運用の経験と発見、推奨チューニング設定や指示が記録されています。
特に明記しない限り、私たちは次の設定でこの検証を行っています。
- 1台の Amazon インスタンス上では 1台の Aerospike インメモリ NoSQL DB サーバーが動いている。
- データオブジェクトは 1,000 万個で、それぞれのサイズは100バイト。※Bin (カラム)は 10 個でサイズは各 10 bytes(使用した全てのインスタンスでメモリ(RAM)内にデータを乗せきるためにオブジェクトのサイズを小さく保った)
- Aerospike Javaクライアントに付属しているJava のベンチマークツールを使用。クライアントプロセスは、サーバーインスタンス外で動く。クライアントインスタンスは、負荷を最大にするように Aerospike サーバに並列に処理を投げるようになっていて、使用される正確なサーバ台数は、各サーバインスタンスの種類に依存する。
- 読み取り件数を最大にするために、データの保持設定をインメモリ(RAM)にし、全てのキーに対する読み取りリクエストを行い、書き込みはしなかった。
- コスト最適化のためにスポットインスタンスを使用した。スポットインスタンスとオンデマンドインスタンスは、パフォーマンスの面でほぼ同じ性能を示した。
手順1:インスタンス·タイプを選択する
私たちは、以下の要件に基づいてインスタンスを探した。
- メモリ内にデータセット全体を保持できる
- 必要なトランザクション·レートを達成できるネットワークとCPUの性能
今回は全て RAM 上で完結させたため、高いストレージ性能を持つ i2 と hs1 インスタンスは考慮しませんでした。
私たちは、EC2インスタンスの種類の数を調べました。
- R -メモリ最適化
- C -計算能力最適化
- M – RとCの中間
- T -非常にローエンドの初心者向け
異なるインスタンスタイプは、ネットワークの性能も異なるため、私達は各タイプのマシンを選んで、iperf というツールを使用して帯域幅の上限を計測し、できる限り多くのクライアントから大きなサイズのパケットをプッシュしました。これらの各マシンでは、以下の帯域幅の制限が見つかりました:
- モデレート(上限 100Mbps)
- High(300Mbps から 1.8Gbps まで)
- 10ギガビット(ピーク時で 8.8 Gbps 周辺)
「低」から「中」のネットワーキングパフォーマンスを持つインスタンスの場合、ネットワークがボトルネックとなってしまうため、私たちは、「低」のネットワーキングパフォーマンスであると Amazon が規定している t1 と m1.small は考慮しませんでした。また、Mシリーズのインスタンスは、今回の検証の時点では拡張ネットワーキングをサポートしていません。
手順2:仮想化タイプを選択する
アマゾンは、準仮想化(PV)と、完全に仮想化された一連のハードウェアを備える仮想化(HVM)をサポートする Xen というオープンソースの仮想化プラットフォームを使用しています。私たちは両方のタイプを試してみました:
- 準仮想化(PV)マシン :まず手始めに、私たちはc3.8xlargeを選びました。これらは高価なインスタンスですが、私たちは期待値の感触を得るためにそれ選びました。このインスタンスでは、EC2-クラシックネットワーク内の PV AMI を使用して開始しました。これらのマシンは、10Gbps と評価されていますが、私たちがこのマシンから得られた値は 1.8 〜 2.2 Gbps(iperfの結果)で、約85Kパケット/秒の制限がかけられていることを発見しました。次に私たちは、決まったパターンがあるのかどうかを確認するために C3.2xlarge を試してみましたが、このマシンも制限されていることがわかりました。重い負荷を実行しているときに top コマンドで CPU の利用状況を見ると、PV は割り当てられたCPUの40%まで消費している事に気付きました。私たちは、これらのインスタンス上にも同様に Aerospike で 85 ktpsを達成することができ、再び明らかな制限がかかりました。
- ハードウェア仮想化マシン :拡張ネットワーキング付きのHVMベースのインスタンスは、AWSのドキュメント通りに、より良いネットワークを提供しています。私たちの検証では、追加のチューニング無しで、TPS が3倍に増加することを確認しました。クライアントとして同じグループ内で拡張ネットワーク設定を持つ c3.4xlarge インスタンスを配置して実行し、Aerospike は 215K TPS を出しました。
私達はさらなる検証のために、同じ価格で PV のインスタンスよりもはるかに優れている HVM インスタンスを選びました。
ステップ3:プレイスメントグループの使用
プレイスメントグループは、単一の Availability Zone 内のインスタンスの論理グループです。Amazon Virtual Private Cloud(VPC)内でプレイスメントグループを使用することで 、アプリケーションは低遅延なフルバイセクション 10 Gbps ネットワークを使用することができます。
私たちは、パフォーマンスを最大化するために、プレイスメントグループを使用していました。また、VPC は HVMインスタンスを使用するための前提条件でした。
ステップ4:テナントのテスト
私たちは、専用テナントと共有テナントの両方を試してみましたが、それらの間に有意な差を見つけることができず、共有テナントを選択しました。
ステップ5:CPU Steal を最小限に抑える
Amazonで実行中のプロセスにおける課題の一つは、計算能力への予測可能なアクセスが欠如していることです。CPU が過度に使用された場合、例えばスレッドが一気に大量の CPU を消費したとき等に、EC2 はその処理を終了することができます。しかし、次の処理により少ない量の CPU を割り当てます。これによりアプリケーションのスループットにピークと谷間が発生しますが、CPU バーストが起きないようにスレッドを絞ることによって回避することができます。このテクニックによって、アプリケーションをより一貫して動作させることができます。
われわれの検証では、CPU の過剰使用を避けるように Aerospike を調整することができました。結果として重負荷であってもほとんど steal が発生せず(0.2から0.7)、予測可能なパフォーマンスをもたらしました。
ステップ6:ネットワーク
インスタンスタイプ、仮想マシン、プレイスメントグループ、テナントを選択してチューニングした後も、私たちは TPS の処理をブロックする原因がわかりませんでした。インスタンスを見ると、システムが単一のコアであるため、割込み処理がボトルネックとなっていることがわかりました。各 NIC は、デフォルトでは一つのコアに一つの割り込みキューを提供しているだけのようでした。
私達は回避策を探しました。次の 4 つを試してみました:
- IRQ(割り込み要求)分配 :私たちは、IRQ を複数のコアに分配するようシステムを強制しようとし(disable irqbalance + echo ffff > *smp_affinity)、それが単一のリアルなコアに束縛されることが分かりました。一つの IRQ に対して、複数のリアルなコアに処理を分散させることはできません。
- Interrupt Coalescing :ソフトウェア割り込みが問題だと考えて、私たちも Interrupt Coalescing を試してみました。EC2 上では、それは CPU 使用率を少し改善しましたが、有効な解決策にはなりませんでした。
- NIC の追加:Elastic Network Interfaces(ENI)が助けに来てくれました! ENI はインスタンスに複数の(仮想)NICを追加する方法を提供します。単一の NIC ではピーク時 250ktps 程度で、コアの割り込み処理のボトルネックになります。複数のインタフェースを追加することが直接の助けになり、2つのインスタンス上で合計 4インターフェイス・4プロセスにした所、私たちは一つの c3.8xlarge インスタンスで 960kTPS まで得ることができました。私達は各クライアントから決められたインターフェイスに送信するようにして、それ以後は確実にすべての NIC と CPU を使用するようにしました。プライベートIPで ENI を使用するのは無料です。
- Receive Packet Steering(RPS) :別の簡単なアプローチは、RPS を使用して複数のコアに IRQ を分配することです(“echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus”)。これにより、管理が容易になり、複数のENISに私たちに同じようなTPSを与えた複数の NIC/ ENI を使用することの必要性を排除した。 RPS付きシングルNICが4コアに広がっ割り込みを800ktpsまでプッシュすることができますが有効。
NIC と RPS のさまざまな組み合わせと、いくつかの Aerospike クのチューニング(サービススレッドのオプションを適切に設定)を検証した結果、私達はとても高い性能を引き出すことが出来ました。5 台のクライアント(C3.2xlarge)から読み取り処理を受信する 1台の C3.8xlarge インスタンス上の Aerospike クラスタが、たった 1.68ドル/時間で 1M TPSを処理しました!!!
Instance type | Network type | Peak Observed bandwidth | TPS(max) | DI** cost / hr |
DI** cost/mo |
RI***cost/mo (1yr term) |
RI**cost/yr (1yr term) |
RI**cost/mo (3yr term) |
RI**cost/yr (3yr term) |
m3.xlarge | high | ~700Mbps | ~87k | 0.28 | 201.6 | 127.28 | 1534.24 | 81.2 | 526.6 |
m3.2xlarge | high | 1Gbps | ~87k | 0.56 | 403.2 | 253.12 | 3050.96 | 161.4 | 1052.2 |
c3.2xlarge* | high | 1Gbps | ~250k | 0.42 | 302.4 | 183.88 | 2215.04 | 121.8 | 789.4 |
c3.4xlarge* | high | 1Gbps | ~500k | 0.84 | 604.8 | 368.48 | 4438.84 | 242.6 | 1577.8 |
c3.8xlarge* | 10G | 8.86Gbps | 1000k | 1.68 | 1209.6 | 735.24 | 8868.92 | 484.48 | 3145.84 |
r3.large | moderate | ~600Mbps | 80ktps | 0.175 | 126 | 69.76 | 830.08 | 47.72 | 228.76 |
r3.xlarge | moderate | 1Gbps | 120ktps | 0.35 | 252 | 138.52 | 1660.16 | 95.44 | 456.52 |
r3.2xlarge* | high | 1Gbps | 250k | 0.7 | 504 | 276.04 | 3320.32 | 189.88 | 912.04 |
r3.4xlarge* | high | 1Gbps | 500k | 1.4 | 1008 | 551.08 | 6640.64 | 379.76 | 1823.08 |
r3.8xlarge* | 10G | 8.86Gbps | 1000k | 2.8 | 2016 | 1102.16 | 13281.28 | 759.52 | 3645.16 |
** RI = リザーブドインスタンス** DI = オンデマンドインスタンス
** コスト計算は全てそれぞれのインスタンスタイプ1台分です。リザーブドインスタンスは、期間は1年と3年で使用率は「重度使用」(100% の利用率)です。
注意:これらのインスタンスは、時には良いパフォーマンスや悪いパフォーマンスも示しています。これらの数字は、1ヶ月稼働させた中で見せた典型的な結果に基づいています。
*コアボトルネック:私たちは、複数の NIC と RPS の設定を使用して、多くの異なる組み合わせを試してみましたが、すべてのケースで %hi とコアがボトルネックになりました。CPU 使用率はピークのわずか約50%でした。
実行手順
以下の手順に従うことで、あなたもたった 1.68ドル/時で Amazon 上に 1M TPS の Aerospike サーバを再現でき、 Amazon EC2 のようなクラウド環境が非常に高いデータベース性能を実現しうる選択肢であることを示してくれます。
- サーバーは、AWS マーケットプレイスから HVM ベースの Aerospike を選択し、 VPC 内の c3.8xlarge インスタンスとしてセットアップします。プレイスメントグループを使用してください。
- サーバーインスタンスに ENI を4つ追加で取り付けます。追加したこれらの ENI には Elastic IP アドレス を使用する必要はありません。
- 各 Aerospike サーバー上のスレッド数を最適化するために、afterburner.sh (cd /opt/aerospike/bin; sudo ./afterburner.sh) を実行します。(訳注: https://github.com/aerospike/aerospike-server/tree/master/tools/afterburner)
- 負荷をかけるクライアントとして、AWS Marketplaceで 5台の Aerospike インスタンスを c3.2xlarge で立ち上げます。サーバーと同じプレイスメントグループで同じ HVM と VPC を使用してください。
- ノード間の通信用に TCPポートの 3000 – 3003 が 開放されていることを security group で確認します。TCPポート 8081 は、AMC (訳注: Aerospike Management Console: ブラウザでアクセスする Aerospike の管理ツール)を使用するため、インターネットに開いている必要があります。
- RAM の 54 GBを、インメモリストアの名前空間に割り当てます(c3.8xlarge は 60GB を持っています)
- Aerospike サーバーを起動します。
- Java のベンチマーククライアントを使用して、サーバにデータをロードします。
cd <java client>/benchmarks
./run_benchmarks -z 40 -n test -w I -o S:10 -b 10 -l 23 -k 10000000 -latency 5,1 -h YOUR_AWS_INTERNAL_IP
- ワークロードは 100% 読み取りでベンチマーククライアント実行します。各クライアントは異なる ENI 上の独立したプライベートIPをアクセスポイントとします。
cd <java client>/benchmarks
./run_benchmarks -z 40 -n test -w RU,100 -o S:10 -b 10 -l 23 -k 10000000 -latency 5,1 -h YOUR_AWS_INTERNAL_IP
- 5 クライアントを使用すると、1M TPSを取得できるでしょう!
しかし、私たちはここで止まりませんでした。私たちはその後、4種類のインスタンスタイプのコストパフォーマンスを、RAM 上に構築した 4台 Aerospike クラスタに対する5種類の読み取り/書き込みのワークロードで、評価しました。Part 2 に続きます。

関連記事
-
-
作業用BGMは本当に仕事が捗るのか?
みなさんは普段どんなスタイルで仕事をしていますか? エンジニアでよくヘッドホンをしながら仕事をしてる
-
-
良いプログラマの条件とは?
野球の打者は、少なくとも30%の確率でヒットを打つことに成功すれば良いとされている。ゴルファーなら、
-
-
エンジニアなら思わず納得してしまうツイート6選
「そうそう!」と思わず納得してしまうことってありますよね。 しかし、普通の人に話したら全然納得しても
-
-
Linux OSのジッタを体系的に削減する黒魔術
低遅延性の求められるトレードシステムにおいて、ジッタの原因をどのように体系的に発見してひとつずつ削除
-
-
フリーランスエンジニアになるにはスクールに通った方がよい?
【関連リンク】 ❏フリーエンジニアにおすすめの交流会・勉強会の存在 ❏フリーエンジニアの生活はどんな
-
-
フリーエンジニアに必要なプログラミング以外のスキル
【関連リンク】 ❏フリーエンジニアの仕事にはどんな種類がある? ❏副業でフリーランスエンジニアになる
-
-
フルスタックエンジニアを目指すには。
by Shunsuke Kobayashi 習うより慣れろと言うことわざがありますが、 エンジニアで
-
-
「ITエンジニアは何でも屋じゃない!」ITエンジニアが言われて困る一言とよくある誤解まとめ
ITエンジニアは、エンジニアではない人から「コンピューターやインターネットなら何でも詳しい」なんて思
-
-
フリーランスエンジニアは田舎でも働ける?メリットや注意点は?
【関連リンク】 ❏フリーランスエンジニアなら知っておきたい単価や条件の交渉について ❏フリーランスプ
-
-
100万ppsを受信するプログラムを書くのはどのくらい難しいのか?【翻訳】CloudFlare ブログ
無料枠が充実していることでも人気なコンテンツデリバリネットワーク (CDN) を提供するCloudF