Redis JSON 성능

Redis JSON 성능 (Performance)

Redis JSON이 어느 정도의 성능을 내는지 미리 감을 잡으려면, 다른 Redis 명령처럼 redis-benchmark로 테스트해 볼 수 있어요. 다만 테스트를 더 세밀하게 제어하기 위해 이 문서에서는 Go로 작성된 ReJSONBenchmark라는 도구를 씁니다. 아래 수치는 Redis 서버와 벤치마크 도구를 모두 실행한 AWS EC2 c4.8xlarge 인스턴스에서 얻은 결과예요. 연결은 네트워킹 스택을 통해 이뤄졌고, 모든 테스트는 비-파이프라인(non-pipelined) 방식입니다.

노트: 아래 결과는 아직 많이 최적화되지 않은 Redis JSON의 프리뷰(preview) 버전으로 측정한 값이에요.

출처: Redis 공식 문서 — performance

Redis JSON 기준 성능 (Baseline)

작은 객체 (A smallish object)

순수하게 합성된(synthetic) 값이지만 흥미로운 JSON 값을 테스트해 봐요. 테스트 대상은 /tests/files/pass-100.json인데, 크기 380바이트이고 중첩(nested)된 구조예요. 먼저 SET하고, 그다음 여러 경로를 써서 GET하는 순서로 테스트합니다.

더 큰 배열 (A bigger array)

더 큰 값으로 넘어가서, /tests/files/pass-jsonsl-1.json의 1.4 kB 배열을 사용해요.

큰 객체 (A largish object)

이번에는 무려 3.5 kB에 달하는 거대한 값, /tests/files/pass-json-parser-0000.json을 다뤄 봅니다.

숫자 연산 (Number operations)

마지막으로 덧셈과 곱셈 몇 가지를 테스트해요.

기준선 (Baseline)

기준선을 잡기 위해 Redis PING 명령을 사용합니다. 먼저 redis-benchmark가 보고하는 결과를 볼게요:

~$ redis/src/redis-benchmark -n 1000000 ping
====== ping ======
  1000000 requests completed in 7.11 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

99.99% <= 1 milliseconds
100.00% <= 1 milliseconds
140587.66 requests per second

ReJSONBenchmark의 동시성(concurrency)은 설정 가능하므로 몇 가지 설정을 테스트해 보면, **16개 워커(workers)**에서 최상의 처리량이 나오는 것을 알 수 있어요.

흥미롭게도 우리 벤치마킹 도구는 PING에서 redis-cli의 140K보다 약간 못한 116K ops 정도를 냅니다.

빈 문자열 (The empty string)

또 다른 JSON 벤치마크는 빈 문자열("", 2바이트)을 설정하고 가져오는 테스트예요. 실용적이진 않지만 모듈의 기본 성능을 알려줍니다.

서버 측 Lua 스크립팅과의 비교 (Comparison vs. server-side Lua scripting)

Redis 오픈 소스의 JSON 성능을 Redis 내장 Lua 엔진과 비교해 봅니다. 이를 위해 /benchmarks/lua의 Lua 스크립트를 사용해요. 이 스크립트들은 JSON 또는 MessagePack 형식으로 저장된 값에 JSON의 GET/SET 기능을 제공합니다. 각 연산(set root, get root, set path, get path)은 다양한 크기의 객체에 대해 각 "엔진"별로 실행됩니다.

루트 설정 및 가져오기 (Setting and getting the root)

원시 JSON(raw JSON)을 저장하는 것이 이 테스트에서 가장 잘 나오는데, 애초에 처리되지 않은 문자열을 그대로 제공하기 때문이라 놀랍지 않아요. Redis를 불투명한 데이터 캐싱용으로 쓰는 건 가능하지만, 이 경우 전체 값을 한 번에 업데이트하는 것 외에는 다른 업데이트가 안 됩니다.

그래서 더 의미 있는 비교는 JSON과 MessagePack 변형 사이의 비교예요. 둘 다 저장 전에 들어오는 JSON 값을 처리하니까요. 두 방식의 처리율과 지연 시간은 매우 비슷하게 움직이지만, 절대 측정값은 Redis JSON의 성능이 더 개선될 여지가 있음을 시사해요.

객체 일부 설정 및 가져오기 (Setting and getting parts of objects)

이 테스트는 Redis JSON이 왜 존재하는지를 보여줍니다. Lua 변형보다 더 좋은 성능을 낼 뿐 아니라, 객체의 전체 크기와 관계없이 일정한 처리율과 지연 시간을 유지해요. 여기엔 마법이 없어요. JSON은 값을 역직렬화(deserialized)된 상태로 유지해서 일부에 접근하는 것이 비교적 저렴한 연산이 됩니다. 반면 원시 JSON이나 MessagePack은 어떤 작업을 하기 전에 전체 객체를 디코딩해야 하므로, 객체가 커질수록 비용이 증가하죠.

추가 차트 (Even more charts)

이 차트들은 파일(값)별로 같은 내용을 독립적으로 보여주는 것들이에요.

원시 결과 (Raw results)

아래는 벤치마크의 원시 결과를 CSV 형식으로 나타낸 것입니다.

title,concurrency,rate,average latency,50.00%-tile,90.00%-tile,95.00%-tile,99.00%-tile,99.50%-tile,100.00%-tile
[ping],1,22128.12,0.04,0.04,0.04,0.05,0.05,0.05,1.83
[ping],2,54641.13,0.04,0.03,0.05,0.05,0.06,0.07,2.14
[ping],4,76000.18,0.05,0.05,0.07,0.07,0.09,0.10,2.10
[ping],8,106750.99,0.07,0.07,0.10,0.11,0.14,0.16,2.99
[ping],12,111297.33,0.11,0.10,0.15,0.16,0.20,0.22,6.81
[ping],16,116292.19,0.14,0.13,0.19,0.21,0.27,0.33,7.50
[ping],20,110622.82,0.18,0.17,0.24,0.27,0.38,0.47,12.21
[ping],24,107468.51,0.22,0.20,0.31,0.38,0.58,0.71,13.86
[ping],28,102827.35,0.27,0.25,0.38,0.44,0.66,0.79,12.87

(전체 CSV 결과는 원문 페이지의 "Raw results" 섹션 참고)

더 알아보기 (Learn more)