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


58

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

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

概要

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

スレッドには、私の知る限り、この質問の目的のために、「スレッドまたはプロセス」を意味-などのpostgresをマルチスレッドではありませんが、質問は(オラクル、SQL Serverのなど)に対して(H2、postgresの)を比較しようとしていません
ジャックダグラス

回答:


31

私の意見は次のとおりです。

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

一部のRDBMSには、そのインスタンス上のすべてのDBでソート、ハッシュ、一時変数などに使用される一時DB(tempdb)があります。 、それによりサーバー全体のパフォーマンスが向上します。

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

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

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


洞察力をありがとう。ソリッドステートドライブを称賛する人々の声が聞こえます。クエリが適切に記述され、アプリケーションが合理的に並列化されていることを確認した後、おそらくそれらに投資するのが最善の方法だと思います。
ジェロームヴェルストリンジェ

@Stan- multithreadedこの文脈では、何か別のことを意味すると思います。つまり、すべてのトランザクションはルークが彼の答えで言及しているようにシリアル化されているということです。
ジャックダグラス

@JVerstry〜いや、そうでもない。ジェフアトウッドのSSDに関する考えを読んでください...故障率が高いです。最善の方法は、データのインデックスを適切に作成し、クエリを適切に作成することです。
jcolebrand

@jcolebrand [OK]を、彼は彼らだけが失敗したときのための強力なバックアップシステムとスピードのためにそれらを提唱するようだ
ジェローム・Verstrynge

2
@Jverstry〜はいはい、彼らは物事をより速くします。
jcolebrand

47

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

innodb_thread_concurrencyは、InnoDBが開いたままにできる同時スレッドの数の上限を設定します。このために設定する最適なラウンド数は、(2 X CPUの数)+ディスクの数です。更新:Percona NYC Conferenceから直接学んだように、InnoDB Storage Engineが実行中の環境に最適なスレッド数を見つけるように警告するには、これを0に設定する必要があります。

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のドキュメントで読むことができます。

ほとんどの人はこれらの機能を知らず、InnoDBがACID準拠のトランザクションを実行するだけで十分満足しています。これらのオプションのいずれかを調整する場合は、ご自身の責任で行ってください。

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

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

おはよう、こんばんは、そしておやすみ!!!

更新2011-05-27 20:11

木曜日にニューヨーク開催されたPercona MySQL Conferenceから戻ってきました。なんて会議。多くのことを学びましたが、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のおかげで、もはや必要ありません。現在のInnoDBの現在のインスタンスは、シングルコアサーバーで正常に動作できます。


11

複数の同時ユーザーまたはプロセス、またはマルチスレッドのデータベースアクセスを備えた単一のプロセスがあれば、スレッド化をサポートするデータベースを所有することは、潜在的に興味深いことになります。

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

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

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


H2はすべてのリクエストをシリアライズしますか、それともDMLのみですか
ジャックダグラス

8

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

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

すべてのトランザクションが1秒未満で問題ない場合、完了までに数時間かかる場合は、他のすべての保留中のトランザクションが完了するまで待機するため、問題になる場合があります。それが「良い」かどうかの判断は、あなた自身のパフォーマンス要件、つまり、ユーザーがトランザクションでデータベースにアクセスするまでの許容待機時間に依存します。

-編集

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


5

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

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

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

だから、もう一度...上記のメリットについてはまったくわからない。長すぎてコメントに収まりませんでした。


-3

マルチスレッドデータベースは、データベースに複数の並列クエリがある場合にのみメリットがあります。使用しているユーザーの数に依存します。同時に10人以上のユーザーがアプリケーションで作業している場合、ほとんどの場合、データベース上で同時に複数のクエリを生成します。

さらに、マルチスレッドデータベースは、CPUにマルチコアがある場合にのみメリットがあります。シングルコアがある場合、マルチスレッドデータベースはジョブをキューに入れ、シングルコアで順番に実行する必要があります。マルチコアがある場合、各コアは1つのスレッドを並行して実行できます。したがって、パフォーマンスが向上します。

これはあなたの質問に答えますか?


7
マルチスレッドデータベースは、シングルコアシステムでも有益です。単一の長時間実行クエリが他のすべてのデータベースアクセスをブロックするのを防ぎます。さらに、別のスレッドがクエリの解析、プリフェッチデータの処理などを行っている間に、ディスクまたはネットワークI / Oで複数のスレッドを待機させることができます

1人のユーザーが、一部の操作を並列化する1つのプログラムを使用している可能性があります。このプログラムは、データベースにマルチスレッド化/マルチプロセッシング機能も備わっている場合に最も有益です。
joanolo 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.