MySQLが数十億のトラフィックをサポートする方法

MySQLが数十億のトラフィックをサポートする方法

1 マスター・スレーブの読み取り・書き込み分離

ほとんどのインターネットビジネスでは、書き込みよりも読み取りが多いため、DB がより多くのクエリをサポートする方法を検討することが優先されます。まず、読み取りトラフィックと書き込みトラフィックを区別する必要があり、読み取りトラフィックを個別に拡張すると便利です。つまり、マスターとスレーブの読み取りと書き込みの分離です。

フロントエンドのトラフィックが急増してスレーブ データベースが過負荷になった場合、DBA はスレーブ データベースの容量拡張を優先します。これにより、DB への読み取りトラフィックが複数のスレーブ データベースに分散され、各スレーブ データベースの負荷が軽減されます。開発者は、DB レイヤーでトラフィックをブロックするために最善を尽くします。

キャッシュ VS MySQL の読み取り/書き込み分離 開発とメンテナンスの難しさにより、キャッシュの導入は複雑さをもたらします。キャッシュ データの一貫性、侵入、アバランシェ対策などの問題を考慮する必要があり、さらに 1 種類のコンポーネントをメンテナンスする必要があります。したがって、まずは読み取りと書き込みの分離を使用し、それが処理できない場合にキャッシュを使用することをお勧めします。

1.1 コア

マスター/スレーブの読み取り/書き込み分離では、通常、DB のデータを 1 つ以上のコピーにコピーし、他の DB サーバーに書き込みます。

  • 元のDBはメインデータベースであり、データの書き込みを担当します
  • ターゲットDBはデータクエリを担当するスレーブデータベースです。

したがって、マスターとスレーブの読み取り/書き込み分離の鍵は次のとおりです。

  • データのコピー

マスタースレーブレプリケーション

  • マスタースレーブ分離によるDBアクセス方法の変化を遮断

開発者が単一のDBを使用しているように感じさせる

2 マスタースレーブレプリケーション

MySQL マスター/スレーブ レプリケーションは、MySQL のすべての変更を記録し、バイナリ ログ ファイルにバイナリ形式でディスクに保存する binlog に依存しています。

マスタースレーブレプリケーションは、バイナリログ内のデータをマスターデータベースからスレーブデータベースに、通常は非同期で転送します。つまり、マスターデータベースの操作は、バイナリログの同期が完了するまで待機しません。

2.1 マスタースレーブレプリケーションプロセス

  • スレーブがマスターに接続すると、マスターの更新されたバイナリログを要求するための I/O スレッドが作成され、受信したバイナリログがリレー ログ ファイルに書き込まれます。マスターは、バイナリログをスレーブに送信するためのログ ダンプ スレッドも作成します。
  • スレーブ データベースも SQL スレッドを作成し、リレー ログを読み取り、それをスレーブ データベースで再生して、マスターとスレーブの一貫性を実現します。

独立したログダンプスレッドを使用すると、マスターデータベースのメイン更新プロセスに影響を与えないように非同期になります。スレーブデータベースは情報を受信した後、それをスレーブデータベースストレージに書き込まず、リレーログに書き込みます。これは、スレーブデータベースの実際のストレージへの書き込みを回避するためです。スレーブデータベースの実際のストレージへの書き込みは時間がかかり、最終的にはスレーブデータベースとマスターデータベース間の遅延が長くなります。

  • マスタースレーブ非同期レプリケーションのプロセス

パフォーマンス上の理由から、マスター データベースの書き込みプロセスは、マスターとスレーブの同期が完了するまで待たずに結果を返します。極端な場合、たとえば、マスター データベースのバイナリ ログがディスクに書き込まれる前にディスクが破損したり、マシンの電源が切れたりすると、バイナリ ログが失われ、マスターとスレーブのデータの一貫性が失われます。しかし、その確率は非常に低く、許容範囲内です。

マスター データベースがダウンすると、binlog の損失によって生じたマスターとスレーブ間のデータの不整合は手動でのみ復元できます。

マスタースレーブレプリケーションの後、次のことが可能になります。

  • 書き込み時はメインライブラリにのみ書き込みます
  • データを読み取るときは、データベースからのみ読み取ります

この方法では、書き込み要求によってテーブルまたはレコードがロックされても、読み取り要求の実行には影響しません。高い同時実行性では、複数のスレーブを展開して読み取りトラフィックを共有できます。つまり、1 つのマスターと複数のスレーブが、高い同時実行性の読み取りをサポートします。

スレーブ データベースは、マスター データベースの障害によるデータ損失を回避するためのバックアップ データベースとしても使用できます。

スレーブの数を無制限に増やすことで、より高い同時実行性をサポートできますか?
いいえ!スレーブの数が増えると、接続される I/O スレッドの数も増えます。マスター データベースは、レプリケーション要求を処理するために同じ数のログ ダンプ スレッドを作成する必要があり、マスター データベースのリソースを大量に消費します。同時に、マスター データベースはネットワーク帯域幅によって制限されます。そのため、マスター データベースは通常、3 ~ 5 台のスレーブにしか接続できません。

2.2 マスタースレーブレプリケーションの副作用

たとえば、Moments への投稿操作には次のデータが含まれます。

  • 同期操作

DBを更新する場合

  • 非同期操作

たとえば、Momentsのコンテンツをレビューシステムに同期させる

したがって、メインデータベースを更新した後、友人サークル ID が MQ に書き込まれ、コンシューマーは ID に基づいてデータベースから友人サークル情報を取得し、レビュー システムに送信します。
このとき、マスター DB とスレーブ DB 間に遅延があると、スレーブ DB からフレンド サークル情報を取得できず、例外が発生します。

マスタースレーブ遅延がビジネスに与える影響の概略図

2.3 マスタースレーブレプリケーションにおける遅延の回避

どうすればいいですか?実際には多くの解決策があり、その中心となる考え方は、データベースからデータをクエリしないようにすることです。したがって、上記のケースでは、次の解決策があります。

2.3.1 データの冗長性

MQ を送信する場合、フレンド サークル ID だけでなく、コンシューマーが必要とするすべてのフレンド サークル情報を送信できるため、DB からデータを再クエリする必要がなくなります。

このソリューションは十分に単純なので推奨されますが、単一のメッセージが大きくなり、帯域幅とメッセージ送信時間が増加する可能性があります。

2.3.2 キャッシュの使用

DB に同期的に書き込むときに、Moments データをキャッシュに書き込みます。この方法では、コンシューマーが Moments 情報を取得するときに、最初にキャッシュを照会し、データの一貫性も確保できます。

このソリューションは、新しいデータが追加されるシナリオに適しています。データを更新する場合、最初にキャッシュを更新するとデータの不整合が発生する可能性があります。たとえば、2 つのスレッドが同時にデータを更新します。

  • スレッドAはキャッシュデータを1に更新する
  • 別のスレッドBはキャッシュデータを2に更新する
  • 次にスレッドBはDBデータを2に更新します。
  • スレッドAはDBデータを1に更新する

最終DB値(1)とキャッシュ値(2)が矛盾しています。

2.3.3 メインデータベースのクエリ

コンシューマー内のスレーブ データベースをクエリする代わりに、マスター データベースをクエリすることができます。

使用時には注意してください。クエリ量が多くなく、メイン データベースの許容範囲内であることを確認してください。そうでない場合、メイン データベースに大きな負荷がかかります。

絶対に必要な場合を除き、このソリューションを使用しないでください。メインデータベースを照会するためのインターフェースが提供されているため、他のユーザーがこのメソッドを悪用しないようにすることは困難です。

マスターとスレーブの同期遅延も、トラブルシューティング時に見落とされがちです。
時々、DB から情報を取得できないという奇妙な問題に遭遇することがあります。コード内に、以前に書き込まれたコンテンツを削除するロジックがあるのではないかと疑問に思うかもしれませんが、しばらくしてから再度クエリを実行すると、データを再び読み取ることができる場合があります。これは基本的に、マスター スレーブの遅延問題です。
そのため、スレーブ データベースが遅れている時間は、通常、監視とアラームの重要な DB 指標と見なされます。通常の時間は ms レベルであり、s レベルに達するとアラームがトリガーされます。

どのデータベースのどのインジケータを通じてマスタースレーブ遅延時間警告を判断するにはどうすればよいでしょうか? スレーブライブラリで、モニタshow slave
status\G コマンド出力の Seconds_Behind_Master パラメータの値によって、マスター スレーブ遅延が発生するかどうかが決まります。
このパラメータ値は、sql_thread と io_thread によって実行されたイベントのタイムスタンプを比較することによってコピーされます。
差異は、イベントのタイムスタンプ (ts と略記) を比較することによって得られます。
ただし、レプリケーション同期マスターライブラリの bin_log ログの io_thread スレッド負荷が高すぎる場合、Seconds_Behind_Master は常に 0 になります。つまり、早期警告を出すことができず、Seconds_Behind_Master の値で遅延を判断するのは正確ではありません。実際、マスターとスレーブのバイナリログの位置を比較することもできます。

3 DBへのアクセス方法

マスタースレーブレプリケーションを使用してデータを複数のノードにコピーすることで、DBの読み取りと書き込みの分離も実現します。このとき、DBの使用方法も次のように変わります。

  • 以前は、1つのDBアドレスのみが必要でした
  • 今では、1 つのマスター データベース アドレスと複数のスレーブ データベース アドレスを使用し、書き込み操作とクエリ操作を区別する必要があります。「データベースとテーブルのシャーディング」と組み合わせると、複雑さが大幅に増加します。

実装の複雑さを軽減するために、業界では DB アクセスの問題を解決するための多くの DB ミドルウェアが登場しており、大まかに次のように分類できます。

3.1 アプリケーションの内部

たとえば、TDDL (Taobao Distributed Data Layer) は、コードの形式でアプリケーションに埋め込まれて実行されます。これはデータ ソース エージェントと見なすことができます。その構成では、複数のデータ ソースを管理します。各データ ソースは、マスター データベースまたはスレーブ データベースである可能性のある DB に対応します。
DB リクエストがあると、ミドルウェアは指定されたデータソースに SQL 文を送信し、処理結果を返します。

アドバンテージ

使いやすく、導入コストも低く抑えられます。アプリケーション内に組み込まれ、プログラムと一緒に実行されるため、運用・保守能力が弱い小規模チームに適しています。

欠点

多言語サポートが不足しており、すべて Java で開発されているため、他の言語をサポートできません。バージョンのアップグレードもユーザーからの更新に依存します。

3.2 独立して展開されたプロキシ層ソリューション

Mycat、Atlas、DBProxy など。

このタイプのミドルウェアは、独立したサーバー上に展開されます。ビジネス コードは、単一の DB を使用するようなものです。実際には、内部で多くのデータ ソースを管理します。DB 要求があると、SQL ステートメントに必要な変更を加えてから、指定されたデータ ソースに送信します。

アドバンテージ

  • 一般的に標準のMySQL通信プロトコルを使用するため、複数の言語をサポートできます。
  • 独立した展開のため、保守やアップグレードが容易で、運用および保守能力を備えた大規模および中規模のチームに適しています。

欠点

  • すべての SQL ステートメントは、アプリケーションからプロキシ レイヤーへ、およびプロキシ レイヤーからデータ ソースへの 2 回ネットワークを通過する必要があるため、パフォーマンスが低下します。

4 結論

マスタースレーブレプリケーションは、ストレージノード間でストレージデータを複製するテクノロジーに拡張することができ、これによりデータの冗長性を実現してバックアップを実現し、水平拡張機能を向上させることができます。

マスタースレーブレプリケーションを使用する場合は、次の点を考慮してください。

  • マスタースレーブの一貫性と書き込みパフォーマンスのトレードオフ

すべてのスレーブ ノードへの書き込みが成功することが保証されている場合、書き込みパフォーマンスは確実に影響を受けます。マスター ノードへの書き込みのみが成功を返す場合、スレーブ ノードでデータ同期の失敗が発生し、マスターとスレーブの間で不整合が発生する可能性があります。インターネットプロジェクトでは一般的に、強力なデータ一貫性よりもパフォーマンスを優先します。

  • マスタースレーブ遅延

これにより、データを読み取ることができないという多くの奇妙な問題が発生します。

多くの実際の事例:

  • Redisはマスタースレーブレプリケーションを通じて読み取りと書き込みの分離を実現します
  • Elasticsearchに保存されたインデックスフラグメントは複数のノードに複製することもできる
  • HDFSに書き込まれると、ファイルは複数のデータノードにもコピーされます。

コンポーネントによってレプリケーションの一貫性とレイテンシの要件が異なり、採用するソリューションも異なりますが、設計の考え方は同じです。

よくある質問

注文が多数ある場合、フロントエンドのユーザー注文クエリでは、userId を介して異なるデータベースにハッシュすると便利ですが、バックエンドのシステム ページではすべての注文を表示して並べ替える必要があるため、SQL の実行が非常に遅くなります。これについてどうすればいいでしょうか?

バックエンド システムはサブデータベースおよびサブテーブル内のデータを直接クエリできないため、データを別のバックエンド データベースまたは ES に同期することを検討できます。

これで、MySQL が数十億のトラフィックをサポートする方法についてのこの記事は終了です。MySQL の数十億のトラフィックの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • 高トラフィックのウェブサイトに対応するための MySQL データベースの 3 つのアーキテクチャ拡張方法の紹介

<<:  ウェブのさまざまなフロントエンド印刷方法: CSS はウェブページの印刷スタイルを制御します

>>:  CSS3 で transform を使用した場合のフォントぼかしの解決方法の詳細な説明

推薦する

Vue は PC カメラを呼び出してリアルタイムで写真を撮る機能を実装します

VueはPCカメラを呼び出してリアルタイムで写真を撮影します。参考までに、具体的な内容は次のとおりで...

ポップアップ効果を実現するにはjsを使用します

この記事の例では、ポップアップ効果を実現するためのjsの具体的なコードを参考までに共有しています。具...

Vue.jsのレンダリング関数の使い方の詳しい説明

Vue では、ほとんどの場合、テンプレートを使用して HTML を作成することを推奨しています。ただ...

Vueはel-tree遅延読み込みを使用して、追加、削除、変更、クエリ機能を実装します。

Vue のツリー表示については、プロジェクトが使用されています: エフェクト ダイアグラムがツリー...

MySQL複合クエリの詳細な説明

UNIONの使用ほとんどの SQL クエリは、1 つ以上のテーブルからデータを返す単一の SELEC...

CSS における z-index: 0 と z-index: auto の違い

最近、スタック コンテキストについて学習しています。学習の過程で、z-index が 0 の場合と ...

VMware Workstation 14 Pro のインストールとアクティベーションのグラフィック チュートリアル

この記事では、VMware Workstation 14 Proのインストールとアクティベーションに...

Vue+ElementUI はページング関数を実装します - mysql データ

目次1. 問題2. 解決策2.1 ページングコンポーネント2.2 データベースデータを取得する関数:...

Vue3 でパンくず関数コンポーネントをカプセル化するいくつかの方法

目次序文1. パンくずリストはなぜ必要なのでしょうか? 2. 一次包装1. 実装のアイデア2. コー...

MySqlを最適化するためにnot inを使用する方法

最近、プロジェクトで選択クエリを使用する際に、未使用の主キー ID を除外するために not in ...

Web2.0製品と機能の簡単な紹介

<br />Web2.0とは何ですか? Web2.0にはソーシャルネットワーク製品とその...

MySQL スロークエリ: スロークエリを有効にする

1. スロークエリの用途は何ですか? long_query_time を超えて実行されるすべての S...

複数の条件を持つ MySQL クエリ メソッド

複数の条件を持つ MySQL クエリ環境: MySQL 5.7 where ステートメントに複数の ...

例によるMySql CURRENT_TIMESTAMP関数の分析

時間フィールドを作成するときデフォルトのCURRENT_TIMESTAMPデータを挿入する際、このフ...

MySQLユーザー削除バグを解決する

著者が MySQL を使用してユーザーを追加していたところ、ユーザー名が間違って記述されていることに...