탕구리's 블로그

어떻게 레디스 성능 메트릭을 모니터링 할까?(How to monitor redis Performance Metrics) 본문

devOps

어떻게 레디스 성능 메트릭을 모니터링 할까?(How to monitor redis Performance Metrics)

탕구리당 2020. 2. 17. 01:12
반응형
 

How to monitor Redis performance metrics

Learn how to monitor Redis performance metrics.

www.datadoghq.com

본 게시물은 위의 아티클("How to monitor Redis performance metrics")에 대한 번역본입니다.

 

 

레디스란?

레디스는 key/value 형식의 데이터 저장소입니다.

레디스를 사용하는 분야는 아래와 같습니다.

 

1. 데이터베이스 기능

디스크 기반의 전통적인 데이터베이스의 대안이며, 레디스는 비동기적으로 데이터를 디스크에 보존할 수 있지만, 내구성보다는 속도에 집중하였습니다.  다양한 기초 데이터 타입과 광범위한 명령어를 제공합니다.

 

2. 메시지 큐 기능

레디스의 차단 명령(여기를 참조)과 낮은 레이턴시는 메시지 브로커를 위한 백엔드로 활용이 가능합니다.

 

3. 메모리 캐시

Redis4.0을 포함하여 가장 자주 사용되는 정책은 key eviction policy이며, 레디스를 캐시 서버로 선택하기에 더 나은 환경을 제공해줍니다. 또한, 전통적인 캐시와는 다르게 레디스는 디스크를 통한 데이터 보존이 가능합니다.

 

Key Redis Metrics

레디스 모니터링은 두 가지 영역에 대한 문제 해결을 가능하게 합니다. 레디스 자체에서 발생하는 이슈와 인프라 어딘가에서 발생하는 문제를 찾도록 도와줍니다. 이번 기사에서는 가장 중요한 Redis의 몇 가지 지표에 대해서 알아봅니다.

 

1. Performance metrics

2. Memory Metrics

3. Basic Activity Metrics

4. Persistence Metrics

5. Error Metrics

 

여기에서 사용된 메트릭 용어를 사용하며,  DataDog에서는 메트릭 수집과 알림을 위한 기본적인 프레임워크를 제공합니다.

 

Performance metrics

낮은 애러 비율은 시스템의 성능에 대한 가장 좋은 지표입니다. 낮은 성능을 나타내는 이유는 일반적으로 메모리 이슈입니다.

메모리 이슈에 관련된 부분은 해당 섹션을 참고해주세요.

 

 

Metric to alert on: latency

레이턴시는 클라이언트 요청과 실제적인 서버 응답 사이의 시간을 측정합니다. 레이턴시 트래킹은 레디스 성능 변화에 대해 파악할 수 있는 가장 직접 적인 방법입니다. 레디스는 싱글 스레드를 통해 작동하기 때문에 특이 사항이 발생하게 되면 심각한 병목현상을 만들어낼 수 있습니다. 하나의 요청에 대한 응답이 길어지게 되면 그 후의 모든 요청이 밀리게 됩니다.

 

일단, 레이턴시에 대한 이슈가 발생하게 되면, 레디스 운용자가 문제를 확인할 수 있는 여러 가지 방법이 있습니다. 해당 섹션을 참고하세요

 

 

Metric to watch: instantaneous_ops_per_sec

명령어 수행에 대한 결과를 트래킹 하는 것은 레디스 내부에서 발생하는 높은 레이턴시에 대한 문제 해결에 중요한 요소입니다.

레이턴시가 길어지게 되면 명령어 큐에 백로그가 쌓이거나, 명령 실행이 느려지거나 네트워크 과다사용 등 수많은 문제를 발생시킬 수 있습니다. 초당 명령어 실행 횟수를 파악하면 문제점을 찾을 수 있습니다. - 만약 문제가 지속적으로 발생한다면, 계산을 위한 명령어가 원인이 아닌, 하나 혹은 그 이상의 느린 명령어들이 레이턴시 이슈를 발생시키게 되면 초당 명령 수가 크게 떨어지거나 중단될 수 있습니다.

 

만약, 과거의 기록과 비교하여 초당 명령어 횟수가 줄어들었다면, low command volume이나 슬로우 쿼리가 시스템을 방해하고 있다는 것입니다. 슬로우 쿼리를 확인하는 방법은 여기를 확인해주세요.

 

Metric to watch : hit rate

레디스 캐시를 사용할 때 캐시 시트를 모니터링하는 것은 아주 효율적이거나 그렇지 않습니다. 낮은 캐시 히트는 사용자가 더 이상 존재하지 않는 키를 찾고 있음을 나타냅니다. 레디스는 캐시 히트 비율에 대해 제공해주지 않습니다. 우리는 다음을 통해 캐시 히트 비율을 계산할 수 있습니다.

 

keyspace_misses 메트릭은 Error Metrics section에서 논의되었습니다.

낮은 캐시 히트는 데이터의 만료나 메모리의 부족 등 다양한 원인이 있으며, 캐시 히드가 발생하지 않는 경우 데이터를 느리게 가져오거나 대체할 리소스가 필요하기 때문에 레이턴시가 길어질 수 있습니다.

 

 

Metric to watch : used_memory

메모리 사용량은 레디스 성능에 대한 중요한 요소이다, 만약 used_memory가 시스템의 가용 메모리를 초과하게 된다면, 운영체제는 메모리의 섹션을 old/unused로 swap을 진행할 것입니다. 모든 스왑 섹션은 디스크에 써지게 되고 성능에 심각한 영향을 미치게 됩니다. 디스크에 대한 I/O는 메모리에 대한 I/O 보다 최대 5배 정도 느린 속도를 갖습니다.

 

MaxMemory 설정(redis.conf)을 통해 레디스에 대한 메모리를 제한할 수 있습니다. maxmemory를 사용하기 위해서는 eviction 정책에 대한 이해가 필요하고 메모리를 확보하는 방법에 대해 결정해야 합니다. 추가적으로 maxmemory-policy에 대한 이해를 위해선 evicted_keys_section을 참조하세요.

 

 

metric to alert on: mem_gragmentation_ratio

mem_fragmentation_ratio 메트릭은 운영체제에서 사용된 메모리와 Redis가 할당한 메모리의 비율을 제공합니다.

 

운영체제는 각각의 프로세스에게 메모리를 할당하며, 운영체제의 가상 메모리 관리자는 메모리 할당자의 의해서 조정된 실제 메모리를 매핑합니다. 만약 레디스 인스턴스의 메모리 할당이 1기가인 경우, 메모리 할당자는 데이터를 저장하기 위한 연속적인 메모리 세그먼트를 찾습니다. 만약 세그먼트가 존재하지 않는다면 메모리 할당자는 프로세스의 데이터를 세그먼트로 나누어 메모리 오버해드가 증가하게 됩니다.

 

파편화 비율을 트래킹 하는 것은 레디스 인스턴스의 성능을 이해하는데 중요하다. 파편화의 비율이 1.5를 초과하면, Redis 인스턴스는 요청한 실제 메모리 양의 150%를 소비합니다. 파편화 비율이 1 미만인 경우, 레디스는 시스템에서 제공 가능한 메모리보다 실제로 더 많은 메모리를 필요하게 되고 스왑을 발생시킵니다. 디스크 스왑이 발생하게 되면 레이턴시가 증가하게 됩니다. 파편화 비율은 1 혹은 1보다 약간 큰 경우 운영체제는 연속적인 세그먼트를 물리 메모리에 할당하게 된다. 

 

만약 서버의 메모리 파편화 비율이 1.5 이상을 상회하고 있다면, 레디스 인스턴스를 재시작하는 것이 운영체제가 이전에 파편화 때문에 사용하지 못하던 메모리를 복구할 수 있도록 한다. 그런 경우에 alert as a notification이 아주 충분하다.

 

그러나 Redis 파편화 비율이 1 이하인 경우, 사용 가능한 메모리를 빠르게 늘리거나, 메모리 사용량을 줄이수 있도록 해야 하며 alert as a page 사용할 수 있다.

 

Redis 4를 사용할 때, 레디스가 jemalloc의 복사본을 포함하고 있다면 새로운 활성 조각 모음을 이용할 수 있다. 이 툴은 조각화가 특정 파편이 기준치에 도달할 때, 연속적인 메모리 영역에 이를 복사하고 이전 복사본은 해제하여 서버가 구동되는 동안 파편화를 줄일 수 있습니다.

 

Metric to alert on: evicted_keys(Cache only)

만약 캐시 용도로 레디스를 사용한다면, maxmemory에 도달한 경우 자동적으로 key가 지워지도록 설정할 수 있습니다. 레디스를 데이터베이스 혹은 큐로 사용한다면, eviction으로 변경하는 것을 선호할 수 있으며, 그런 경우에 메트릭을 지나칠 수 있습니다.

 

key eviction을 트래킹 하는 것은 레디스 프로세스의 각각의 순차적인 작동에 있어서 매우 중요합니다. 반면에 많은 수의 키가 evictiong 되는 경우 낮은 히트 비율을 보일 수 있으며, 레이턴시 또한 길어질 수 있습니다. 만약 TTL을 사용하는 경우 evict keys를 발생하지 않을 것입니다. 만약 해당 지표가 지속적으로 0보다 높다면 인스턴스의 레이턴시는 증가할 것입니다. TTL을 사용하지 않는 다른 경우에 결국 메모리는 부족하게 되고 정책에 의해 키를 제고하게 됩니다.

 

key의 expiration policy는 다음 명령을 통해 확인 가능합니다.

 maxmemory policy에 대한 정책은 다음과 같습니다

1. noeviction : 제한 메모리에 도달하여도 사용자는 키를 추가 합니다.

2. volatile-lru : expiration set에 존재하는 키들 중 가장 최근에 사용한 키를 제거합니다.

3. volatile-ttl : expiration set에 존재하는 키들 중 만료시간에 가장 가까운 키들을 제거합니다.

4. voloatile-random : expiration set에 존재하는 키들 중 임의로 키를 제거합니다.

5. allkeys-lru : 모든 키들 중 가장 최근에 사용한 키를 제거합니다.

6. allkeys-random : 모든 키들 중 임의로 키를 제거합니다.

7. volatile-lfu : Redis 4에 추가되었으며, expiration set에서 가장 사용 빈도가 낮은 키를 제거합니다.

8. allkeys-lfu : Redis 4에 추가되었으면, 모든 키들 중에서 가장 사용 빈도가 낮은 키를 제거합니다.

 

NOTE:  성능적인 이유로 레디스 4의 LRU, TTL, LFU 정책을 사용할 때 전체 키를 통해서 샘플링하지 않습니다. 레디스는 첫째로 키스 페이스의 랜덤 서브셋을 통해서 샘플링하고, eviction 전략의 샘플 키로 사용합니다. 일반적으로 Redis의 최신 (> = 3) 버전은 실제 LRU와 거의 비슷한 LRU 샘플링 전략을 사용합니다. 예를 들어 LFU 정책은 항목이 순위에 따라 내려가지 않고 액세스 할 수 있는 시간을 설정하여 조정할 수 있습니다. 자세한 내용은 Redis의 설명서를 참조하십시오.

 

Metric to watch: blocked_clients

레디스는 작동 리스트에 있는 명령어가 Block 되는 수를 제공합니다.  BLPOP, BRPOP 그리고 BRPOPLPUSH은 LPOP, RPOP, RPOPLPUSH 명령의 변형을 제한합니다. 소스 리스트가 비어있지 않다면, 명령어는 예상대로 작동합니다, 그러나 소스 리스트가 비어있으면 차단 명령은 소스가 채워지거나 시간 종료에 도달할 때까지 대기합니다.

 

블록 된 사용자 수가 증가하면 문제가 발생할 수 있습니다. 레이턴시나 다른 이슈들이 소스 리스트가 채워지는 것을 방해할 수 있습니다. 비록 블락된 클라이언트는 자체적으로 알람을 발생시키지는 않지만 해당 메트릭에 0이 아닌 값이 지속적으로 표시되면 조사를 해봐야 합니다.

 

 

Metric to alert on : connected_clients

레디스로의 접근은 보통 어프리케이션에 의해서 발생되기 때문에, 클라이언트 연결의 상한선과 하한선이 존재할 것입니다. 정상 범위를 벗어나게 되면 문제들이 발생하기 시작합니다. 만약 연결된 클라이언트가 너무 낮은 경우 업스트림 연결이 유실될 수 있고, 클라이언트 연결이 너무 과한 경우 서버가 다를 수 있는 요청 수를 압도할 수 있습니다.

 

그럼에도 불구하고, 클라이언트 커넥션수는 운영체제나, 레디스 설정 혹은 네트워크 제한에 의해서 제한되어 있습니다. 클라이언트 커넥션을 모니터링은 새로운 클라이언트나 관리자 세션을 위해 충분한 리소스 자원이 남아있는지 확인할 수 있습니다.

 

Metric to alert on : connected_slaves

데이터베이스 무거워지는 경우, 레디스에서는  master-slave 구조를 이용할 수 있다. 슬레이브에 연결된 커넥션 수를 모니터링하는 것이 열쇠이다. 연결된 슬레이브의 수가 예상치 않게 변경되었다면, 스레이브 인스턴스나 호스트에 문제가 생겼을 수 있습니다.

 

 

NOTE: 위에 다이어그램에서, 레디스 마스터는 두 개의 슬레이브 커넥션을 가지고 있다. 첫 번째 슬레이브도 각각 2개의 슬레이브를 가지고 있다. 두 번째 슬레이브는 마스터에 직접 연결되지 않습니다.

 

Metric to alert on : master_last_io_seconds_ago

레디스 레플리케이션을 이용할 때, 슬레이브 인스턴스는 주기적으로 마스터의 상태를 체크한다. 마스터와 긴 시간 동안 연결이 되지 않으면 마스터 인스턴스나 슬레이브 인스턴스 혹은 그 사이에 연결돼있는 인프라에 문제가 발생했음을 확인할 수 있습니다. 데이터 동기화가 제대로 이루어지기 위해서는 마스터와 슬레이브 간 연결이 유실되는 것을 최소한으로 해야 합니다. 슬레이브와 마스터 간 연결이 중단되고 다시 연결된 경우 PSYNC를 통해 데이터 동기화가 진행됩니다. 해당 명령을 실행할 수 없는 경우 전체 SYNC를 통해 마스터가 데이터베이스 내용을 디스크에 백그라운드로 저장하도록 진행합니다. 백그라운드 저장을 시작하고 수신된 새로운 명령어들은 버퍼링을 통해 명령에 대한 데이터를 수정합니다. 백그라운드 저장이 종료되면 버퍼링 된 명령과 함께 클라이언트에게로 데이터가 전송됩니다. 그 후 각각의 슬레이브는 SYNC 작업을 실행합니다. 슬레이브에서 SYNC가 발생하게 되면 마스터에 레이턴시를 유발할 수 있습니다.

 

Metric to watch: keyspace

일반적으로 데이터베이스의 키 숫자를 파악하는 것은 좋은 방법입니다. in-memory 데이터 저장소에서 키 스페이스가 커질수록 성능의 최적을 위해 더 많은 메모리를 요구하게 됩니다. maxmemory에 도달할 때까지 레디스에서 계속 키를 추가하게 되면 키가 추가되는 만큼 eviction에 의해 키가 제거되며 평평한 그래프의 모습을 나타 냅니다.

 

레디스를 캐시로 사용하고 키 저장 공간이 꽉 차 있는 경우, 클라이언트가 오래된 데이터나 evicted 된 데이터를 찾는 것과 같이 낮은 캐시 적중률을 나타낼 것입니다. keyspace_misses의 수를 트래킹 하는 것은 원인을 찾기에 좋습니다.

 

반대로, 레디스를 데이터베이스나 큐로 사용하는 경우, 휘발된 키는 옵션이 아닐 수 있습니다. 키의 개수가 많아진다면 메모리를 추가하거나 호스트 간의 데이터 셋을 분할하는 것이 좋습니다. 가능하다면 메모리를 추가하는 것이 간단하고 효율적일 수 있습니다. 하나의 인스턴스에서 제공하는 것보다 많은 메모리를 필요로 하게 된다면, 파티셔닝이나 샤딩을 통해 여러 컴퓨터 리소스를 결합할 수 있습니다. 파티셔닝을 진행하는 경우 레디스는 eviction이나 swapping 없이 더 많은 키를 저장할 수 있습니다. 그러나 파티셔닝을 적용하는 것은 몇 가지 메모리 스틱을 적용하는 것보다 어렵습니다. 레디스 파티셔닝에 대한 자료를 보고 싶으면 여기를 참조해 주세요.

 

레디스의 Replication을 이용하는 경우 필수적으로 persistence를 사용해야 합니다. 슬레이브가 맹목적으로 마스터를 복사하기 때문에 만약 마스터가 persistence 없이 재시작된다면 비어있는 데이터를 슬레이브가 복제하게 됩니다. 만약 레디스를 캐시 용도로 사용하고 있는 경우에는 Persistence를 사용할 필요가 없습니다.

 

Metrics to watch: rdb_last_save_time and rdb_changes_since_last_save

일반적으로 데이터 셋의 변화를 주시하는 것은 좋은 생각입니다. 과도하게 오랜 시간 동안 디스크에 쓰기 작업이 진행되면 서버 장애 시 데이터가 유실될 수 있습니다. 마지막 세이브 시간과 실패 시간 사이의 데이터 변화는 유실될 수 있습니다.

 

 rdb_change_since_last_save를 모니터링하는 것은 데이터 변화에 대한 예지를 제공합니다. 데이터가 크게 변경되지 않는다면  쓰기 작업은 문제가 되지 않습니다. 저장된 시간과 변화된 시간을 모두 추적하게 되면 특정 시점에 장애가 발생한 경우 얼마나 많은 데이터가 유실됐는지 추적 가능합니다.

 

Error metrics

레디스 에러 메트릭은 비정상적인 상태를 알려줄 수 있습니다. 다음은 일반적인 에러 메트릭들입니다.

Metric to alert on: rejected_connections

레디스는 마은 활성 커넥션에 대해 다룰 수 있습니다. 커넥션의 기본값은 10,000입니다. redis.conf의 maxclient의 변경을 통해 다른 값으로 커넥션의 최댓값을 수정할 수 있습니다. 새로운 커넥션이 거절되면, 레디스 인스턴스는 현재 최대 커넥션을 맺고 있는 상태입니다.

 

시스템이 maxclient에 설정되어 있는 커넥션만큼 수를 지원하지 않을 수 있는데, 레디스는 커널을 검사하여 이용 가능한 file descriptor 수를 결정합니다. 만약 이용 가능한 file descripter의 수가 maxclient +32 보다 적다면, maxclient의 설정은 무시되고 file descriptor가 사용됩니다.

 

레디스 클라이언트 커넥션을 다루는 자세한 내용이 궁금하시다면 redis.io를 참조해주세요.

 

metric to alert on: keyspace_misses

레디스가 키를 찾을 때의 결괏값이 있거나 없을 수 있습니다. 키가 존재하지 않는다면 keyspace_misses의 카운트가 증가합니다. keyspace_misses의 카운트를 0이 아니라면, 데이터베이스에 해당 키가 존재하지 않는다는 것이며, 레디스를 캐시 서버로 사용하지 않는 경우엔 keyspace_misses는 0에 가깝습니다. 

 

metric to alert on: master_link_down_since_seconds

해당 지표는 마스터와 슬레이브의 연결이 끊어진 경우에 사용 가능합니다. 해당 지표는 0을 초과하면 안 되고 마스터와 슬레이브는 지속적인 연결을 유지해야 합니다. 마스터와 슬레이브가 재연결을 시도하게 되면 데이터 업데이트를 위한 리소스를 할당해야 하므로 명령 수행에 대한 대기시간이 늘어날 수 있습니다.

 

 

Conclusion

이번 포스팅에서는 레디스 서버를 모니터링하기 위한 유용한 지표들에 대해서 알아보았습니다. 만약 당신이 레디스를 처음 시작했다면, 아래 제공된 모니터링 메트릭들이 데이터베이스 인프라의 성능과 상태에 대해 좋은 지표를 제공할 것입니다.

 

- Number of commands processed per second

- Latencty

- Memory fragmentation ratio

- Evictions

- Rejected clients

 

반응형

'devOps' 카테고리의 다른 글

Docker로 Redis 사용하기(feat. 삽질)  (0) 2020.04.07
Docker로 Tomcat 사용하기  (0) 2020.03.20
[Kubernetes] #2 쿠버네티스 구성  (0) 2020.01.12
[Kubernetes] #1 쿠버네티스란 무엇일까?  (0) 2020.01.12
서버 가상화? Docker?  (0) 2018.06.03
Comments