Redisベースの優先キュー

1872 ワード

に質問


Redisを使用して優先キューを実装するにはどうすればいいですか?

sorted setの概要


Sorted setはRedisが提供するデータ構造タイプで、setとhashの特徴を兼ね備えています.まず、sorted setの各要素は一意である.次に、sorted setの各要素には、scoreと呼ばれる浮動小数点値が関連付けられます.それ以外に、sorted setの要素は秩序化されており、これらの要素は次のルールに従ってソートされます.
  • AとBが2つのscoreの異なる要素である場合、A>B
  • は、A.score>B.scoreの場合のみ、A>B である.
  • AとBのscoreが同じである場合、A>B
  • は、Aの辞書順がBより大きい場合にのみ、

    sorted set操作

  • ZADD:sorted setに要素
  • を追加
  • ZCOUNT:sorted setのscoreが指定した値に等しい要素は何個ありますか
  • ZSCORE:sorted setで指定した要素のscoreは何ですか
  • ZCARD:sorted setの合計数の要素
  • ZREM:sorted setの指定要素
  • を削除する.
  • ZREVRANGE:指定インデックス区間内の要素
  • を大きいから小さい順に返す.
  • ZRANGE:指定インデックス区間内の要素
  • を小さい順に返す.
    sorted setでサポートされている操作は、優先順位キューの実装に役立つ操作をいくつか挙げただけです.

    優先キューの実装


    sorted setに基づいて、簡単な優先順位キューを実現することができます.コードは次のとおりです.
    class PriorityQueue(object):
    
        def __init__(self, redis_client, queue, namespace='priority-queue'):
            self.client = redis_client
            self.key = '%s:%s' % (namespace, queue)
    
        def enqueue(self, score, member):
            return self.client.zadd(self.key, score, member)
    
        def dequeue(self):
            """  :          """
            score = None
            member = None
            result = self.client.zrevrange(self.key, 0, 0, withscores=True)
            # [( member, score), (member, score), ...]
            if result:
                member, score = result[0]
                ret = self.client.zrem(self.key, member)
                assert ret == 1
            return score, member
    
        def card(self):
            return self.client.zcard(self.key)
    
        def __repr__(self):
            return u"PriorityQueue" % self.key
    

    優先順位キューの主な操作はエンキューとデキューであり、sorted setは要素のscoreに基づいて優先順位を維持します.上記のコードのデキュー操作はスレッドが安全ではないことに注意してください.優先度が最も高い要素を取ることと、この要素を削除することは2回の操作であり、原子的ではありません.