Redisは同期メソッド呼び出しのような機能を実現する(一)
2421 ワード
まず、このようにするのは純粋に面白いためだと宣言します.
通常、Redisは主にいくつかのデータを格納するために使用されます.データはメモリにあるので、クエリーの更新が速いです.また、Pub/sub機能を利用して、メッセージの公開/購読を実現することもできます.しかし、今日はRedisのlistを通じてServer-Clientの同期通信を実現する方法について説明します.
Client側は、実行後にサーバ側から送信された要求をリスニングし、いくつかの操作を実行し、結果をサーバ側に返します.
Redisのlistデータ構造を利用して、popをブロックする方式を使用してClient側待機配布コマンドとServer側待機返却結果を実現する. まず、サーバ側はグローバル一意のkeyを生成し、keyとdataを一緒に指定したキューにpushします.ここでは「myqueue」です.lpushの後、サーバ側はbrpopを使用してkeyキューから結果を返すのを待機し、タイムアウト時間を2秒に設定します. Client側起動後、brpopを使用して指定されたキューから配布コマンドを取得し、サーバ側から配布されたデータを受信すると、Clientはkeyとdataを取得し、独自の処理を行い、処理が完了すると、「key」キューに結果をlpush実行します. 最後に、サーバ側はbrpopを使用して「key」キューから実行結果を取得します.
通常、Redisは主にいくつかのデータを格納するために使用されます.データはメモリにあるので、クエリーの更新が速いです.また、Pub/sub機能を利用して、メッセージの公開/購読を実現することもできます.しかし、今日はRedisのlistを通じてServer-Clientの同期通信を実現する方法について説明します.
具体的なニーズ
Client側は、実行後にサーバ側から送信された要求をリスニングし、いくつかの操作を実行し、結果をサーバ側に返します.
考えを実現する.
インプリメンテーションコード
import redis
import time
import json
import threading
host = 'localhost'
port = 6322
queue = 'myqueue'
class Server(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
pool = redis.BlockingConnectionPool(host=host, port=port, db='0')
conn = redis.Redis(connection_pool=pool)
idx = 0
while True:
idx = idx + 1
key = str(idx)
data = "request_" + key
request = {'id': key, 'data': data}
print 'Server: Send request: %s' % request
conn.lpush(queue, json.dumps(request))
response = conn.brpop(key, 2)
if response:
print 'Server: Receive response: %s' % response[1]
else:
print "Server: Timeout!!!"
time.sleep(1)
class Client(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
pool = redis.BlockingConnectionPool(host=host, port=port, db='0')
conn = redis.Redis(connection_pool=pool)
while True:
msg = conn.brpop(queue)[1]
print 'Client: Receive request: %s' % msg
time.sleep(0.1)
d = json.loads(msg)
key = d.get('id')
d['data'] = "response_" + key
print 'Client: Send response: %s' % d
conn.lpush(key, json.dumps(d))
conn.expire(key, 5)
server = Server()
server.start()
client = Client()
client.start()