問題分析
クーポンにはサブスクリプションプッシュという機能があります。クーポン購読プッシュとは何ですか?ユーザーがクーポンを購読すると、クーポンが受け取れる1分前にリマインダーがユーザーのアプリにプッシュされるということです。本来であれば、この購読機能はメッセージセンター側で行うべきなのですが、短時間で行うことはできないと言われました。だから、クーポン担当の私にやらせてくれたんです-......。-!具体的な解決策としては、特定のプッシュ時間帯に、クーポンシステムがメッセージセンターのプッシュインターフェイスを呼び出し、情報をプッシュします。
この機能のビジネスシナリオを以下に分析します。同社は現在、6000W +の登録ユーザーは、照会しないことです。例えば、20元の順序を置くためにしきい値なしクーポンがあり、その後、このクーポンをつかむより多くの人々になります、10W +の保守的な見積もりは、百万人のレベルは言って良いことではありません。最初は20W万人に設定し、これらの20Wプッシュ情報を完了するために1分でプッシュされます!そして、ユーザーは複数のクーポン券を購読することができます。だから、2つの未解決の困難があるのこのサブスクリプション機能を知っています:
プッシュの効果:プッシュが遅いと、ユーザーは開店時間に間に合わなかったと不満を持つでしょう。
誰もが欲しがる爆発的なクーポン券!
またしても、プッシュの量はプッシュの効果に影響します。本当に頭の痛い問題です!
そして、問題を一つずつ解決していきましょう!
技術的な困難の分析
プッシュ効果の問題:ユーザーがクーポンセンターでクーポン収集のリマインダーを購読すると、ユーザーの購読リマインダーのレコードがバックグラウンドで生成され、どのタイミングでユーザーにプッシュ情報を送信するかのレコードが生成されます。そこで問題となるのは、リアルタイムでプッシュするレコードをシステムがどのように素早く選択できるかということです!
オプション1:MQの遅延配信 MQは、メッセージの遅延配信をサポートしていますが、スケールが大きすぎる1秒5秒10秒30秒1メートルは、正確なポイントインタイム配信を行うために使用することはできません!そして、ユーザーがサブスクリプションを実行し、サブスクリプションのキャンセルは、MQのメッセージは、この操作を削除送信する大きな頭痛の種ですが、時間の短い期間が着陸することは困難です!そして、ユーザーは重複排除の問題を伴うキャンセル後、再び購読することができます。だから、MQのソリューションは却下されます。
オプション2:伝統的な定時タスク。これは比較的簡単で、時間指定タスクはロードユーザーサブスクリプションのリマインダーのレコード内部のdbに移動し、そこから現在のレコードをプッシュすることができます。しかし、実際のビジネスから切り離されたデザインはフーリガンであるということわざがあります。最終的にこのビジネスに適した伝統的なタイムドタスクの次の分析!
以上のことから、一般的に従来のタイムド・タスクには次のような欠点があることは明らかです:
パフォーマンスのボトルネック1台のマシンだけで処理しているため、大量のデータに圧倒されています!
効率が悪い時限タスクの頻度が高すぎると、オペレーショナル・データベースに大きな負担がかかるため!
単一障害点。万が一、その1つがハングアップしたら、ビジネス全体が使えなくなります。- 恐ろしいことです!
ですから、従来の時間制限のある仕事は、このビジネスにも向いていません。
時限タスククラスタ
最初のステップは、タイムドタスクのクラスタによって解決される3つの問題を定義することです!
- 効果は高いはずです
- スループットが大きいこと
- サービスが安定しており、単一障害点がないこと。
以下は、タイムドタスククラスター全体のアーキテクチャ図です。
パフォーマンス:帯域幅などの他の要因を除くと、基本的にマシン数に直線的に関係します。マシン数が多いほどスループットは高くなり、マシン数が少ないほど相対的なスループットは低くなります。
効果:数秒に改善され、満足のいく結果。
単一障害点?存在しません!redisクラスタや全サーバがダウンしない限り。
redisを使用する理由
最初のredisは、高性能なストレージDBとして使用することができ、パフォーマンスはMySQLよりもはるかに優れており、永続性、安定性をサポートしています。
2番目のredis SortedSetキューは、当然ながら条件として時間によるソートをサポートしており、プッシュするレコードを選択するのに適しています。
OK~ さて、ソリューションが出来上がったところで、このソリューションを1日で軌道に乗せるにはどうしたらいいでしょうか?はい、ソリューションを設計してから基本的なコーディングを終えるまでの時間は1日です。時間があまりに急ぐからです。
まず、user_idをキーとして使用し、キュー番号のハッシュをredisのSortedSetキューに格納します。これが必要な理由は、ユーザーが同時に2つのクーポンを購読し、プッシュが非常に近接している場合、2つのプッシュを1つにマージすることができ、ハッシュが比較的均等になるからです。以下はコードのスクリーンショットです:
そして、キューの数を決めなければなりません。一般的には、通常のサーバと同数のキューを定義して処理を行います。これは、キューの数が少なすぎるとキューの競合を引き起こす可能性があり、多すぎるとレコードが適時に処理されなくなる可能性があるためです。
しかし、ベストプラクティスは、オンラインクラスタ内のマシン数が頻繁に変化するため、キューの数を動的に設定できるようにすることです。大きなプロモーションは、マシンを追加することはありませんし、ビジネスの成長は、マシンの数も増加することはありません〜。だから、私はキューの数の動的な設定のために淘宝網のダイヤモンドを借りました。
これにより、実際の生産状況に応じて、いつでもクラスタ全体のスループットを調整することができます。 タイムドタスククラスターには動的な調整をサポートする機能が残っているんですね~。
最後の重要な要素はロードバランシングです。これは非常に重要です!これがうまく行われないと、おそらく複数のマシンが同時にキューを処理するために競合することになり、クラスタ全体の効率に影響を与えることになるからです!時間的な制約がある場合、私はredisのシンプルで実用的な使用法である自己インクリメントキーとmodキュー番号アルゴリズムを使用しました。これにより、同時に2台のマシンがキューを奪い合うことはほぼなくなります。
クラスタのスループット
10 * 2000 = 20000.そして、メッセージをMQの形でメッセージ・センターにプッシュします。
20Wを送るには、実際には数十回プッシュする必要があります。
OK~ ここでは、タイムドタスククラスター全体がほぼ基本的に地面にあります。他に何を改善すればいいかと聞かれれば、これです:
1、プラス監視、どのようにクラスタ木製のそれを監視することができ、タスクの山に問題が発生した場合にどのように行うには〜 2、プラス視覚的なインターフェイス。3、それはインテリジェントなスケジューリングを持って、タスクの優先順位を高めることが最善です。優先順位の高いタスクが最初に実行されます。4、リソースのスケジューリングは、マシンの数が十分でない場合には、力が十分ではありませんが、優先順位は、重要なタスクの実行を確保するため。