Redis) 이것이 레디스다 8 - 파이프라인

대량의 데이터를 입력하는 방법

  1. 레디스 클라이언트 라이브러리를 사용하여 하나씩 순차적으로 데이터를 입력하는 방법
    • 가장 접근하기 쉽지만 하나씩 순차적으로 입력하는 방법은 데이터 입력에 걸리는 시간이 현저하게 느리다.
    • 또한 라이브러리를 사용하면 네트워크 통신으로 인한 시간이 데이터 처리 시간과 별개로 추가된다.
  2. 레디스 파이프라인을 사용하여 한꺼번에 입력하는 방법
    • 한 번에 모든 데이터를 전송하기 때문에 단일 데이터를 여러번 입력하는 것에 비해 빠른 속도를 보장한다.
  3. 레디스 스냅샷 파일에 직접 기록하는 방법
    • 스냅샷 파일에 대량의 데이터를 기록하고 서버를 재기동한다. (재기동이라는 단점으로 인해 비추천)

파이프라인

  • 레디스 명령 형식

다음 shell script를 통해 1,000,000개의 레디스 명령어를 생성 후 파이프라인으로 이를 실행해보자.

1
2
3
4
5
6
#!/bin/bash

for i in {1..1000000}
do
printf "set key${i} val${i}\r\n" >> sample_data
done
1
2
3
4
[devson@localhost redis]$ cat sample_data | redis-cli --pipe
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 1000000
  • 레디스 프로토콜 형식

위 레디스 명령어를 프로토콜 형식으로 변경하여 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

for i in {1..1000000}
do
key="key${i}"
val="val${i}"
len=${#key} # 문자열의 length를 구한다.

printf "*3\r\n" >> sample_data

printf "\$3\r\n" >> sample_data
printf "set\r\n" >> sample_data

printf "\$${len}\r\n" >> sample_data
printf "${key}\r\n" >> sample_data

printf "\$${len}\r\n" >> sample_data
printf "${val}\r\n" >> sample_data
done

앞서 레디스 명령 형식으로 보냈을 경우 레디스 프로토콜 형태로 변경하는 작업이 추가되기 때문에 처음부터 레디스 프로토콜 형식으로 보내는 것이 더 빠르다.
(하지만 두 경우 모두 빠르기 때문에 상황에 맞게 사용하면 된다.)

  • Jedis의 파이프라인 기능 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Jedis jedis = new Jedis(host, port);
jedis.connect();

Pipeline pipe = jedis.pipelined();

for (var i = 1; i < 1_000_000; i++) {
String key = "key" + i;
String val = "val" + i;
pipe.set(key, val);
}

pipe.sync();

jedis.disconnect();

파이프 라인을 운영 중인 시스템에 사용하면 파이프 라인 명령이 레디스의 모든 리소스를 점유하게 되어 서비스의 응답 속도가 저하되기도 한다.
이런 경우 오히려 라이브러리를 통해 입력하는 편이 낫다.

Share