2012-11-17 5 views
4

Python과 함께 Redis 서버를 사용하고 있습니다.python Redis Connections

내 응용 프로그램이 다중 스레드 (프로세스 당 20 - 32 개의 스레드 사용)이고 또한 다른 컴퓨터에서 응용 프로그램을 실행합니다.

가끔 Redis cpu 사용이 100 %이며 Redis 서버가 응답하지 않거나 느린 것으로 나타났습니다.

총 4 개의 연결로 구성된 연결 풀 1 개를 사용하고 싶습니다. 예를 들어 최대 20 대의 시스템에서 앱을 실행하면20 * 4 = 80 연결이 redis 서버에 있어야합니다.

POOL = redis.ConnectionPool(max_connections=4, host='192.168.1.1', db=1, port=6379) 
R_SERVER = redis.Redis(connection_pool=POOL) 

class Worker(Thread): 

    def __init__(self): 
     self.start() 

    def run(self): 
     while True: 
      key = R_SERVER.randomkey() 
      if not key: break 
      value = R_SERVER.get(key) 


    def _do_something(self, value): 
     # do something with value 
     pass 

if __name__ = '__main__': 
    num_threads = 20 
    workers = [Worker() for _ in range(num_threads)] 
    for w in workers: 
     w.join() 

위의 코드는 명령이 실행될 때 최대 크기 4의 연결 풀에서 연결을 얻을 20 개 스레드를 실행해야합니다.

연결이 해제되면? 이 코드 (https://github.com/andymccurdy/redis-py/blob/master/redis/client.py)에 따르면

:

#### COMMAND EXECUTION AND PROTOCOL PARSING #### 
def execute_command(self, *args, **options): 
    "Execute a command and return a parsed response" 
    pool = self.connection_pool 
    command_name = args[0] 
    connection = pool.get_connection(command_name, **options) 
    try: 
     connection.send_command(*args) 
     return self.parse_response(connection, command_name, **options) 
    except ConnectionError: 
     connection.disconnect() 
     connection.send_command(*args) 
     return self.parse_response(connection, command_name, **options) 
    finally: 
     pool.release(connection) 

각 명령의 실행 후에는 연결이 해제되고 다시 수영장에 도착한다

누군가가 내가 생각 올바른 이해했는지 확인 할 수 위의 예제 코드는 설명대로 작동합니까?

내가 레디 스 연결을 볼 때 때문에, 항상 더 많은 4보다

편집이 있습니다 : 난 그냥 함수가 마침내 전에 반환 문이 코드에서 나타났습니다. 마침내 그 목적은 무엇입니까?

+0

finally 블록은 예외인지 여부에 관계없이 실행됩니다. 이것은 DRY 사용 사례입니다. –

+1

Redis 서버가 응답하지 않는 경우가 있습니다. Windows를 사용하고 있습니까? 그렇다면 Windows 버전은 데이터베이스를 비동기 적으로 디스크에 저장하므로 Redis가 완료 될 때까지 중단됩니다. –

+1

유닉스 환경에서도 저장 비용이 비쌀 수 있습니다. RDB 덤프 직렬화 전략을 사용하는 경우 Redis는 메모리 내 DB의 복사본을 작성하여 기록합니다. DB 크기가 사용 가능한 메모리의 1/2보다 작 으면 잘못된 결과가 발생합니다. 그게 문제라면 AOF 전략을 사용하거나 직렬화를 해제하십시오. –

답변

0

Matthew Scragg가 언급했듯이 finally 절은 테스트가 끝날 때 실행됩니다. 이 특별한 경우에는 연결을 해제 한 상태로 두지 않고 연결을 풀에 다시 풀어주는 역할을합니다.

응답이없는 경우 서버가 수행중인 작업을 살펴보십시오. Redis 인스턴스의 메모리 제한은 무엇입니까? 얼마나 자주 디스크에 저장하고 있습니까? AWS 인스턴스와 같은 Xen 기반 VM에서 실행 중이십니까? 복제를 실행하고 있습니까? 그렇다면 얼마나 많은 슬레이브가 양호한 상태에 있거나 데이터의 전체 동기화를 자주 요청합니까? 귀하의 명령 중 하나라도 "저장"합니까?

명령 줄 인터페이스를 사용하여 이러한 질문에 대답 할 수 있습니다. 예를 들어 redis-cli info persistence은 디스크에 저장하는 과정에 대한 정보를 알려주므로 redis-cli info memory은 메모리 사용량을 알려줍니다.

지속성 정보를 얻으려면 구체적으로 rdb_last_bgsave_statusrdb_last_bgsave_time_sec을보고 싶습니다. 마지막 저장이 성공했는지 그리고 얼마나 오래 걸렸는 지 알려줍니다. 시간이 오래 걸릴수록 리소스 문제가 더 많이 발생하고 반응이 느려질 수있는 속도가 느려질 가능성이 높아집니다.

0

최종 블록은 앞에 return 문이 있어도 항상 실행됩니다. redis-py/connection.py, pool.release (connection) 만 연결을 available-connections 풀에 넣으십시오. 따라서 연결은 아직 살아 있습니다. redis server cpu 사용 정보는 앱에서 항상 요청을 보내고 휴식이나 잠자기가 없으므로 더 많은 CPU를 사용하지만 메모리는 사용하지 않습니다.cpu 사용은 열린 파일 번호와 관련이 없습니다.

관련 문제