2016-09-29 3 views
0

그래서 정렬 된 집합에서 점수를 증가시키고 있습니다. 이것이 Jedis 클라이언트를 사용하는 Java 응용 프로그램에서 초당 약 10-30 개의 명령을 실행하는 유일한 명령입니다. 나는 단지 점수를 업데이트하고 있기 때문에 응답에 대해서도 신경 쓰지 않습니다. 내 우려는 각각의 ZINCRBY 명령이 자체 TCP 패킷에 저장되고 내 스레드가 다음 ZINCRBY 스레드를 보내도록 허용하기 전에 다음 응답을 기다리는 것입니다.Redis Java Client : 성능 향상을 위해 명령을 파이프 라인에 버퍼해야합니까?

그래서 파이프 라이닝을 구현하여 한번에 50 개의 명령을 배치 할 수 있습니다. 다음은 코드/디자인 패턴 냄새가 나는 곳입니다.이 디자인 패턴이 드라이버가 처리해야하는 공통점이 아닌가? .net "StackExchange.redis"드라이버는 자동으로 일괄 처리 명령을 수행하지만 Java 드라이버에는이 기능이없는 것으로 보입니까? 들어오는 명령을 파이프 라인에 넣고 50 개 항목을 호출 한 후 sync()을 호출하는 사용자 지정 redis 명령 버퍼 클래스를 만드는 것이 좋습니다.

20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.393 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.394 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.394 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.629 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.630 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.630 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.631 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.632 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Opening RedisConnection 
20160929 06:48:27.633 [Twitter4J Async Dispatcher[0]] DEBUG o.s.d.r.c.RedisConnectionUtils # Closing Redis Connection 

을 그래서 봄 제공된 템플릿 패턴을 통해 순진 실행 된 명령에 따라 연결을 (폐쇄 것 같습니다 : 나는 봄 데이터 레디 스를 통해 Jedis을 사용하고 같은

또한, 나는 내 기록이 나타났습니다). 연결을 닫으면 패킷 당 하나의 명령을 보내도록 TCP 버퍼가 강제로 처리되므로 소켓이 상당한 양의 CPU를 먹기 때문에 꽤 비효율적 인 것으로 보입니다. Spring Data Redis API는 Jedis 클라이언트에 직접 액세스 할 수 있지만 현재 파이프 라인이 열려 있으면 연결을 닫지 않으므로 "파이프 라인 버퍼"를 작성하는 것이 좋습니다.

짧은에서 redis 파이프 라인에 쓰는 버퍼와 X 명령 이후의 플러시를 생성/활용해야합니까? 나는 순전히 각 CPU 사이클 (높은 AWS 청구서)을 낭비하는 생각을별로 좋아하지 않으며, 내 시나리오에 더 나은 디자인 패턴이 있는지 궁금해합니다. 또는 다른 Java Redis Client로 전환하면이 문제가 해결됩니다. 또는 이미 redis 파이프 라인에 명령을 버퍼링하는 Java 라이브러리가있는 경우

답변

2

여기서 여러 가지 측면을 언급 할 때 여기에서 자세히 알아볼 필요가 있다고 생각합니다.

일반적으로 모든 Java Redis 클라이언트 (Jedis, , Redisson 등)는 기본적으로 TCP 채널에 직접 명령을 기록합니다. 따라서 각 명령은 하나 이상의 TCP 패킷으로 전송됩니다. 두 클라이언트 모두 TCP 채널에 Redis 명령을 작성하기 위해 비동기식/이벤트 위주의 프로그래밍 모델을 사용하기 때문에 이들의 작동 모드로는 Lettuce 및 Redisson이 있습니다. Jedis는 차단 API를 노출하므로 명령 결과를 기다려야합니다. 레디 송 (Redisson)과 레터스 (Lettuce)는 명령 결과를 기다리지 않도록 여러 종류의 API (Futures를 사용하는 비동기식 또는 RxJava/리 액티브 스트림을 사용한 리 액티브)를 제공합니다.

일괄 처리/버퍼링은 클라이언트 메모리에서 명령을 수집하고 명령을 일괄 처리로 Redis에 전송하는 또 다른 기술입니다. 이것은 LettuceRedisson 클라이언트 모두에서 작동합니다. Jedis는 명령을 TCP 채널에 직접 파이프 라이닝 모드로 씁니다.

명령 일괄 처리는 몇 가지 의미를 제공합니다. 자동 배치 명령 (예 : 10 또는 50 크기)이 가능하지만 사용자가주의해야합니다.일괄 처리에는 항상 명령이 피할 수 있도록 마지막 동기화가 필요하며 일괄 처리 크기에 아직 도달하지 않았기 때문에 보내지 않았습니다.

스프링 데이터 Redis는 Jedis와 Lettuce를 사용하여 기능을 노출하므로 Spring Data Redis는 두 드라이버의 공통된 요소에 대처해야합니다. Redis와 상호 작용할 때마다 닫히지 않는 풀링 된 연결을 활용할 수 있도록 Jedis와의 연결 풀링을 사용하도록 Spring Data Redis를 설정할 수 있습니다.

+0

감사합니다. 나는 약간의 연구를 한 후에 상추를 사용할 생각이다. 내 유스 케이스에서는 스트리밍 트위터 API에서 읽고, 크기 50의 버퍼를 쉽게 채우고 connection.flushCommands();를 호출 할 수 있도록 충분한 일관성있는 redis 명령을 보내야한다. 나는 플러시 - 후 - 엑스 - 명령 또는 다른 화재 -와 - 잊지 최적화 기능을 이미 자바 드라이버에서와 같은 경우 .net StackExchange.redis 드라이버 (http://stackoverflow.com/questions 참조하십시오) 궁금 해서요/27796054/pipelining-vs-batching-in-stackexchange-redis) – Zombies

+0

게시글에 결론을 추가하는 것을 잊어 버렸습니다. 최적화 대상을 아는 것이 중요합니다. 각 접근법은 자체 속성을 가지고 있으며 접근 방식과 사용 사례에 적합해야합니다. flush-after-x-commands 포인터를 주셔서 감사합니다. 이것은 관심의 대상 일 수 있습니다. – mp911de

0

파이프 라인은 통신 비용을 줄이기 위해 Redis의 일반적인 패턴입니다. Jedis은 파이프 라이닝을 지원하는 redis 용 권장 Java 드라이버입니다. Lettucepipelining도 지원하는 대안입니다.

관련 문제