web-dev-qa-db-ja.com

シングルスレッドデータベースとマルチスレッドデータベースのパフォーマンスについて

H2は、パフォーマンスに関して高い評価を得ているシングルスレッドデータベースです。他のデータベースはマルチスレッドです。

私の質問は、マルチスレッドデータベースがシングルスレッドデータベースよりも興味深いものになるのはいつですか?ユーザー数は?いくつのプロセス?トリガーは何ですか?誰かが共有する経験がありますか?

概要

  • 通常のボトルネックはディスクアクセスです
  • SSDは高速ですが壊れやすい(障害手順は必須)
  • シングルスレッドシステムでの1つの長いクエリは、他のすべてをブロックします
  • マルチスレッドシステムの構成は注意が必要です
  • マルチスレッドデータベースは、シングルコアシステムでも有益です
59

これが私の意見です:

通常、DBシステムのボトルネック(または最も遅い部分)はディスクです。 CPUは、算術演算、処理、またはCPUが実行するその他のタスク中にのみスパイクします。適切なアーキテクチャーを使用すると、マルチスレッド化により、遅いディスクの読み取り/書き込みを行う代わりに、CPUへのクエリの負荷を相殺できます。 (以前にディスクに保存された)計算列を作成してディスクからこの列を読み取るよりも、CPUサイクルを使用して値を計算する方が速い場合があります。

一部のRDBMSには、そのインスタンスのすべてのDBがソート、ハッシュ、一時変数などに使用する一時DB(tempdb)があります。このtempdbファイルをマルチスレッド化および分割して、tempdbのスループットを向上させることができます。 、それによりサーバー全体のパフォーマンスが向上します。

マルチスレッド(並列処理)を使用すると、1つのコアだけを使用するのではなく、クエリの結果セットを分割して、サーバーの異なるコアで処理できます。この機能は必ずしもパフォーマンスを向上させるとは限りませんが、向上する場合があるため、この機能を使用できます。

DBで利用可能なスレッドは、ディスクへの読み取り/書き込み、ユーザー接続、バックグラウンドジョブ、ロック/ラッチ、ネットワークIOなど、さまざまな目的で使用されます。OSアーキテクチャに応じて、スレッドはCPUに優先的に供給され、待機とキューを使用して管理されます。 CPUがこれらのスレッドをかなり速くクランチできる場合、待機時間が短くなります。マルチスレッドDBは、シングルスレッドDBよりも高速になります。シングルスレッドDBでは、他のトレッドをすぐに利用できるようにするのではなく、1つのスレッドのみをリサイクルするオーバーヘッドが発生するためです。

拡張されたDBシステムを管理および実行するには、より多くのスレッドが必要になるため、スケーラビリティも問題になります。

31
StanleyJohns

MySQLについて言えることは、トランザクション(ACID準拠)ストレージエンジンであるInnoDBが実際にマルチスレッド化されていることです。しかし、それはあなたがそれを構成するのと同じくらいマルチスレッドです!!! 「そのまま」の状態でも、InnoDBはデフォルト設定が与えられていれば、シングルCPU環境で優れたパフォーマンスを発揮します。 InnoDBマルチスレッド機能を利用するには、多くのオプションをアクティブにすることを忘れないでください。

innodb_thread_concurrency InnoDBが開いたままにできる並行スレッドの数の上限を設定します。これに設定する最適なラウンド数は、(2 X CPU数)+ディスク数です。 [〜#〜] update [〜#〜]:Percona NYC Conferenceから直接学んだので、警告するにはこれを0に設定する必要がありますInnoDBストレージエンジンは、それが実行されている環境に最適なスレッド数を見つけます。

innodb_concurrency_tickets は、無欠陥の同時実行性チェックをバイパスできるスレッドの数を設定します。その制限に達すると、スレッドの同時実行チェックが再び標準になります。

innodb_commit_concurrency は、コミットできる同時トランザクションの数を設定します。デフォルトは0なので、これを設定しないと、任意の数のトランザクションを同時にコミットできます。

innodb_thread_sleep_delay は、InnoDBキューに再び入る前にInnoDBスレッドが休止できるミリ秒数を設定します。デフォルトは10000(10秒)です。

innodb_read_io_threads および innodb_write_io_threads (両方ともMySQL 5.1.38以降)は、指定した数のスレッドを読み取りと書き込みに割り当てます。デフォルトは4で、最大は64です。

innodb_replication_delay innodb_thread_concurrencyに達した場合、スレーブにスレッド遅延を課します。

innodb_read_ahead_threshold 非同期読み取りに切り替える前に、設定されたエクステント数(64ページ[ページ= 16K])の線形読み取りを許可します。

私がもっと多くのオプションを挙げれば、時間は私を逃れるでしょう。それらについては MySQLのドキュメント で読むことができます。

ほとんどの人はこれらの機能に気づいておらず、ACID準拠のトランザクションを実行するだけでInnoDBに非常に満足しています。これらのオプションのいずれかを微調整する場合は、自分の危険で行います。

私は、MySQL 5.5の複数のバッファープールインスタンス(9つのバッファープールインスタンスで162GB)を使用して、この方法でメモリ内のデータを自動パーティション化しようとしました。一部の専門家は、これによりパフォーマンスが50%向上すると述べています。私が得たのは、実際にInnoDBをクロールさせる大量のスレッドロックでした。私は1バッファ(162GB)に切り替えましたが、すべてが再び順調でした。これを設定するには、Perconaのエキスパートが必要だと思います。私は明日ニューヨークで開催されるPercona MySQLカンファレンスに参加します。機会があればそれについて尋ねます。

結論として、InnoDBは、マルチスレッド操作のデフォルト設定を前提として、マルチCPUサーバーで正常に動作します。それらを微調整するには、細心の注意、忍耐力、優れたドキュメント、そして素晴らしいコーヒー(またはRed Bull、Joltなど)が必要です。

おはようございます、こんばんは、おやすみなさい!!!

アップデート2011-05-27 20:11

木曜日 ニューヨークのパーコナMySQLカンファレンス から戻ってきました。どのような会議。多くのことを学びましたが、InnoDBについて調査する回答を得ました。 Ronald Bradford から、innodb_thread_concurrencyを0に設定すると、InnoDBがスレッドの並行性を使用して内部で最良のアクションを決定できることが通知されました。 MySQL 5.5でこれをさらに実験します。

更新2011-06-01 11:20

1つの長いクエリに関する限り、InnoDBは ACID準拠 であり、 MultiVersion Concurrency Control を使用して非常に適切に動作します。トランザクションは、他のユーザーがデータにアクセスするのをブロックしない分離レベル(デフォルトでは反復可能な読み取り)を実行できる必要があります。

マルチコアシステムに関しては、InnoDBは長い道のりを歩んできました。以前は、InnoDBはマルチコア環境でうまく機能できませんでした。複数のコアを取得して複数のmysqldプロセスをCPUに分散させるには、単一のサーバーで複数のmysqlインスタンスを実行する必要があったことを覚えています。これは、Perconaとその後のMySQL(ええと、Oracleのおかげで私はまだ苦労している)のおかげで、もはや必要ありません。彼らはInnoDBを、成熟度の高いストレージエンジンに開発しました。現在のInnoDBのインスタンスは、シングルコアサーバーで適切に動作します。

49
RolandoMySQLDBA

複数の同時ユーザーまたはプロセス、またはマルチスレッドデータベースアクセスを使用する単一プロセスさえあればすぐに、スレッド化をサポートするデータベースを持つことが面白くなる可能性があります。

H2はスレッドセーフですが、データベースへのすべてのリクエストをシリアル化します。これは、高負荷シナリオで潜在的なパフォーマンスの問題になる可能性があります。これが実際に特定のプロジェクトに当てはまるかどうかは、パフォーマンス要件の組み合わせ、データベースにアクセスするスレッド/ユーザー/プロセスの数、これらのスレッドによって実行されるクエリの頻度、および平均と最悪のパフォーマンスクエリ。

たとえば、パフォーマンス要件が1秒以内に応答することである場合、実行に0.05秒かかる単一のクエリを実行している同時ユーザーは10人以下ですが、シングルスレッドデータベースでは、これらの目標を達成できます(マルチスレッドおそらくすでに顕著なパフォーマンスの向上をもたらすでしょう)。最悪の場合のパフォーマンスが0.5秒である単一の潜在的なクエリの同じシナリオを考えると、データベースアクセスをシリアル化しても、パフォーマンスの目標を達成することはできなくなります。

現在プロジェクトでH2を使用している場合は、ロードシナリオでコードベースに対してプロファイラーを実行することをお勧めします(いくつかの一般的なユースケースを使用して、コードに同時にヒットするx個のスレッドを開始します)。これにより、理論化だけでなく、コードベースのパフォーマンスとボトルネックに関する実際のメトリックが得られます。これが、データベースへのアクセスを待機する時間の大部分を費やしているリクエストを示している場合は、スレッド化されたデータベースに移動するときです。

11
Luke Hutteman

私が言うことができることから、「シングルスレッド」はH2の少し誤った名称です。ポイントは すべてのトランザクションをシリアル化する です(つまり、一度に1つずつ行います)。

それがアプリケーションにとって「大丈夫」であるかどうかに関する重要な質問は、「ユーザー数」ではありません。または「プロセスの数は?」でも「トランザクションの所要時間は?」

すべてのトランザクションが1秒未満の場合は問題ないかもしれませんが、完了までに数時間かかる場合は、他のすべての保留中のトランザクションが完了するのを待っているため、問題がある可能性があります。それが「問題ない」かどうかの決定は、ユーザー自身のパフォーマンス要件(つまり、ユーザーがトランザクションでデータベースにアクセスするまでの許容可能な待機時間)によって異なります。

-編集

H2は実際にはトランザクションをシリアル化しないようです-DMLだけです。言い換えれば、単一の長いトランザクション内の多数の短い更新 他の更新はブロックされません 。ただし、 実験的なMVCC機能 を使用している場合を除き、テーブルのロックは実際には同様の効果があることを意味します。 実験的な "multi_threaded"機能 もありますが、それは MVCCと同時に使用することはできません

PostgreSQLサイトの一部を引用しています...私はこれらの引数のメリットについてまったく理解していないことに注意してください。コメントに適合しなかっただけです。

開発者からFAQ( "スレッドが使用されない理由..."):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

スレッドは現在、バックエンドの複数のプロセスの代わりに使用されていません:(...)

  • 1つのバックエンドでのエラーは、それらが単一のプロセス内のスレッドである場合、他のバックエンドを破壊する可能性があります
  • スレッドを使用した速度の改善は、残りのバックエンドの起動時間と比較するとわずかです。
  • 読み取り専用の実行可能マッピングの共有とshared_buffersの使用は、スレッドのようなプロセスが非常にメモリ効率が良いことを意味します
  • プロセスを定期的に作成および破棄することで、長時間実行されるプロセスでは管理が難しいメモリの断片化から保護できます。

Todoリストから(「不要な機能」):

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

単一のプロセスでスレッドとして実行されているすべてのバックエンド(不要)

これにより、現在のセットアップから得られるプロセス保護が排除されます。スレッドの作成は通常、最新のシステムでのプロセスの作成と同じオーバーヘッドであるため、純粋なスレッドモデルを使用することは賢明ではないようです。 (...)

だから、もう一度...上記のメリットを私はまったく知りません。コメントを入れるには長すぎた。

5