20w のユーザーのプッシュを数秒で同時に完了するにはどうすればよいでしょうか?この記事では、Redis がリアルタイムのサブスクリプション プッシュを実装するための 3 つの方法、MQ、従来のスケジュールされたタスク、および Redis の SortSet キューを紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
![リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明](https://img.php.cn/upload/article/000/000/024/605c06c4a015c653.jpg)
[関連する推奨事項: Redis ビデオ チュートリアル ]
少し前、私たちは会社のクーポン収集センター用のプロジェクトを開発しました。このプロジェクトは Redis を主要なテクノロジーとして実装しています。
まず、クーポン コレクション センター プロジェクトについて話しましょう。このプロジェクトは、JD.com アプリのクーポン コレクション センターと似ています。もちろん、写真は会社のものではなく、JD.com から取得したものです。 。 。
![](/img/remote/1460000039677010)
![161664369845615リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明 リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明](https://img.php.cn/upload/image/649/743/657/161664369845615%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E3%81%AE%E3%82%B5%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%20%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%20Redis%20%E3%81%AE%203%20%E3%81%A4%E3%81%AE%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E7%B0%A1%E5%8D%98%E3%81%AA%E8%AA%AC%E6%98%8E)
#クーポンを受け取るにはサブスクリプションプッシュという機能があります。
クーポン収集のためのサブスクリプション プッシュとは何ですか?
は、ユーザーがクーポンのプッシュ通知を購読していることを意味し、リマインダー情報は取得できる 1 分前にユーザーのアプリにプッシュされます。
このサブスクリプション機能、本来はメッセージセンターが実装する予定だったのですが、短期間では実装できないとのことでした。そこでクーポン担当の私がやってみました-.-!。具体的な計画は、特定のプッシュ時点に到達することであり、クーポン システムはメッセージ センターのプッシュ インターフェイスを呼び出して情報をプッシュします。
この機能のビジネス シナリオを分析してみましょう。同社には現在 6000W の登録ユーザーがいます。誰なのかは聞かないでください。 。 。たとえば、注文時に 20 元が即時に割引されるしきい値なしの割引クーポンがあれば、より多くの人がこのクーポンを手に入れるでしょうが、控えめに見積もっても 10 W と推定されますが、それが 10 W であるかどうかは判断できません。百万元。当初の目標は 200,000 人なので、この 200,000 件のプッシュ メッセージは 1 分で送信されます。また、1 人のユーザーが複数のクーポンを購読できます。したがって、このサブスクリプション機能には 2 つの顕著な問題があることがわかります。
- プッシュの効果: プッシュが遅いと、ユーザーは通知が間に合わず、通知を逃したと不満を抱くでしょう。掴み始めるチャンス。
- プッシュ量大、誰もが手に入れたい人気クーポン!
ただし、プッシュの量はプッシュの効果に影響します。これは本当に頭が痛いです!
それでは、問題を一つずつ解決していきましょう!
プッシュの有効性に関する問題: ユーザーがクーポン コレクション センターでクーポン コレクション リマインダーを購読すると、ユーザーのサブスクリプション リマインダー レコードがバックグラウンドで生成され、リマインダーが付与された時点が記録されます。ユーザーにプッシュメッセージを送信します。したがって、問題は、どのレコードをリアルタイムでプッシュするかをシステムがどのように迅速に選択できるかということになります。
オプション 1:
MQ の配信の遅延。 MQ はメッセージの遅延配信をサポートしていますが、スケールが 1 秒 5 秒 10 秒 30 秒 1 分と大きすぎるため、正確な時点の配信には使用できません。また、サブスクリプション実行後にユーザーがサブスクリプションをキャンセルした場合、送信された MQ メッセージを削除する操作は少し面倒で、短期間で実装するのは困難です。また、ユーザーはキャンセルしてから購読することもできますが、これにも重複排除の問題が伴います。したがって、MQ の計画は拒否されます。
オプション 2:
従来のスケジュールされたタスク。これは比較的単純で、スケジュールされたタスクを使用するには、ユーザーのサブスクリプション リマインダー レコードをデータベースにロードし、現在プッシュできるレコードを選択します。しかし、よく当たる格言があります。実際のビジネスから切り離されたデザインは不正なものです。従来のスケジュールされたタスクが当社のビジネスに適しているかどうかを分析してみましょう!
複数のマシンの同時実行をサポートできますか? | 一般的にはそうではなく、同じです常に単独でのみ実行できます。 |
#ストレージ データ ソース
通常は mysql またはその他の従来のデータベースであり、単一テーブル ストレージです |
|
頻度
秒、分、時間、日をサポートしますが、通常はあまり速くありません |
|
要約すると、一般的な従来のスケジュールされたタスクには次の欠点があることがわかっています:
1. パフォーマンスのボトルネック。 1 台のマシンのみが処理しているため、大量のデータに対応できません。
2. 有効性が低い。スケジュールされたタスクの頻度は高すぎることはできません。高すぎると、ビジネス データベースに多大な負荷がかかります。
3. 単一障害点。
実行中のマシンがハングアップすると、ビジネス全体が利用できなくなります。 - これはひどいことです!したがって、従来のスケジュールされたタスクはこのビジネスには適していません。 。 。それで、私たちは途方に暮れているのでしょうか?実はそうではありません! 従来のスケジュールされたタスクを簡単に変換するだけです。これを、複数のマシンで同時に実行できるスケジュールされたタスク クラスターに変えることができ、効率性は第 2 レベルまで正確になり、単一障害点を排除できます。これには、強力な Redis の助けが必要です。
オプション 3:
スケジュールされたタスク クラスター まず、スケジュールされたタスク クラスターが解決する必要がある 3 つの問題を定義する必要があります。
1. 効率が高くなければなりません
2. スループットが大きくなければなりません
3. サービスは安定していて、単一障害点があってはなりません。以下は、スケジュールされたタスク クラスター全体のアーキテクチャ図です。
![161664392982223リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明 リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明](https://img.php.cn/upload/image/681/243/439/161664392982223%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E3%81%AE%E3%82%B5%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%20%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%20Redis%20%E3%81%AE%203%20%E3%81%A4%E3%81%AE%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E7%B0%A1%E5%8D%98%E3%81%AA%E8%AA%AC%E6%98%8E)
アーキテクチャは非常に単純です。ユーザーのサブスクリプション プッシュ レコードを Redis クラスターのsortedSet キューに保存し、リマインダーのタイムスタンプをスコア値として使用し、私たちの個人的な各ビジネス サーバーは、秒の頻度でタイマーを開始します。私の設定は 1 秒です。その後、ロード バランシングの後、プッシュされるユーザー レコードがキューから取得され、プッシュされます。次に、次のアーキテクチャを分析します。
1. パフォーマンス: 帯域幅やその他の要素を除くと、基本的にマシンの数と直線的に関係します。マシン数が多いほどスループットは向上しますが、マシン数が少ない場合は相対的なスループットが低下します。
2. 効果:2段階目まで改善されており、効果は許容範囲内です。
3. 単一障害点?存在しない! Redis クラスターまたはすべてのサーバーがダウンしている場合を除きます。 。 。 。
ここでは、redis が使用される理由の分析を示します。
まず、redis は高性能のストレージ データベースとして使用でき、そのパフォーマンスは MySQL よりもはるかに優れており、永続性をサポートし、安定性も優れています。
2 番目の redis SortedSet キューは、条件として時間に基づく並べ替えを当然サポートしており、プッシュするレコードを選択する際に完全に満足します。
わかりました~ 計画が利用可能になったので、どうすれば 1 日以内にそれを実装できるでしょうか?はい、この計画を設計してから基本的なコーディングを完了するまでにかかった時間はわずか 1 日です。 。 。時間が遅すぎるからです。
最初に user_id をキーとして使用し、次にキュー番号ハッシュを redis SortedSet キューに変更します。これはなぜでしょうか? ユーザーが同時に 2 つのクーポンを購読し、プッシュ時間が非常に近い場合、2 つのプッシュを 1 つにマージでき、ハッシュが比較的均一になるためです。以下は、コードの一部のスクリーンショットです:
![161664396164468リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明 リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明](https://img.php.cn/upload/image/200/643/330/161664396164468%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E3%81%AE%E3%82%B5%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%20%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%20Redis%20%E3%81%AE%203%20%E3%81%A4%E3%81%AE%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E7%B0%A1%E5%8D%98%E3%81%AA%E8%AA%AC%E6%98%8E)
次に、キューの数を決定する必要があります。一般的に、処理サーバーに必要な数のキューを定義します。 。キューが少なすぎるとキューの競合が発生する可能性があるため、多すぎるとレコードが適時に処理されなくなる可能性があります。ただし、オンライン クラスター マシンの数は頻繁に変化するため、ベスト プラクティスは、キューの数を動的に構成できるようにすることです。
大キャンペーン中にマシンを追加しますよね?業務量が増えるとマシンの数も増えますよね?そこでタオバオのダイヤモンドを借りてキューの数を動的に設定しました。
![161664397035289リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明 リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明](https://img.php.cn/upload/image/932/450/191/161664397035289%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E3%81%AE%E3%82%B5%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%20%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%20Redis%20%E3%81%AE%203%20%E3%81%A4%E3%81%AE%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E7%B0%A1%E5%8D%98%E3%81%AA%E8%AA%AC%E6%98%8E)
毎回キューから取得するレコードの数も動的に構成できます。
![161664401628364リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明 リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明](https://img.php.cn/upload/image/358/181/541/161664401628364%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E3%81%AE%E3%82%B5%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%20%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%20Redis%20%E3%81%AE%203%20%E3%81%A4%E3%81%AE%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E7%B0%A1%E5%8D%98%E3%81%AA%E8%AA%AC%E6%98%8E)
こうすることで、次のことが可能になります。いつでも設定できます。実際の運用状況によって、クラスター全体のスループットが調整されます。したがって、スケジュールされたタスククラスターには、動的な調整をサポートする機能がまだあります~。最後の重要なコンポーネントは負荷分散です。これはとても重要です!
これがうまく行われないと、複数のマシンがキューを同時に処理するために競合する可能性があり、クラスター全体の効率に影響を与える可能性があります。時間が非常に限られていたときは、redis を使用してキーを自動インクリメントし、キューの数を変更するシンプルで実用的なアルゴリズムを使用しました。これにより、2 台のマシンが同時にキューを競合することがなくなります。
![1616643983585300.png リアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明](https://img.php.cn/upload/image/491/407/899/1616643983585300.png)
プログラミング関連の知識の詳細については、次のサイトを参照してください: プログラミングビデオ! !
以上がリアルタイムのサブスクリプション プッシュを実装するための Redis の 3 つの方法についての簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。