[REDIS] 레디 스 pubsub 수를 비 차단되어 있습니까?
REDIS레디 스 pubsub 수를 비 차단되어 있습니까?
내가 사용하려는 레디 스 'pubsub에 전송 일부 메시지를하지만, 아래의 코드처럼들을 사용하여 차단하지 않으 :
import redis
rc = redis.Redis()
ps = rc.pubsub()
ps.subscribe(['foo', 'bar'])
rc.publish('foo', 'hello world')
for item in ps.listen():
if item['type'] == 'message':
print item['channel']
print item['data']
섹션의 마지막 차단합니다. 난 그냥이 작업을 수행 할 수있는 방법, 주어진 채널에 데이터가 있는지 확인하려면? 방법과 같은 검사가 있습니까?
해결법
-
==============================
1.그게 가능하다고 생각하지 않습니다. 채널이 어떤 "현재 데이터를"없습니다, 당신은 따라서이 차단 API이며, 채널을 구독하고 채널에 다른 클라이언트에 의해 추진되고 메시지를 받기 시작. 당신이 술집 / 하위의 레디 스 명령 문서를 보면 또한 그것은 더 명확하게 것입니다.
그게 가능하다고 생각하지 않습니다. 채널이 어떤 "현재 데이터를"없습니다, 당신은 따라서이 차단 API이며, 채널을 구독하고 채널에 다른 클라이언트에 의해 추진되고 메시지를 받기 시작. 당신이 술집 / 하위의 레디 스 명령 문서를 보면 또한 그것은 더 명확하게 것입니다.
-
==============================
2.당신이 경우 비 차단, 비동기 처리의있는 거 생각, 당신은 비동기 프레임 워크 / 서버를 아마 사용하고 (또는 사용한다).
당신이 경우 비 차단, 비동기 처리의있는 거 생각, 당신은 비동기 프레임 워크 / 서버를 아마 사용하고 (또는 사용한다).
최신 정보: 파이썬은 기본 비동기 IO 지원을받은 평균 시간에, 원래의 대답부터 오년이었다. 지금 AIORedis, 비동기 IO 레디 스 클라이언트가있다.
-
==============================
3.레디 스 - 평은 비 차단 GET_MESSAGE을 사용하도록 권고로 받아 들여지는 대답은 사용되지 않습니다 (). 그러나 그것은 쉽게 스레드를 사용하는 방법을 제공합니다.
레디 스 - 평은 비 차단 GET_MESSAGE을 사용하도록 권고로 받아 들여지는 대답은 사용되지 않습니다 (). 그러나 그것은 쉽게 스레드를 사용하는 방법을 제공합니다.
https://pypi.python.org/pypi/redis
메시지를 읽기위한 세 가지 전략이있다.
내부적으로 GET_MESSAGE ()는 빠르게 접속의 소켓을 폴링 시스템의 '선택'모듈을 사용합니다. 읽을 수 할 수는 데이터가있을 경우, GET_MESSAGE (), 읽을 메시지를 포맷하고 반환 또는 메시지 처리기에 전달합니다. 데이터가 읽을 수 있다면, GET_MESSAGE ()는 즉시 없음을 반환하지 않습니다. 이 응용 프로그램 내부에 기존의 이벤트 루프에 통합하는 것이 사소한 수 있습니다.
while True: message = p.get_message() if message: # do something with the message time.sleep(0.001) # be nice to the system :)
레디 스-PY의 이전 버전은 pubsub.listen와 메시지를 읽고 (). () 경청하는 메시지를 사용할 수있을 때까지 차단하다는 생성기입니다. 응용 프로그램이 다른 작업을 수행하지만, 받아 레디 스로부터받은 메시지에 따라 행동 할 필요가없는 경우, ()의 실행을 얻을 수있는 가장 쉬운 방법입니다 들어요.
for message in p.listen(): # do something with the message
세 번째 옵션은 별도의 스레드에서 이벤트 루프를 실행합니다. pubsub.run_in_thread () 새로운 스레드를 생성하고 이벤트 루프를 시작합니다. 스레드 객체가 run_in_thread의 호출자에게 리턴됩니다 (). 호출자는 이벤트 루프 스레드를 종료 Thread.stop를 () 메소드를 사용할 수있다. 내부적으로이 별도의 스레드에서 실행이 본질적으로 당신을 위해 작은 비 차단 이벤트 루프를 만드는 것을 GET_MESSAGE 래퍼 ()는 단순히이다. run_in_thread은 () 옵션 SLEEP_TIME 인수를합니다. 지정된 경우, 이벤트 루프는 루프의 각 반복의 값 () time.sleep 호출한다.
참고 : 우리는 별도의 스레드에서 실행하고 있기 때문에, 자동으로 등록 된 메시지 핸들러로 처리되지 않는 메시지를 처리 할 수있는 방법이 없습니다. 따라서, 레디 스-평 호출 run_in_thread에서 방지를 ()의 경우 첨부 된 메시지 핸들러가없는 패턴 또는 채널에 당신이있는 거 구독.
p.subscribe(**{'my-channel': my_handler}) thread = p.run_in_thread(sleep_time=0.001) # the event loop is now running in the background processing messages # when it's time to shut it down... thread.stop()
당신은 메시지가 도착했는지 알고 싶어 그래서 당신이 질문에 대답하기 위해, 단지 GET_MESSAGE을 확인합니다.
-
==============================
4.레디 스 피라의 새로운 버전은 비동기 pubsub에 대한 지원을하고 있습니다 자세한 내용은 https://github.com/andymccurdy/redis-py를 확인합니다. 다음은 문서 자체의 예는 다음과 같습니다
레디 스 피라의 새로운 버전은 비동기 pubsub에 대한 지원을하고 있습니다 자세한 내용은 https://github.com/andymccurdy/redis-py를 확인합니다. 다음은 문서 자체의 예는 다음과 같습니다
while True: message = p.get_message() if message: # do something with the message time.sleep(0.001) # be nice to the system :)
-
==============================
5.이 차단 리스너를 스레드로 동작하는 예제입니다.
이 차단 리스너를 스레드로 동작하는 예제입니다.
import sys import cmd import redis import threading def monitor(): r = redis.Redis(YOURHOST, YOURPORT, YOURPASSWORD, db=0) channel = sys.argv[1] p = r.pubsub() p.subscribe(channel) print 'monitoring channel', channel for m in p.listen(): print m['data'] class my_cmd(cmd.Cmd): """Simple command processor example.""" def do_start(self, line): my_thread.start() def do_EOF(self, line): return True if __name__ == '__main__': if len(sys.argv) == 1: print "missing argument! please provide the channel name." else: my_thread = threading.Thread(target=monitor) my_thread.setDaemon(True) my_cmd().cmdloop()
-
==============================
6.여기에 스레드가없는 비 차단 솔루션입니다 :
여기에 스레드가없는 비 차단 솔루션입니다 :
fd = ps.connection._sock.fileno(); rlist,, = select.select([fd], [], [], 0) # or replace 0 with None to block if rlist: for rfd in rlist: if fd == rfd: message = ps.get_message()
ps.get_message ()는 그 자체로 충분하지만, 내가 대신 상대 레디 스 연결의 여러 FDS 기다릴 수 있도록 나는이 방법을 사용합니다.
-
==============================
7.비 차단 코드에 도달하려면 패러다임 코드의 다른 종류의 작업을 수행해야합니다. 그것은 모든 변경 사항을 듣고 새 스레드를 사용하고 다른 일을 할 수있는 메인 스레드를 떠나, 어렵지 않다.
비 차단 코드에 도달하려면 패러다임 코드의 다른 종류의 작업을 수행해야합니다. 그것은 모든 변경 사항을 듣고 새 스레드를 사용하고 다른 일을 할 수있는 메인 스레드를 떠나, 어렵지 않다.
또한, 메인 쓰레드 사이의 상호 교환 데이터에 대한 몇 가지 메커니즘이 필요하고 가입자 스레드를 레디 스됩니다.
-
==============================
8.가장 효율적인 접근 방식을 기반으로 greenlet-보다는 쓰레드 기반이 될 것입니다. greenlet 기반의 동시성 프레임 워크로, gevent 이미 상당히 파이썬 세계에서 설정됩니다. 레디 스-평을 가진 gevent 통합 그러므로 훌륭한 될 것입니다. 즉 GitHub의에서이 문제에 논의되고 있는지 정확히 :
가장 효율적인 접근 방식을 기반으로 greenlet-보다는 쓰레드 기반이 될 것입니다. greenlet 기반의 동시성 프레임 워크로, gevent 이미 상당히 파이썬 세계에서 설정됩니다. 레디 스-평을 가진 gevent 통합 그러므로 훌륭한 될 것입니다. 즉 GitHub의에서이 문제에 논의되고 있는지 정확히 :
https://github.com/andymccurdy/redis-py/issues/310
-
==============================
9.당신은 gevent을 사용할 수 있습니다, 비 블로킹 레디 스 pubsub 응용 프로그램을 구축하는 패치 gevent 원숭이.
당신은 gevent을 사용할 수 있습니다, 비 블로킹 레디 스 pubsub 응용 프로그램을 구축하는 패치 gevent 원숭이.
-
==============================
10.레디 스 '술집 / 하위 클라이언트에 메시지를 채널에 (듣기) 가입 보냅니다. 당신이 듣지 않을 경우 메시지 (따라서 차단 호출)을 그리워합니다. 당신이 비 블로킹을 원한다면, 내가 대신 큐를 사용하는 것이 좋습니다 (레디 스는 꽤 좋은 너무). 당신이 사용하는 술집에있는 경우 / 당신이 제안 gevent으로 사용할 수있는 서브 큐에 비동기 차단 리스너, 푸시 메시지를 가지고 비 블로킹 방식으로 해당 대기열에서 메시지를 처리하기 위해 별도의 소비자를 사용합니다.
레디 스 '술집 / 하위 클라이언트에 메시지를 채널에 (듣기) 가입 보냅니다. 당신이 듣지 않을 경우 메시지 (따라서 차단 호출)을 그리워합니다. 당신이 비 블로킹을 원한다면, 내가 대신 큐를 사용하는 것이 좋습니다 (레디 스는 꽤 좋은 너무). 당신이 사용하는 술집에있는 경우 / 당신이 제안 gevent으로 사용할 수있는 서브 큐에 비동기 차단 리스너, 푸시 메시지를 가지고 비 블로킹 방식으로 해당 대기열에서 메시지를 처리하기 위해 별도의 소비자를 사용합니다.
from https://stackoverflow.com/questions/7871526/is-non-blocking-redis-pubsub-possible by cc-by-sa and MIT license
'REDIS' 카테고리의 다른 글
[REDIS] 내가 장고 내 데이터베이스로의 PostgreSQL이있을 때해야하는 이유는 내가 레디 스 사용? [닫은] (0) | 2020.01.11 |
---|---|
[REDIS] PHP 스크립트에서 레디 스에 연결을 시도 할 때 "사용 권한이 거부되었습니다"문제 해결 (0) | 2020.01.11 |
[REDIS] hazelcast 대 레디 스 [폐쇄] (0) | 2020.01.11 |
[REDIS] 레디 스에서 가장 큰 개체를 찾을 수있는 가장 쉬운 방법은 무엇입니까? (0) | 2020.01.11 |
[REDIS] 레디 스 알림 : 만기에 키와 값을 가져옵니다 (0) | 2020.01.11 |