web/Spring

lettuce pipeline코드 사용시 커넥션 풀 사용 필요

반응형

lettuce를 사용해서 레디스를 사용을 하고 있었는데 어느날 갑자기 아래처럼 레디스 커넥션을 못잡는 이슈가 발생했다.

org.springframework.data.redis.RedisSystemException: Redis exception; nested exception is io.lettuce.core.RedisException: Master is currently unknown: [RedisMasterReplicaNode [redisURI=redis://xxx.xxx.com?timeout=20s, role=REPLICA]]

 

처음에는 aws 레디스쪽 이슈일것으로 의심했으나 레디스쪽에는 별다른 지표가 없었고 애플리케이션에서 커넥션을 사용하지 못하는 것 같았다.

 

이번에 배포 하면서 들어간 코드는 비동기 코드로 파이프라인 코드를 사용하는 부분이 들어갔었다. 파이프라인을 사용한 부분은 set + expire를 줘야했고 한번에 100개 이상의 키를 넣었어야했는데 단건으로 요청할시 하나의 요청이 20ms걸린다고 가정했을 때 100개면 2초가 소요되었다.

 

이는 로직상 너무 늦어지는 부분이었고 이걸 줄이기 위해서 요청을 한번에 레디스에 보낼수 있도록 파이프라인을 사용했고 그결과 20~100ms사이로 요청을 확 줄일 수 있었다.

 

근데 이부분이 커넥션을 못찾게 되는 부분을 만들게 되었다.

 

이유가 모였을까? 기본적으로 lettuce는 하나의 싱글 커넥션을 가지고 처리를 하고 내부적으로는 네티 기반(event-driven i/o)으로 되어있어서 멀티 스레드 환경에서 사용하는데 문제가 없다. 

 

그래서 파이프라인이 들어가기 전에 비동기 환경에서 사용했어도 별도의 커넥션 풀을 사용하지 않아도 큰 문제가 없었다. 하지만 pipeline이나 트랜잭션의 요청의 경우 블로킹 요청이기 때문에 네티 환경에서 사용하게 되면 문제가 발생된다.

 

이 사실을 알고 우리는 배치 애플리케이션이었고 굳이 레디스에 msetex하는 파이프라인 부분에 비동기로 할필요가 없어서 동기로 바꿨고 문제는 해결되었다.

 

근데 만약 계속 비동기 사용이 필요한경우에는 하나의 커넥션으로 하게되면 block되는 과정에서 다른 스레드에서 커넥션을 사용하지 못하는 문제가 발생하기 때문에 커넥션 풀을 꼭 사용해야한다.

 

커넥션 풀 사용하는 방법

https://github.com/redis/lettuce/wiki/Connection-Pooling

 

참고  :https://bytepitch.com/blog/article/redis-integration-spring-boot

 

Software Engineering Company Blog | BytePitch

BytePitch shares knowledge on software development topics to support the community and help software engineering projects succeed.

bytepitch.com

 

반응형