본문 바로가기

Programing

redis pipeline

Redis에서 Pipeline을 사용해야하는 이유 


참고 : http://redis.io/topics/pipelining 


redis는 TCP 서버로 Request/Response protocol 이라고 불리우는 클라이언트-서버 모델을 사용한다. 

즉, 이말은 request가 아래와 같은 단계를 거쳐서 처리된다는 것을 의미한다. 

  • 클라이언트는 query를 서버로 보내고 소켓을 통해 서버로 부터 결과(response)를 받는다. 주로 blocking 모델을 따른다. 
  • 서버는 명령(command)를 수행하고 결과(response)를 클라이언트로 다시 보낸다. 

결국 4개의 커맨드를 날린다면 redis에서 아래와 같은 순서로 처리된다. 

  • Client: INCR X
  • Server: 1
  • Client: INCR X
  • Server: 2
  • Client: INCR X
  • Server: 3
  • Client: INCR X
  • Server: 4


보면, 클라이언트가 요청을 한후 서버의 응답을 받고, 다시 요청을 하고 다시 요청을 받는데 이런 방식으로는 더 많은 request를 처리하기 힘들다. 

이유는 만약 클라이언트 - 서버간에 network가 좋지 않을 경우, RTT (Round Trip Time : 클라이언트에서 서버 왕복시간)이 길어지기 때문이다. 

예를 들어 RTT가 250 milliseconds라면 아무리 서버가 1초에 10만개의 요청을 동시에 처리할 수 있다고 해도 cleint에서는 1초에 4개(250 millisecond * 4) 밖에 요청하지 못한다. 



Redis pipeline을 사용하면 


아래과 같은 형식으로 request를 처리 할 수있다. 


$ (echo -en "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG

위를 보면 3개의 ping 명령어를 netcat명령어를 통해 한번에 전송하고 서버에서 처리한후 3개의 결과를 받아온다. 

위의 방식으로 처음에 4개의 명령어를 처리하는 과정은 아래와 같다. 

  • Client: INCR X
  • Client: INCR X
  • Client: INCR X
  • Client: INCR X
  • Server: 1
  • Server: 2
  • Server: 3
  • Server: 4


성능 향상에 대해서 (benchmark) 


require 'rubygems'
require 'redis'

def bench(descr)
    start = Time.now
    yield
    puts "#{descr} #{Time.now-start} seconds"
end

def without_pipelining
    r = Redis.new
    10000.times {
        r.ping
    }
end

def with_pipelining
    r = Redis.new
    r.pipelined {
        10000.times {
            r.ping
        }
    }
end

bench("without pipelining") {
    without_pipelining
}
bench("with pipelining") {
    with_pipelining
}

위의 코드에서 redis server로 pring을 날리는 명령어는 첫번째는 매번 request로 날리고 두번째는 pipeline을 사용해서 요청하고 있다. 

결과는 아래와 같다. 


without pipelining 1.185238 seconds
with pipelining 0.250783 seconds


즉, 5배의 성능향상 결과가 있다. 항상 5배라기 보다 network의 RTT의 영향을 받지 않았을 때의 최고 속도대비 RTT의 영향을 받았을 때(실험자의 상황에서)의 결과를 보여주는 것이다. 


이것은 여러 명령어를 처리하는 transaction과는 다르니 이부분에 대해서는 다음 문서를 참고 하면 되겠다. 

http://redis.io/topics/transactions



'Programing' 카테고리의 다른 글

redis cluster 구성하기  (0) 2014.09.23
redis transaction  (0) 2014.09.10
redis  (0) 2014.09.08
logback  (0) 2014.07.25
homebrew, mongodb 설치  (0) 2012.05.05