2011-04-18 2 views
6

테스트 목적으로 Redis에 부하를 걸고 모든 상한선을 찾으려고했습니다. 먼저 크기 32 문자의 50,000 및 100,000 키를 32 자 정도의 값으로로드했습니다. 두 키 크기에서 8-15 초를 넘지 않았습니다. 이제 각 키의 값으로 4KB의 데이터를 넣으려고합니다. 처음 10000 키는 800 밀리 초가 걸립니다. 하지만 그 시점부터 점진적으로 느려지고 약 50,000 개의 키를 설정하는 데 약 40 분이 소요됩니다. node_redis (Mranney)으로 NodeJs를 사용하여 데이터베이스를로드하고 있습니다. 내가하고있는 실수가 있습니까? 아니면 크기가 4KB 인 큰 값으로 Redis가 느린가요?Redis 성능 문제?

다른 클라이언트를 현재 클라이언트와 평행하게 실행하고 키를 업데이트하면이 클라이언트는 8 초 이내에 50000 키를 4KB 값으로로드하는 작업을 완료하고 처음 클라이언트는 여전히 영원히 작업을 수행합니다. 그것은 노드 또는 redis 라이브러리의 버그입니까? 이것은 놀랍고 생산을 위해 받아 들일 수없는 것입니다.

+0

hiredis를 사용하고 있습니까? – generalhenry

+0

흠 .. hiredis를 설치했지만 필요한 경우 프로그램에 자동으로로드되는지 ('redis') 모르겠다. 그게 문제 야? – Lalith

+0

hiredis 모듈이 설치되어 있는지 확인하려면 node를 실행 한 다음'require ("hiredis")'를 실행하십시오. –

답변

5

노드에서 Redis로 일괄 쓰기를 수행하려면 몇 가지 종류의 역 압력을 받아야합니다. 기본적으로 노드는 모든 쓰기를 대기열에 넣고 나가는 대기열 크기의 상한을 적용하지 않습니다.

node_redis에는 기본적인 배압을 구현하기 위해들을 수있는 "드레인"이벤트가 있습니다.

+0

안녕 Matt, client.command_queue.length를보고 "drain"이벤트가 발생할 때까지 중지하려고 시도했습니다. client.command_queue.length는 항상 0입니다. 그래서 적절한 번호를 제공하는 client.offline_queue.length를 확인했지만 드레인 이벤트는 한 번만 발생합니다. 다시 시도하고 코드로 돌아갈 것입니다. 감사합니다. – Lalith

+0

첨부했습니다. 여기 코드는 https://gist.github.com/945441입니다. 이것은 배압하는 적절한 방법이 아닌 것 같습니까? – Lalith

+2

여기에 몇 가지 다른 문제가 있습니다.첫 번째는 사전 연결 명령이 대기 중임을 나타냅니다. 두 번째는 일단 연결이되면 전송 된 명령에 대해 다른 큐가 유지되지만 응답은 아직 수신되지 않은 것입니다. 두 경우 모두 다루는 일반적인 방법을 예제로 추가했습니다. https://github.com/mranney/node_redis/blob/master/examples/backpressure_drain.js –

3

기본 redis 구성은 그런 용도로 최적화되어 있지 않습니다. 나는 당신이 32 바이트의 페이지 크기로 디스크에 스와핑했음을 의심한다. 즉, 추가 된 각 키는 연속적인 128 페이지의 빈 페이지를 찾아야하고 시스템 VM을 사용하거나 스왑 파일을 많이 확장해야 할 필요가 있음을 의미한다.

키를 업데이트하면 공간이 이미 할당되어 성능 문제가 보이지 않습니다.

+0

이것은 테스트 목적으로 만 사용되므로 별 관심이 없습니다. 그러나 이러한 요구가 실시간으로 발생하고 응용 프로그램에 많은 양의 데이터를 저장해야한다면 어떻게 될까요? 요구 사항에 맞게 변경할 수있는 구성이 있습니까? – Lalith

+0

또한 첫 번째 클라이언트가 모든 50000 개의 키를 생성하기 전에 두 번째 클라이언트를 실행하면 첫 번째 클라이언트보다 앞서 완료됩니다. 네가 한 말은 내가 직면 한 문제가 아닐 수도있다. – Lalith

+3

페이지 크기 및 메모리 사용을 구성 할 수 있습니다 - redis.conf의 주석을 확인하십시오. 두 번째 클라이언트 마무리는 반드시 그 시나리오를 배제하지 않습니다. 메모리 부족 조건과 동시성의 조합은 특히 시간 초과 및 자동 재시도가 관련 될 경우 매우 복잡 할 수 있습니다. 예를 들어, 오류가 발생할 때마다 이전 키를 모두 재설정 할 수 있습니까? –

0

비동기 적으로 수행되는 NodeJs에서 많은 세트 (키 값)를 수행 했으므로 많은 소켓 연결이 동시에 열려 있습니다. NodeJs 소켓 쓰기 버퍼가 오버로드되어 GC가 노드 프로세스와 연결될 수 있습니다.

추 신 : 톰이 제안한대로 재구성 메모리 구성을 변경했으나 여전히 동일하게 수행하고있었습니다.