목적
- Redis 를 사용 중인 시스템의 성능 개선 방향을 모색하고, 시스템상에서 안정성을 위해하지 않고, 성능을 개선 할 수 있는 방안이 있기에, 이에 대한 테스트를 진행하여
증명함을 목적으로 한다.
- Redis 를 사용 중인 시스템의 성능 개선 방향을 모색하고, 시스템상에서 안정성을 위해하지 않고, 성능을 개선 할 수 있는 방안이 있기에, 이에 대한 테스트를 진행하여
테스트 환경
- 아래 환경으로, 1개의 서버에 3개의 Redis Master 서버를 기동하고, 테스트를 수행하였음.
- 장비 사양구성상세
CPU Intel(R) Xeon(R) CPU E5645@2.40GHz 6 Core ( HT X) Memory 16 GB Disk 1+0 RAID HDD 550G Network NetXtreme II BCM5709 1Gigzbit Ethernet 1 Port - Redis 구성구성상세
Replication Active-StandBy Replication 구성 , RDB 파일 이중화 AOF Active-StandBy AOF 구성 Memory 각 Redis 당 3GB - 장비 구성IPPORTRole
X.X.X.45 50001 Master X.X.X.45 50002 Master X.X.X.45 50003 Master X.X.X.44 50001 Slave X.X.X.44 50002 Slave X.X.X.44 50003 Slave X.X.X.43 NULL BenchMark Toll - 3개 Process , 50 Clinet Per a Process
- 아래 환경으로, 1개의 서버에 3개의 Redis Master 서버를 기동하고, 테스트를 수행하였음.
튜닝 포인트
- Process 의 CPU Affinity 를 지정 할 수 있는 Taskset 으로 Redis Process 를 특정 CPU 에 Binding
- Network Ethernet 이 사용하는 CPU 의 IRQ(인터럽트) 를 특정 CPU 에 Affinity 할 경우와 전체 CPU 에 나누어 분산 시켰을 때의 성능 차이 분석
- Ethernet 은 기본적으로 IRQ 를 CPU 한개의 노드에 Affinity 되어서 동작하려고 내부적으로 노력한다. 이는 소켓 버퍼가 성능 향상을 위해 CPU L2 캐쉬단에서 동작하기 때문에, 네트워크를 사용하는 특정 프로세스는 Ethernet IRQ 가 Bind 되어 있는 CPU 를 쓰게 되는 것을 확인 할 수 있을 것이다.
(예를 들면 보통 Ehternet 은 IRQ Balancer 를 동작하지 않는 이상 0 번 CPU 에서 보통 동작하려고 노력한다. 이때 프로세스를 띄워서 소켓 통신을 해보면 이 프로세스는 보통 CPU 0 을 사용한다 (CPU 인터럽트 비용을 줄이기위해) 그리고, 이때 한개 프로세스를 더 띄워보면, 이 프로세스도 CPU 0 을
사용하고자 노력하는 것을 확인할 수 있다. 즉 IRQ 를 Balancing 해주지 않으면 0 번 CPU 에 프로세스들이 몰리는 현상이 발생한다. ( 몰리는 현상이라기 보다는 Ethernet 을 사용하기 위한 인터럽트다 )
- Ethernet 은 기본적으로 IRQ 를 CPU 한개의 노드에 Affinity 되어서 동작하려고 내부적으로 노력한다. 이는 소켓 버퍼가 성능 향상을 위해 CPU L2 캐쉬단에서 동작하기 때문에, 네트워크를 사용하는 특정 프로세스는 Ethernet IRQ 가 Bind 되어 있는 CPU 를 쓰게 되는 것을 확인 할 수 있을 것이다.
테스트
- 시스템 튜닝 전 (NO-Tunning)
- 설명
- Default 로 테스트 한 것으로 해당 서버에는 3개의 Redis Master 가 동작하고, IRQ 는 1 번 CPU 에서 동작하고 있다.
- 이때 Redis 들이 네트워크 Interrupt 를 최소화하고자 1 번 CPU 에 몰리고 있는 현상을 볼 수 있다. 1번 CPU 가 Busy 하고 나머지는 놀고 있기 때문에 CPU 사용을 분산해서 튜닝을 진행해보자
- 성능수행 회수operation500015000250003AvgMax Latency
1회차 Set 54351.96 50729.49 49060.97 51380.81 206 milliseconds Get 49042.68 59070.93 50986.07 53033.23 10 milliseconds 2회차 Set 51705.78 52170.29 52639.34 52171.8 Get 53329.92 52203.51 52097.45 52543.63 - CPU
- 설명
- 1차 튜닝
- 설명
- IRQ 는 0-1 을 사용할 수 있도록 Binding 한다. cat /proc/interrupt 를 보면 확인 할 수 있다.
- 그리고 Taskset 으로 Redis 를 CPU 2개씩 Affinity 를 지정한다. 50001 Redis 는 2-3 CPU , 50002 Redis 는 4-5 CPU , 50003 Redis 3-5 CPU 로 Binding 하였다.
- 성능이 많이 올라갔으나 L2 캐쉬를 사용하지 않기때문에 Redis 의 Latency (응답속도) 가 조금 튀는 것을 확인 할 수 있었다. 다만 특정 한 프로세스가 점유하는 현상이 없어지므로,
각 프로세스가 비슷한 응답을 줄수 있다.
- 성능수행 회수operation500015000250003AvgMax Latency
1회차 Set 64167.55 58679.25 59765.00 61423.4 201 milliseconds Get 71295.15 78529.92 71536.90 73787.32 43 milliseconds 2회차 Set 62506.25 63921.45 61601.39 62676.36 Get 72469.02 80568.49 74142.17 75726.56 - CPU
- 설명
- 2차 튜닝
- 설명
- Ethernet 의 각 IRQ 를 모든 CPU 에 분산한다. 그리고 Redis 를 CPU 2개씩 Affinity 를 지정한다. 50001 Redis 는 0-1 CPU , 50002 Redis 는 2-3 CPU , 50003 Redis 4-5 CPU 로 Binding 하였다.
- CPU 가 안정화되는것을 확인할 수 있다. 그리고 Max Latency 로 많이 떨어짐을 확인 할 수 있었다.
- 성능수행 회수operation500015000250003AvgMax Latency
1회차 Set 62820.38 64454.59 57582.46 61619.14 139 milliseconds Get 74573.45 71675.34 78531.16 74926.65 16 milliseconds 2회차 Set 62632.31 63580.07 57126.54 61112.97 Get 70313.6 73284.77 72195.91 71931.43 - CPU
- 설명
- 시스템 튜닝 전 (NO-Tunning)
사용 명령어
- 프로세스의 CPU Affinity 확인
- $> taskset -cp $PID
- 프로세스의 CPU Affinity 변경 ( 0-1 번 CPU Binding )
- $> taskset -cp 0-1 $PID
- IRQ 변경( 0 번 CPU 에 Binding )
- $> cd /proc/irq/$number/
- $> echo 0 > smp_affinity_list
- 프로세스의 CPU Affinity 확인
결론
- Taskset 으로 Redis Process 를 CPU 에 Affinity 하고, IRQ 를 분산 시킨 결과 SET 은 Default 대비 20% 성능 개선 , GET 은 Default 대비 40 % 정도 성능 개선 효과를 볼 수 있었다.
- 1차 튜닝 방법과 2차 튜닝 모두 장단점이 있다. 1차 튜닝은 일정한 Latency 패턴 유지 , 2차 튜닝은 Redis 가 AOF 를 사용할 때 Dist Write Interrupt 를 CPU 한쪽에 몰아서 Waiting 을 줄일 수 있고, 네트웍에 대한 Interrupt 도 줄일 수 있다.
- Taskset 과 IRQ 조절은 Redis 프로세스를 내리지 않고도 가능하므로, QA 시에 조절하면서 적정한 값을 찾는 것이 가장 좋다고 볼 수 있다. ( Operation 패턴(lpush , set,get 조합) 에 따라 달라질 수 있기 때문이다.
- 튜닝은 각 시스템과 환경에 따라 달라지므로, 적절히 튜닝하여 성능 개선을 하도록 하자.
2016년 9월 23일 금요일
Redis ( CPU Affinity 와 SoftIRQ 를 활용한 Redis 성능 개선 )
라벨:
레디스,
CPU Afffinity,
Linux,
OS 튜닝,
Redis,
Redis 성능,
Redis 성능 테스트,
SoftIRQ,
taskset
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기