InnoDBの代わりにRocksDBエンジンを使用してFacebookからMySQLフォークを作成し、実際のアプリケーション(Drupal、Wordpress、Redmine)でテストしました。
これは素晴らしいことです。 低負荷では、ゲインは数十パーセントと小さくなります。 しかし、高負荷では、ゲインは大幅に向上します。 MariaDBの安定版リリースにRocksDBが追加されると、半年以内に人々の半数がInnoDBからRocksDBに切り替えると確信しています。 特に、クラウド/ VPSおよび専用サーバー上の小規模サイト。
MyRocksの優れている点は何ですか? ランダムではなく線形記録で、一般にディスク操作の数を減らします。 つまり、データベーストランザクションは、より少ないディスク操作を生成し、より少ないディスクキューを占有し、はるかに高速に書き込まれます。
記事で実際のRedmineスクリプトのテスト結果を収集し、結果と結論の分析を追加しました。 RocksDBを使用したMySQLでのRedmineは、InnoDBを使用した場合よりも高速であることが判明しました。最小負荷時の20%から最大3回までです。 後で、Drupalおよびその他のPHPアプリケーションに関する資料を準備します。
MyRocksの動作はご自身で確認できます-記事の最後に、MySQLの代わりにMyRocksで組み立てられたLAMP / LEMP / Rubyスタックのインストーラーと仮想マシンへのリンクがあります。

はじめに
Facebookは、 RocksDBストレージに基づいて、MySQLのストレージエンジンMyRocksを作成しました。 Facebookからのパッチを含むMySQL 5.6の形式のMyRocksの実装は、オープンソースに転送され、GitHub- https://github.com/facebook/mysql-5.6でホストされます 。 MyRocksはInnoDBの代替であり、いくつかの利点があります。
- 録音ボリュームの削減
- 最高の圧縮
- ランダム読み取り削減
これにより、HDDのトランザクション速度が大幅に向上し、SSDの摩耗が減り、レプリケーションが高速化されます。
MariaDBとPerconaは、MyRocksをMySQLフォークに統合する作業をすでに進めています。MariaDBのFacebook MyRocksは 、MySQLをPercona Server for MySQLで発表しています 。 MariaDBは、MyRocksがこの冬にリリース候補10.2で利用可能になることを発表しました。 Jetwareでは、MySQL 5.6に基づいたFacebookのMyRocksの元の実装が、MySQLの代替品の数に追加されました。
模擬テストのパフォーマンステストは、印象的な結果を示しています。 ストレージデバイスのタイプに応じて、速度の向上は20%〜10倍です。 LinkBenchのテスト結果は、MyRocksの出版物である松信義典のMySpaceのスペースおよび書き込みに最適化されたMySQLデータベースとMark Callaghan ブログ ( MyRocksなど)で確認できます 。 これらのテストの大部分は、大量のデータベース(数十ギガバイト)と強力なマシンに焦点を当てています。
合成テストと大量のデータのテストに加えて、一般的なWebアプリケーションと小規模サイトのパフォーマンス向上をテストおよび評価することにしました。
最初にRedmineをテストします。 私たちはそれがどのように機能するかを知っており、開発で積極的に使用しているため、テストには実用的な価値もあります。結果が良好であれば、MyRocksに切り替えます。
試験条件
ソフトウェア
Redmine 3.3.1とRuby 2.3.1をデフォルトの構成で使用し、プラグインを追加しません。
データベースサーバーとして使用するもの:
すべてのバイナリは、1つのGCC 4.9.3コンパイラによってコンパイルされ、推奨されるビルドオプションと最適化オプションがあります。
オペレーティングシステム-Ubuntu 14.04 x86_64、Linuxカーネル3.13.0。 ファイルシステムはext4です。
データセット
テストを実行する前に、データベースには事前生成されたプロジェクト、ユーザー、タスクが格納されています。 このようなオプションも3つあります。
- 小セット
- 30ユーザー
- 2つのレベルの3つのプロジェクトと10のサブプロジェクト。各プロジェクトには10人のユーザーがいます
- それぞれ10個のコメントを含む1000個のタスク
- 大セット
- 1000ユーザー
- 最初の10個のプロジェクト、2番目のレベルの100個のサブプロジェクト、3番目のレベルの10個のサブプロジェクト。各プロジェクトには10人のユーザーがいます
- 各10個のコメントを含む10,000個のタスク
- ジャイアントセット
- 10,000人のユーザー
- 最初の100プロジェクト、2番目のサブプロジェクト1000個、3番目のレベルのサブプロジェクト100個、各プロジェクトには10人のユーザーがいます
- それぞれ10個のコメントがある100,000個のタスク
Redmineの実際の使用の大部分は、SmallとLargeの間です。 巨大なレベルのボリュームはあまり一般的ではありません。
占有スペース

ソースデータ
列は、さまざまなデータベースおよびさまざまなデータセットに使用されるスペースの量を示します(少ないほど良い)
装備品
- プロセッサー:4コアXeon E31220 3.10GHz
- メモリー:16 Gb RAM、DDR3 1333
- HDD:RAIDミラー、Western Digital RE4 1 Tb x 2
仮想マシン
Redmineは、クラウドプロバイダーまたはオフィスサーバーでの作業と同様の条件で動作することをシミュレートします。 これを行うために、物理サーバー全体を選択するのではなく、はるかに少ないリソースを持つ仮想マシンに配置し、近隣からのディスクシステムの異なる負荷をシミュレートします。 仮想化プラットフォームとして、dom0-Linuxカーネル3.16.7でXen 4.6が使用されます。 ストレージデバイスは、シンプロビジョニングとスナップショットなしで、通常のリニアであるLVMを使用してパーティション分割されます。 ボリュームはHDDの中央にあります。
3つの仮想マシン構成が使用されました。
- 1 Gb RAM、4 CPU、16 Gb HDD
- 2 Gb RAM、4 CPU、16 Gb HDD
- 8 Gb RAM、4 CPU、HDD 16 Gb
テスト操作
Redmineで最も頻繁に使用される操作(タスクの作成、タスクへのコメントの追加、タスクのステータスと責任者の変更)の速度を確認します。 これらの操作から、2つのテスト、タスクの2つの作業サイクルを作成しました。
テストは、1つ、2つ、および4つの並列Redmineプロセスで実行されます。
サードパーティのディスク負荷
ロードは、 fio
ユーティリティを使用して作成されますfio
ユーティリティは、50/50のランダムブロックをディスクの残りの部分に読み書きします。 パブリッククラウドとVPSのプロバイダーを使用する場合や、独自のサーバーでVMWare、Hyper-V、KVM、XenServerを実行している複数の仮想マシンの場合、一般的な仮想マシン操作の典型的ないくつかのレベルのディスク負荷をシミュレートしました。
不完全なロードをシミュレートするために、 --rate_iops
を使用してIOPS制限付きでfioを実行し、ディスク使用率を測定します。 100%シングルスレッドの負荷では、これは約80 IOPSです。 14 IOPSの負荷により、25%の回復が生成されます。 --iodepth
を使用してスレッドの数を増やすと、大きな負荷がシミュレートされます。
近隣の仮想マシンの数、作業の性質、ピーク負荷に応じて、クラウドプロバイダーとVPSの両方、および独自のサーバーでディスク負荷が大幅に異なる場合があります。 したがって、わずかなシングルスレッド負荷(14 IOPS、25%)、および1、2、および4フローでの完全なサードパーティの負荷で、サードパーティの負荷がない状態でテストしました。
測定値
多数の操作で各Redmine操作の合計実行時間を測定し、平均実行時間を比較します。 結果の最初の10%は無視されます-それらについては、システムをウォームアップします。 結果の最後の10%は無視され、並列プロセスのさまざまな完了時間によるテールの歪みが除外されます。
測定は、さまざまな条件の組み合わせで実行されます。
- 異なる仮想マシン構成と異なるデータセット用
- 異なる数の同時Redmineプロセス(メインロード)および異なるサードパーティのディスクロード
ランタイムは、MyRocks MySQL、MySQL、MariaDBの3つのデータベースすべてについて測定されます。 また、MySQLとMariaDBに対するMySQL MyRocksの速度の違いも計算します。 収集されたデータはグラフで表示されます。
試験結果
小さなデータセットと小さな仮想マシン
- 仮想マシン:1 Gb RAM、4 CPU、16 Gb HDD
- データセット:30ユーザー、13プロジェクトおよびサブプロジェクト、1000タスク
運用スケジュール
1)タスクの作成。 2)10タスクの処理

ソースデータ
列は操作の時間を示します(少ないほど良い)。 行は、MySQLまたはMariaDBサーバーがMySQL MyRocksサーバーよりも低速だった回数を示しています。
最小負荷-1つのRedmineプロセスとサードパーティの負荷なし。 最大負荷-4つのRedmineプロセスと4つの完全なサードパーティディスク負荷フロー。
MyRocksのタスク作成時間は、負荷が最大まで増加するとわずかに変化し、0.018秒から0.023秒に23%増加します。 MySQLおよびMariaDBの場合、最小タスク作成時間は0.022秒であり、最大負荷で10倍から0.23秒に増加します。 最小限の作業負荷で、MySQLとMariaDBはMyRocksより24%遅くなります。 最大負荷では、9.5倍遅くなります。
MyRocksのタスク処理時間は、最小負荷での0.245秒から、最大負荷での0.327秒に33%増加します。 MySQLおよびMariaDBの場合、最小タスク処理時間は約7倍増加します。最小負荷時の0.283秒から最大2.245秒までです。
効率的な読み取りキャッシュに十分なRAMがないため、これはInnoDBの速度に大きく影響します。
大規模なデータセットと中規模の仮想マシン
- 仮想マシン:2 Gb RAM、4 CPU、16 Gb HDD
- データセット:1000ユーザー、120プロジェクトおよびサブプロジェクト、10000タスク
運用スケジュール
1)タスクの作成。 2)10タスクの処理

ソースデータ
列は操作の時間を示します(少ないほど良い)。 行は、MySQLまたはMariaDBサーバーがMySQL MyRocksサーバーよりも低速だった回数を示しています。
最小負荷-1つのRedmineプロセスとサードパーティの負荷なし。 最大負荷-4つのRedmineプロセスと4つの完全なサードパーティディスク負荷フロー。
この構成では、仮想マシンのリソースはデータと負荷の量によりよく対応します。 MyRocksの場合、タスク作成時間は同じままです-0.018秒から0.023秒まで、23%増加します。 MySQLおよびMariaDBの場合、最小時間は少し長くなり(0.023秒)、2回だけ増加します(最大負荷で最大0.056秒)。 これらはMyRocksよりも遅く、負荷が最小の場合は30%、最大の場合は2.3倍になります。
タスクを処理する場合、状況は似ています。 負荷が増加したMyRocksランタイムは、0.248秒から0.331秒にわずかに増加します。 MySQLおよびMariaDBの場合、最小時間はすでにSmall Datasetの場合よりも10%長く、0.296秒です。 最大負荷では、時間はほぼ2倍に増加します-最大0.595秒。 MySQLとMariaDBはMyRocksよりも遅く、最小負荷で18%、最大負荷で80%です。
巨大なデータセットと大規模な仮想マシン
- 仮想マシン:8 Gb RAM、4 CPU、16 Gb HDD
- データセット:10,000ユーザー、1,200プロジェクトおよびサブプロジェクト、100,000タスク
運用スケジュール
1)タスクの作成。 2)10タスクの処理

ソースデータ
列は操作の時間を示します(少ないほど良い)。 行は、MySQLまたはMariaDBサーバーがMySQL MyRocksサーバーよりも低速だった回数を示しています。
最小負荷-1つのRedmineプロセスとサードパーティの負荷なし。 最大負荷-4つのRedmineプロセスと4つの完全なサードパーティディスク負荷フロー。
データ量が10倍増加すると、すべてのデータベースのタスク作成時間がわずかに増加しました。MyRocksでは0.020秒、MySQLおよびMariaDBでは0.026〜0.029秒です。 負荷を増やすと、MyRocksの速度が35%低下して0.027秒になります。 MySQLおよびMariaDBの場合、負荷の増加は速度にさらに影響します-最大負荷では、時間が3倍に増加します-0.088秒になり、MyRocksよりも3.2倍遅くなります。
タスクを処理すると、MyRocksの実行時間は0.255秒から0.33秒に32%増加します。 MySQLおよびMariaDBの場合、時間が0.309秒から1.242秒に4回増加します。 そして、MyRocksの3.8倍遅れています。
データボリュームは、InnoDBインデックスの更新時のランダムな書き込み遅延が影響を及ぼし始めるサイズに既に拡大しており、最大負荷でのRocksDBとInnoDBの速度の差が再び拡大しています。
結果分析
記憶容量
Redmineの場合、1 Gbが最小推奨値です。 ページキャッシュでデータを効果的にキャッシュするには、メモリサイズがすでに不十分であるため、速度はディスクの負荷に非常に敏感です。 ディスクからデータを読み取る必要があるため、SELECTクエリではすでに遅延が発生しています。 RocksDBのストレージ容量が小さいため、InnoDBよりも効率的な読み取りキャッシュが可能になりました。 そのため、負荷が重い場合でも、MyRocksの操作速度はわずかに変化しました。
メモリが2 Gbに増加すると、使用されるメインデータは既にページキャッシュに収まり、データベースサーバーは常にディスクからそれを読み取る必要がなくなります。 この場合、ディスクは、データベースの変更のみを伴う狭いネックです。 トランザクションはライトバックキャッシュなしでディスクに書き込まれ、ディスクの負荷が大きいと書き込みが完了するまでの待ち時間が長くなります。
線形記録を促進するRocksDBのデータストレージの編成、および記録されるデータの量の削減により、書き込み操作の数が削減されます。 したがって、ディスクの負荷が高い場合でも、RocksDBのトランザクション速度はわずかに低下し、InnoDBを使用した場合の速度を大幅に超えることがわかります。
RocksDBとInnoDBの速度
RocksDBの動作原理に基づいて、トランザクションの高速化が期待されていました。 合成パフォーマンステストで、開発者はDBMSの速度が10倍に向上しました。 Redmineなどのアプリケーションの場合、操作の実行時間は、Rubyスクリプトの実行時間とデータベース内のクエリの時間で構成されます。 もちろん、ストレージエンジンをRocksDBに置き換えてもRubyの速度は向上せず、このコンポーネントは変更されません。 しかし、これを念頭に置いても、データベースの高速化による速度の向上は印象的でした。
ここでは、2 Gbの仮想マシンとBigデータセット、および8 Gbの仮想マシンとGiantデータセットの境界テスト結果を示します。 ここでは、リソースが極端に不足しているため、ここでは1 Gbの仮想マシンの高負荷テストを考慮していません。
運用スケジュール
1)タスクの作成。 2)10タスクの処理

列は操作の実行時間を示します(少ないほど良い)
最小(サードパーティのディスク負荷なしの1つのRedmineプロセス)と最大負荷(4つのRedmineプロセスと完全なサードパーティディスク負荷の4つのスレッド)
低負荷の場合、 MyRocksのRedmineは、MySQLおよびMariaDBよりも15% 〜25 %高速でした。 保存されたデータのサイズは、RocksDBとInnoDBの両方のこの速度にほとんど影響しません。Redmineタスクの数が10倍に増加すると、実行時間が約10%増加しました。
高負荷 (並列プロセス数の増加とサードパーティのディスク負荷の増加)により、動作は完全に変わります。 MyRocksのギャップは、2倍からほぼ4倍に増えています。 格納されたデータのサイズも速度に大きな影響を与え始めました-Redmineタスクの数が10倍に増加すると(1.5-2倍)、InnoDBを搭載したサーバーでの実行速度が大幅に低下し、RocksDBでの実行速度はそれほど低下しません(0-15%)。
データ量と高負荷の同時増加により、MyRocksでのRedmineは1.5倍遅くなり、MySQLとMariaDBでのRedmineは4倍遅くなりました。
作業安定性
テスト中に、親の問題を考慮して検索する際のRedmine SQLクエリの1つの動作にニュアンスが見つかりました。 そのため、MyRocksでは一部のタイプの検索が遅くなりました。 しかし、これはRedmine側の小さな省略です-parent_idにはテーブルにインデックスがありませんでした。 また、MyRocksでいくつかの競合するトランザクションの後、CPUが消費される小さなバグが発生しました。
他の問題は発生しませんでした。 開発者によると、Facebookは長い間、実稼働環境でMyRocksを使用しています。
今すぐMyRocksを使用するか、MariaDBリリース候補10.2またはPercona Server for MySQLにMyRocksが登場してからさらにテストを待つことができます。 MyRocksパッケージは、スタックデザイナ (PHP LAMP / LEMPなど)、Ruby RAMP / REMP、またはRedmineなどのアプリケーションのmysqld
代替の1つとしてJetwareリポジトリで利用できます。
数週間前、内部RedmineサーバーをMyRocksに移行し、正常に動作しました。
おわりに
- RocksDBを使用したRedmineは、InnoDBを使用した場合よりも高速でした-最小負荷時の20%から最大3回まで。
- InnoDBを使用するRedmineのデータ量と負荷が4倍増加すると、RocksDBを使用するRedmineの速度は1.5倍になります。
PS他のアプリケーションでのMyRocksのテスト
このテストでは、RedmineアプリケーションのMyRocksのパフォーマンスをテストしました。 次のテストでは、PHPアプリケーションでMyRocksのパフォーマンスをテストします。 おそらく、Drupalが最初になります。
英語の記事