springboot_connection_pool
Redis Connection Pool and Thread
레디스 개발자 교육 신청 |
레디스 정기점검/기술지원 Redis Technical Support |
레디스 엔터프라이즈 서버 Redis Enterprise Server |
---|
Redis Connection Pool and Thread
Spring Boot에서 Redis Connection Pool 사용 방법과 Thread로 테스트 결과를 설명합니다.
- Spring Boot: 3.1.4
- Spring: 6.0.12
- Lettuce: 6.2.6
- commons-pool2: 2.11.1
Connection Pool 설정 - LettuceConnectionFactory
- Connection Pool을 사용하지 않을 경우: LettuceClientConfiguration를 사용합니다.
- Connection Pool을 사용할 경우: GenericObjectPoolConfig에 연결 수를 설정하고, LettucePoolingClientConfiguration를 사용해서 poolConfig(genericObjectPoolConfig)를 설정합니다.
- connectionFactory.setShareNativeConnection(true/false) 설정: 기본값은 true입니다.
- TRUE: Connection Pool을 설정해도 Redis와 연결은 1개만 맺습니다. Connection Pool을 적용하려면 false로 설정해야 합니다.
- FALSE: Connection Pool을 사용하려면 false로 설정해야 합니다. 이 경우 스레드마다 스레드 시작 시 Redis 서버와 연결을 하나씩 맺습니다. 스레드가 100개이면 Redis 서버에 100개의 연결이 생깁니다.
- Connection Pool을 설정하지 않은 상태에서 FALSE로 했을 경우:
명령 실행 시 연결이 필요하다고 판단되면 연결을 맺습니다.
연결 개수가 일정하지 않습니다.
테스트해보면 연결 시에도 문제가 발생할 수 있고, 성능에도 좋지 않습니다. 권장하지 않습니다.
RedisConfig.java
Thread 설정
Thread 개수를 입력 받아 실행합니다. 각 thread 당 1000번 save(set 명령)을 실행합니다.
StringController.java
Repository 설정
Save 메소드에서 set 명령을 실행합니다.
StringRepository.java
Project 생성
start.spring.io
common-pool2는 dependencies에 없습니다.
build.gradle
dependencies에 implementation 'org.apache.commons:commons-pool2' 추가했습니다.
성능 테스트 Performance Test
레디스 서버와 연결(connection)이 1개일 때와 여러 개(스레드 당 1개)일 때 성능 비교.
- 일반적으로 여러 스레드가 1개 연결을 사용하는 것보다는 스레드당 1개 연결을 사용하는 것이
성능이 더 좋을 거라는 생각.
- 1개 연결을 공유하게 하는 setShareNativeConnection()의 기본 값이 왜 true로 했을까에 대한 의문
결과: 스레드(1~100)까지는 Case 1,2의 성능이 거의 같다.
(약간의 숫자 차이는 있지만 성능 테스트마다 숫자는 조금씩 다르게 나올 수 있으므로 가의 같은 것으로 본다.)
스레드(500, 1000)에서는 Case 2가 성능이 떨어진다.
Case 2에서 스레드 5000은 스레드 시작 시 레디스 서버와 연결을 맺는데
연결 맺는 시간이 너무 오래 걸려서 테스트가 불가능했다.
결론: 연결 1개를 사용하는 것이 성능에 좋다.
Case 1: 연결 1개
setShareNativeConnection(true), true는 기본값이다.
스레드 | 연결 | 서버CPU | 입력건수 | 시간(ms) | SET(μs) | Network |
---|---|---|---|---|---|---|
1 | 1 | 2% | 1,000 | 8,126 | 8126 | |
10 | 1 | 3% | 10,000 | 8,651 | 865 | |
100 | 1 | 5% | 100,000 | 14,768 | 147 | 3Mbps |
500 | 1 | 10% | 500,000 | 34,637 | 69 | 7Mbps |
1000 | 1 | 15% | 1,000,000 | 62,424 | 62 | 8Mbps |
5000 | 1 | 20% | 5,000,000 | 288,450 | 58 | 9Mbps |
Case 2: 연결 여러 개
스레드 | 연결 | 서버CPU | 입력건수 | 시간(ms) | SET(μs) | Network |
---|---|---|---|---|---|---|
1 | 1 | 2% | 1,000 | 7,869 | 7869 | |
10 | 10 | 5% | 10,000 | 8,233 | 823 | 1Mbps |
100 | 100 | 20% | 100,000 | 14,093 | 141 | 1Mbps |
500 | 500 | 20% | 500,000 | 56,639 | 113 | 5Mbps |
1000 | 1000 | 20% | 1,000,000 | 128,244 | 128 | 5Mbps |
5000 | 5000 |
- SET(us): Client 기준으로 SET 명령 1개당 걸린 시간(microsecond, μs), 레디스 서버 기준으로 약 3μs 정도 걸린다.
- 서버CPU: 20%를 넘지 못했다. 서버 CPU를 100% 다 사용하게 하려면 client(agent) 개수를 늘려야 한다.
<< RedisTemplate | Connection Pool | Async >> |
---|