make-delivery 프로젝트

[#5] 성능을 위해 Redis keys 대신 scan 이용하기

sunggook lee 2020. 10. 25. 22:58

Redis scan을 사용하는 이유 

레디스의 명령어중 keys를 이용하면 모든 키값들을 가져올 수 있지만 이키값들을 가져오는동안 다른 명령어를 수행하지 못합니다. 따라서 성능에 영향을 줄 수 있어 레디스에서는 scan,hscan을 권장합니다. redis의 keys 명령어는 시간 복잡도가 O(N)입니다. 레디스는 싱글스레드로 동작하기 때문에 이처럼 어떤 명령어를 O(n)시간 동안 수행하면서 lock이 걸린다면 그시간동안 keys 명령어를 수행하기 위해 멈춰버리기 때문입니다.

 

Redis에서 제공하는 Scan명령어는 Keys처럼 한번에 모든 레디스 키를 읽어오는 것이아니라 count 값을 정하여 그 count값만큼 여러번 레디스의 모든 키를 읽어오는 것입니다. (기본 count값은 10입니다) 예를들어 레디스에 읽어야하는 키값이 총 10000개라고 치고 count가 10개이면 1000번에 나눠서 이 키를 읽는 것입니다. 커서가 0이 될대까지 while문을 돌며 키를 나눠서 읽는 것입니다.

 

따라서 count의 개수를 낮게잡으면 count만큼 키를 읽어오는 시간은 적게걸리고 모든 데이터를 읽어오는데 시간이 오래걸리지만 그 사이사이 시간에 다른 요청들을 레디스에서 처리해줄 수 있을 것입니다. 반대로 count의 개수를 높게 잡으면  count의 개수만큼 읽어오는데 시간이 오래걸리고 모든데이터를 읽는데는 시간이 짧게 걸리지만 그 사이사이에 다른 요청을 받는 횟수가 줄어들어 레디스가 다른 요청을 처리하는데 병목이 생길 수 있습니다.

 

레디스 scan 퍼포먼스 medium.com/@chlee7746/redis-scan-%EB%AA%85%EB%A0%B9%EC%96%B4-%ED%8D%BC%ED%8F%AC%EB%A8%BC%EC%8A%A4-e29e242b8038

 

 

redisConnection을 열고 hScan을 사용합니다.

 

스프링에서 실제 사용 방법

RedisTemplate.execute 함수를 사용하여 명령어들을 한번에 처리하고 RedisCallback을 이용해 다수의 operation이 같은 Redis Connection안에서 수행되는 것을 보장합니다.

 

RedisTemplate.execute 함수는 RedisTemplate.executePipelined와 똑같이 여러 명령어들을 파이프라인을 열고 한번에 처리합니다. execute함수는 파이프라인을 열고 RedisCallback함수를 실행하여 한번에 명령어들을 처리합니다.

 

 

 

프로젝트:

github.com/f-lab-edu/make-delivery

 

f-lab-edu/make-delivery

구매자에게 음식 배달을 제공하는 서비스입니다. Contribute to f-lab-edu/make-delivery development by creating an account on GitHub.

github.com

 

참고자료

docs.spring.io/spring-data-redis/docs/current/reference/html/#reference

 

Spring Data Redis

Some commands (such as SINTER and SUNION) can only be processed on the server side when all involved keys map to the same slot. Otherwise, computation has to be done on client side. Therefore, it is useful to pin keyspaces to a single slot, which lets make

docs.spring.io

redis.io/commands/keys

 

KEYS – Redis

Returns all keys matching pattern. While the time complexity for this operation is O(N), the constant times are fairly low. For example, Redis running on an entry level laptop can scan a 1 million key database in 40 milliseconds. Warning: consider KEYS as

redis.io