ホームページ  >  記事  >  バックエンド開発  >  mysql への高同時書き込みの設計

mysql への高同時書き込みの設計

WBOY
WBOYオリジナル
2016-08-04 09:19:371454ブラウズ

最近プロジェクトを開発しました。クライアントは 10 秒ごとに 100 行のデータをサーバーに送信し、サーバーは重複をチェックした後にデータを書き込みます。
クライアント数は数万程度で、提出されるデータは比較的集中しており、データの読み取りの問題は考慮されていません。
現在の設計は次のとおりです:
データベースはクライアントに従ってテーブルに分割されています。各テーブルのデータ量はそれほど多くありません。
サーバーはデータを取得した後、まずそれを Redis キューに挿入し、次にスケジュールされたタスクを通じてデータベースに挿入します。
問題は:
1. サーバーがクライアントに提供するインターフェイスは、同時にデータを送信する数千のクライアントに対応できますか (クライアントは 10 秒に 1 回送信します)。
2. まず、データを Redis キューに保存します。データが数千万または数百万ある場合、Redis は安定していますか?
基本的な目標は、サーバーが正常にサービスを提供できることを確認することです。

-------------------------- 補足内容---------------------- -- ------
このプロジェクトは主にユーザーデータを収集します。コンピュータの電源を入れると自動的に実行されます。
毎回 100 件、10 秒に 1 回送信します。通常、ユーザーは 1 日 10 回以内、つまり 1,000 件のデータ以内に送信します。
各データには、100 文字以内の 5 つまたは 6 つの値のペアが含まれています。
日々のデータの整合性を確保する必要があります。複数のクライアントが同じユーザー データを収集する状況が発生するため、重複を避ける必要があります。

ここで次のことを考えてみましょう:
データ テーブルはユーザーごとにテーブルに分割されます。
ユーザーによって送信されたデータは、まずユーザーに従って Redis キューに保存されます。つまり、各ユーザーは 1 日に 1 つのキューを持ち、データベースに保存された後、キューは削除されます。

返信内容:

最近プロジェクトを開発しました。クライアントは 10 秒ごとに 100 行のデータをサーバーに送信し、サーバーは重複をチェックした後にデータを書き込みます。
クライアント数は数万程度で、提出されるデータは比較的集中しており、データの読み取りの問題は考慮されていません。
現在の設計は次のとおりです:
データベースはクライアントに従ってテーブルに分割されています。各テーブルのデータ量はそれほど多くありません。
サーバーはデータを取得した後、まずそれを Redis キューに挿入し、次にスケジュールされたタスクを通じてデータベースに挿入します。
問題は:
1. サーバーがクライアントに提供するインターフェイスは、同時にデータを送信する数千のクライアントに対応できますか (クライアントは 10 秒に 1 回送信します)。
2. まず、データを Redis キューに保存します。データが数千万または数百万ある場合、Redis は安定していますか?
基本的な目標は、サーバーが正常にサービスを提供できることを確認することです。

-------------------------- 補足内容---------------------- -- ------
このプロジェクトは主にユーザーデータを収集します。コンピュータの電源を入れると自動的に実行されます。
毎回 100 件、10 秒に 1 回送信します。通常、ユーザーは 1 日 10 回以内、つまり 1,000 件のデータ以内に送信します。
各データには、100 文字以内の 5 つまたは 6 つの値のペアが含まれています。
日々のデータの整合性を確保する必要があります。複数のクライアントが同じユーザー データを収集する状況が発生するため、重複を避ける必要があります。

ここで次のことを考えてみましょう:
データ テーブルはユーザーごとにテーブルに分割されます。
ユーザーによって送信されたデータは、まずユーザーに従って Redis キューに保存されます。つまり、各ユーザーは 1 日に 1 つのキューを持ち、データベースに保存された後、キューは削除されます。

  1. 挿入をマージします。一度に 1 つのアイテムを挿入しないでください。たとえば、同じ挿入操作の場合、1000 個の挿入をマージします。これにより、インタラクションの数を減らすことができます

  2. このテーブルが単純な挿入とクエリ操作のみを実行し、トランザクションのサポートを必要としない場合は、InnoDB と比較して、挿入中により高いパフォーマンスを得ることができる MyISAM エンジンの使用を検討できます。

まず、いくつかの考慮事項があります

    帯域幅は十分ですか?
  1. CPU の数、コアが 4 つで php-fpm の数も 4 の場合、各リクエストの処理時間は 50 ~ 150 ミリ秒かかります。期間内に処理されるリクエストのおおよその数を計算します。
  2. メモリ、1 つのプロセスは 10-25M のメモリを占有します。
  3. 考慮できる内容には、負荷分散と DNS ポーリングが含まれます。クラスターの高可用性にも注意してください。

第二に、いくつかの考慮事項があります

    データ行、行の長さはどれくらいですか? Redis は 1k を超えるとパフォーマンスが低下します。
  1. 処理速度、キューに蓄積されるデータ量、および使用するメモリの量
  2. Redis アーキテクチャ、データが失われないようにする方法と高可用性を実現する方法
  3. 現在のリソースでこのソリューションが可能かどうか、また他のソリューションがあるかどうか。
並行して書くことはできますか?次に、アクティブ-アクティブ アクティブ-アクティブ モードを使用して、同時書き込み圧力を 50% 削減します

MyCatを使用する

データベースのシャーディング、一貫性のあるハッシュ、または単純な ID 間隔のハッシュを実行できますが、面倒に感じる場合は、読み取りと書き込みを分離し、最初に負荷を確認してください。

キューを使ってみますか?

質問者さんは、比較的データ生成が集中しているとのことですが… それならキュータスクを使ってタスク集中期間を少し延長することも考えられます… 書き込みをスムーズにしてみましょう… 書き込みと読み込みの遅延や平滑化処理を考慮する必要があります適切なバランス ポイントを見つけるだけです...本当に妥協の余地がない場合は、上記のハイエンドのアプローチを使用してください...さらに、データベースをいじりたくない場合は、次のこともできます。まずダンプ ファイルに書き込んでみてください...別のパッケージ化されたインポート...これが荒道とみなされるかどうかはわかりません...

-1. 一度に 100 個のアイテムを送信して 10 秒で処理するのは、明らかに比較的緊急です。データの一部が失われることは許容されると思います (クライアント上でのデータのキャッシュは実際には問題ありません)。危険なアプローチ)、たとえば、200 個のアイテムがあり、20 秒に 1 回送信します。

-2. サーバーはタスクキューを使用してサーバーのブロッキングを軽減し、同時実行性を向上させることができます。 (10秒に1回送信、高同時実行が発生しやすい)

-3. さらに、データの読み取りと書き込みが頻繁に行われるかどうかを考慮する必要があります。そうしないと、クラスターの同期に追加のコストがかかります。

-4. このような特殊な事業者は、他の事業者とサーバーを共有してはなりません。

-5. 後のテーブルの分割方法については、あなたのビジネスによって異なります。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。