3

クライアントが gevent-socketio と redis-py で構築された複数の Redis PubSub チャネルから更新を受信するリアルタイム Web アプリケーションがあります。

私はdjango -tictactoeの例でviews.py、l.26を見ています。クライアントがチャネルのサブスクライブ メッセージを送信すると、新しい greenlet が生成されます。その後、greenlet は Redis PubSub チャネルにサブスクライブし、メッセージが受信されるまでブロックします。

class GameNamespace(BaseNamespace):
    def listener(self, chan):
            red = redis.StrictRedis(REDIS_HOST)
            red = red.pubsub()
            red.subscribe(chan)

            print 'subscribed on chan ', chan

            while True:
                for i in red.listen():
                    self.send({'message': i}, json=True)

    def recv_message(self, message):
        action, pk = message.split(':')

        if action == 'subscribe':
            Greenlet.spawn(self.listener, pk)

私の理解では、新しい Greenlet を作成したり、サブスクリプションを解除したりせずにサブスクリプションを追加することはできません。

頻繁な購読と購読解除を効率的に処理するにはどうすればよいですか?

更新:私が構築しているのは、理論的には無限の 2D マップでの HTML5 リアルタイム MMO ゲームです。マップのサイズが大きいため、マップ全体の状態をブラウザに送信することはできません。そのため、マップはタイルに分割され、プレーヤーがマップをドラッグすると動的に読み込まれます (Google マップを考えてください)。

マップがドラッグされるたびに、クライアント/ブラウザーは、表示されたばかりのタイルの更新をサブスクライブし、少し遅れて、非表示になったタイルの更新のサブスクライブを解除します。サブスクリプションの変更は、プレイヤーごとに 1 秒に 1 回程度であるため、頻度は相対的です。

クライアントの数は(うまくいけば)多くなります。理論的には、すべてのプレイヤーがマップの同じ部分を見ることができるため、SUBSCRIBEUNSUBSCRIBEは非常にコストがかかりO(N) where N is the number of clients already subscribed to a channelます。実際には、世界中に均等に分散されるため、これは問題になりません。

ただし、私の主な問題は、リッスン時に Python Redis PubSub 実装がブロックされることです。上記の例で red.listen() を呼び出すと、メッセージが到着するまでサブスクリプションを変更できなくなります。上記のコード例は、サブスクリプションごとに Redis への新しい接続を使用して新しい Greenlet を開始しますが、これはおそらく悪い考えです。

4

1 に答える 1

0

サブスクリプション間のパーティショニングの根拠/要件、つまり、他のサブスクリプションとは別に保持する必要があるサブスクリプション間を流れる情報については言及していないため、明確に回答することは困難です。いくつかの仮定で行きます...

複数のサブスクリプションを管理する少数または固定数のクライアントがある場合は、単一の長期サブスクリプションを通じて多数の異なるイベントを多重化し、その Redis クライアントが最終的なイベント コンシューマーへの逆多重化を行う方がよい場合があります。このアプローチは、Redis の観点からは、コンシューマーごとにサブスクリプションを繰り返し設定および破棄するよりもパフォーマンスが高い可能性があります。

このようなスキームでは、パブリッシャー側でメッセージごとに適切なキューを選択できるようにするための追加のインテリジェンスが必要ですが、これは簡単に達成できる場合もあります。たとえば、N を法としてクライアント ID をハッシュすることによって実現できます。ここで、N は pub/ の数です。サブキュー。

これがあなたが求めていたものと関係があることを願っています...

于 2012-04-19T21:45:47.557 に答える