PHP + Redisのは、24時間リアルタイム更新のランキングを達成順序集合します

基本的な導入

Redisのは順序集合と同じコレクションも、文字列型要素の集合であり、重複するメンバーを許可していません。

違いは、ダブルスコアは要素の各タイプに関連付けされることです。これは、メンバーの合格点のコレクションの大量注文に小さなからRedisのことです。

順序集合のメンバーは、それを繰り返すことができるユニークですが、スコア(得点)。

コレクションは、ハッシュテーブルを実現するので、削除、追加、検索の複雑さはO(1)です。セット内のメンバーの最大数2 ^ 32--1 ^(4,294,967,295、各セット40万人を格納することができます)。

最初のメンバー(メンバー)のユニークな特性を有するメンバーは分数をソートすることができるように、第二に、各部材は、得点(スコア)に関連付けられている順序集合の集合です。

要件の説明

ゲームで想像し、あなたが今、あなたはそれを行うだろうか、経験に基づいて、トップ10にランク選手を整理する必要がある場合は、プレイヤーデータの何百万人は、そこにありますか?一般的にはこのような何かにSQL文を取得する方法を記述することです。

スコアの降順限界0,20によるgame_socre順序から*を選択

このように、少量のデータの可能な状況が、データのクエリの速度の大量の場合には、特にも不測のテーブルクエリを必要とする、遅くなり、下落のスピードがさらに明らかです。

実現

そして、あなたはこれを達成するためのRedisの使用を検討することができます。

この機能は、主にRedisのデータ型はZSETのRedisの順序付けられたコレクションです達成するために使用されます。ZSETは、元の順序属性タイプよりも1以上の拡張のセットタイプです。このプロパティは自動的にシーケンスが挿入される各データ値に調整され、値の値が連続特定の順序で配置されていることを確認します。

主なアイデアは、達成することです。

1、新しいレコードが(特定のニーズにレコードの内容を参照してください)ZSETでRedisの中にゲームに関わる新しいプレイヤーは、スコア0

プレイヤーの経験値がプレイヤーのスコアの値を変更し、変更された2、

3、ZREVRANGEのRedisの方法の使用は、ランキングを取得します

戻り値は、範囲内のメンバーを指定し、設定キーを命じました。スコア値の位置は、メンバー(降順)だけデクリメントされる配置されています。逆順のスコア値の同じ辞書式順序を持つメンバー。この点配置のメンバーに加えてZREVRANGEコマンドとしてスコア値、および他の態様ZRANGEコマンドを減少させるためです。

Redisの127.0.0.1:6379> ZADD KEY_NAME SCORE1 VALUE1 .. Scoren黒字

1、データ準備

 

 2、取得スコア高得点ランキングTOP10(ZREVRANGE下降、ZRANGEの昇順)

 

 図3は、ユーザの実際のランキングEE(ZREVRANK下降、ZRANK昇順)、リアルタイムのスコアを表示します

 

 

さらに、要件

私たちは、トップ10の選手とのポイントの最近24時間のユーザーリーダーボードや統計を実装する必要があります

実現

主なアイデアは、達成することです。

より良いアイデアがある場合は、私はより良いの下部にメッセージを残すことができるか知っている(;信用情報ZADDの使用は、時間によって、ユーザーを追加し、ゲームポイントの合計の24時間を達成するために設定ZUNIONSTORE、「24リスト」を達成するためにA)

ZUNIONSTORE先numkeys キー [ キー ...]

RedisのZunionstore指令演算は、格納先に1を与えられた以上のセットとのセットを注文し、キーnumkeysパラメータの所定の数が指定されなければならない、と組合(結果セット)。

デフォルトでは、結果は、スコアと部材での値の所定のセットのすべてのメンバーの分数の値を設定します。

可能性のある問題が発生しました

1、同じスコアの問題

フェース部材でRedisの同じスコアは独自の辞書のソート順に応じて設定されている、すなわち、その後、NATURAL USER3前になって、逆の順序で、「USER2」と「USER3」は、これら2つの文字列に応じてそこにソートされます。この問題を解決するために、我々はスコアにタイムスタンプを追加することを検討することができ、式は次のとおりです。

実際のスコアをスコア=タイムスタンプ* 10000000000 +(9999999999 - タイムスタンプ)

我々は原因32ビットのタイムスタンプに、(2038年に持続することができる)32ビットのタイムスタンプを使用した1970年1月1日からの秒数であるシステム()関数によって提供されるタイムスタンプを使用して、10進整数であります(最大4294967295)。

そこで、タイムスタンプがZSETの添加の結果として、下位10ビット(10進整数)、次いで10 ^ 10倍の実際のスコアの膨張、スコアの2つの部分を占有してみましょう。時系列逆順に考慮に入れると、その必要性のこの部分はマイナスとの理由9999999999タイムスタンプであるタイムスタンプを、逆にします。

私たちが読んだときのみ10を除去することができる後に実際の選手が、得点します。

プログラムは、最初はかなり良いように見えますが、2つの問題があります。

最初の問題は小さな問題で、タイムスタンプは、弁別秒でも同じことが第二の二点がまだ発生する同様の問題の前に存在する場合、もちろん、我々はより高精度のタイムスタンプを選択し、実際のシーンにすることができ、十分ではありません既に無関係同じ第二の行です。

2 ^ 53 53 ^ 2に、唯一最高 - 第二の問題は、スコアRedisのタイプは52桁の有効数字二重、64ビットの倍精度浮動小数点数を使用するため、それが発現測距正確整数であり、大きな問題です(実際には9,007,199,254,740,992の最大値、はなく、さらに16完全な表現)16進整数を表します。

前回のタイムスタンプが10を占めている場合それは、その後、いくつかのリーダーボードのスコアのために十分ではありません6点、が残されています。当社は、2015年1月1日から開始時間として、中央値はタイムスタンプを減らすことを検討することができ、それはまだ数を増やすことはできません。

またはスタンプユニットとして、差別、分、時間を減らします。

型int64型のRedisのスコアならば、我々は、上記の問題を持っていません。

独自のソースコードを変更しない限り、ここでは、実際には、Redisのは本当に、ZSETの更なる追加のInt64型のが、唯一の錯覚を提供する必要があります。

 

リンクします。https://mp.weixin.qq.com/s/kK4WHghsg5yt_kcdnVQWNg

おすすめ

転載: www.cnblogs.com/clubs/p/11691580.html