[REDIS] 레디 스에서 파이프 라인을 사용할 때 왜 이렇게 10 만 개 레코드로 둔화되고?
REDIS레디 스에서 파이프 라인을 사용할 때 왜 이렇게 10 만 개 레코드로 둔화되고?
이 내 테스트 코드 그래서 파이프 라인이 많은 세트 / GET은 레디 스에서 요구하는 더 좋은 방법이라고 말한다 :
public class TestPipeline {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
JedisShardInfo si = new JedisShardInfo("127.0.0.1", 6379);
List<JedisShardInfo> list = new ArrayList<JedisShardInfo>();
list.add(si);
ShardedJedis jedis = new ShardedJedis(list);
long startTime = System.currentTimeMillis();
ShardedJedisPipeline pipeline = jedis.pipelined();
for (int i = 0; i < 100000; i++) {
Map<String, String> map = new HashMap<String, String>();
map.put("id", "" + i);
map.put("name", "lyj" + i);
pipeline.hmset("m" + i, map);
}
pipeline.sync();
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
}
내가 그것을 실행하면, 잠시 동안이 프로그램과 응답이 없다,하지만 난 파이프 작업을하지 않을 때, 그것은 격차 파이프 라인없이 어떻게 더 나은 왜 내가 혼란 스러워요 있도록 만 20,073 밀리합니다!
나에게 대답을 주셔서 감사합니다, 몇 가지 질문은, 어떻게 6메가바이트 데이터를 계산합니까? 내가 10K 데이터를 보낼 때, 파이프 라인은 일반 모드보다 항상 더 빠르지 만 100,000로, 파이프 라인은 더의 대답을들은 것이 바람직 선택 said.Is이 내가 그것을 이해하지 않기 때문에 JIT와 anyting 다음과 같다 100-1000 작업을 생각하지 않을 것이다?
해결법
-
==============================
1.당신이 이러한 벤치 마크 (특히 벤치 마크 JVM을 사용)을 쓰기 전에 고려해야 할 몇 가지 사항이 있습니다 :
당신이 이러한 벤치 마크 (특히 벤치 마크 JVM을 사용)을 쓰기 전에 고려해야 할 몇 가지 사항이 있습니다 :
이제, 레디 스 파이프 라인에 대한 당신의 파이프 라인은 너무 깁니다. 파이프 라인의 100K 명령은 Jedis가 레디 스 아무것도를 보내기 전에 6메가바이트 버퍼를 구축하는 것을 의미한다. 이 포화 될 (클라이언트 측 및 서버 측 아마도) 소켓 버퍼를 의미하고, 레디 스도 6메가바이트 통신 버퍼를 처리 할 것이다.
또한, 귀하의 벤치 마크 (파이프 라인을 사용하는 마술은 비동기하지 않습니다) 여전히 동기입니다. 즉, Jedis는 파이프 라인의 마지막 쿼리 레디 스에 전송 될 때까지 응답을 읽기 시작되지 않습니다. 파이프 라인이 너무 긴 경우, 그것은 일을 차단할 수있는 잠재력을 가지고있다.
100-1000 운영에 파이프 라인의 크기를 제한하는 것이 좋습니다. 물론,보다 왕복 생성되지만, 상기 통신 스택의 압력이 수용 가능한 수준으로 감소한다. 예를 들어, 다음 프로그램을 고려 :
import redis.clients.jedis.*; import java.util.*; public class TestPipeline { /** * @param args */ int i = 0; Map<String, String> map = new HashMap<String, String>(); ShardedJedis jedis; // Number of iterations // Use 1000 to test with the pipeline, 100 otherwise static final int N = 1000; public TestPipeline() { JedisShardInfo si = new JedisShardInfo("127.0.0.1", 6379); List<JedisShardInfo> list = new ArrayList<JedisShardInfo>(); list.add(si); jedis = new ShardedJedis(list); } public void push( int n ) { ShardedJedisPipeline pipeline = jedis.pipelined(); for ( int k = 0; k < n; k++) { map.put("id", "" + i); map.put("name", "lyj" + i); pipeline.hmset("m" + i, map); ++i; } pipeline.sync(); } public void push2( int n ) { for ( int k = 0; k < n; k++) { map.put("id", "" + i); map.put("name", "lyj" + i); jedis.hmset("m" + i, map); ++i; } } public static void main(String[] args) { TestPipeline obj = new TestPipeline(); long startTime = System.currentTimeMillis(); for ( int j=0; j<N; j++ ) { // Use push2 instead to test without pipeline obj.push(1000); // Uncomment to see the acceleration //System.out.println(obj.i); } long endTime = System.currentTimeMillis(); double d = 1000.0 * obj.i; d /= (double)(endTime - startTime); System.out.println("Throughput: "+d); } }
이 프로그램을 사용하면 또는 파이프 라인없이 테스트 할 수 있습니다. 그것이 최소한 10 초 동안 실행되도록, 파이프 라인을 사용하는 반복 (N 매개 변수)의 수를 증가해야합니다. 당신은 루프에서 println 메소드의 주석을 해제하면 프로그램이 시작에서 느린 것을 깨닫게되고 JIT가 (프로그램이 적어도 몇 초에 실행해야하는 이유의 의미있는 결과를 제공 할 수 있음) 최적화 것에 시작으로 빨리 얻을 것이다.
파이프 라인을 사용하는 경우 내 하드웨어 (오래된 애슬론 상자)에, 나는 8-9 배의 처리량을 얻을 수 있습니다. 이 프로그램은, 상기 내부 루프 포맷 키 / 값을 최적화 및 워밍업 단계를 추가함으로써 개선 될 수있다.
from https://stackoverflow.com/questions/16697389/why-it-is-so-slow-with-100-000-records-when-using-pipeline-in-redis by cc-by-sa and MIT license
'REDIS' 카테고리의 다른 글
[REDIS] 레디 스 명령은 사용 가능한 모든 키를 얻으려면? (0) | 2019.12.31 |
---|---|
[REDIS] 어떻게 레디 스 서버를 중지 할 수 있습니다? (0) | 2019.12.31 |
[REDIS] 방법 레디 스에서 특정 패턴과 일치하지 않는 키를 얻으려면? (0) | 2019.12.31 |
[REDIS] 레디 스 : 설정에서 키 값 쌍으로 설정 시간 제한 (0) | 2019.12.31 |
[REDIS] 레디 스 읽을 수없는 저장 악센트 (0) | 2019.12.31 |