Redis 모니터링: 효율적인 성능 관리와 문제 해결을 위한 가이드
Redis의 모니터링에 대해 깊이 있게 알아보겠습니다. Redis는 고성능 인메모리 데이터 저장소로 널리 사용되고 있지만, 효율적인 운영을 위해서는 적절한 모니터링이 필수적입니다. 이 글에서는 Redis 모니터링의 다양한 방법과 도구, 그리고 주요 고려사항에 대해 상세히 다루겠습니다.
1. Redis CLI를 이용한 기본 모니터링
Redis는 기본적으로 몇 가지 유용한 모니터링 명령어를 제공합니다. 이들은 Redis CLI를 통해 쉽게 사용할 수 있습니다.
1.1 redis-cli monitor
~ docker exec -it d4b14a834ba7 redis-cli monitor
OK
1682871818.259467 [0 127.0.0.1:54426] "HGETALL" "user:300"
1682871820.037704 [0 127.0.0.1:54426] "KEYS" "*"
1682871828.763765 [0 127.0.0.1:54426] "GET" "mylist"
1682871831.609374 [0 127.0.0.1:54426] "TYPE" "mylist"
1682871853.119967 [0 127.0.0.1:54426] "LRANGE" "mylist" "0" "-1"
분석
1. 명령어: docker exec -it d4b14a834ba7 redis-cli monitor
- Docker 컨테이너(ID: d4b14a834ba7)에서 Redis CLI를 실행하고 모니터 모드를 활성화합니다.
2. Redis 명령어 로그:
- 각 로그 항목은 3개의 공백으로 구분된 세 부분으로 구성됩니다:
- UNIX 타임스탬프 (초 단위, 마이크로초 정밀도)
- [데이터베이스 번호 클라이언트IP:포트] 형식의 메타 정보
- 실행된 Redis 명령어와 인자
모니터링 관점에서, 이 로그는 시스템의 실시간 활동을 상세히 보여주어 디버깅이나 성능 분석에 유용할 수 있습니다. 그러나 프로덕션 환경에서는 성능 오버헤드로 인해 monitor 명령의 지속적인 사용은 권장되지 않습니다.
1.2 redis-cli --stat
~ docker exec -it d4b14a834ba7 redis-cli --stat
------- data ------ --------------------- load -------------------- - child -
keys mem clients blocked requests connections
15 1.93M 6 0 4134030 (+0) 2147
15 1.93M 6 0 4134031 (+1) 2147
15 1.93M 6 0 4134032 (+1) 2147
15 1.93M 6 0 4134033 (+1) 2147
15 1.93M 6 0 4134034 (+1) 2147
15 1.93M 6 0 4134035 (+1) 2147
15 1.93M 6 0 4134036 (+1) 2147
15 1.93M 6 0 4134037 (+1) 2147
15 1.93M 6 0 4134038 (+1) 2147
15 1.93M 6 0 4134039 (+1) 2147
15 1.93M 6 0 4134040 (+1) 2147
15 1.93M 6 0 4134041 (+1) 2147
15 1.93M 6 0 4134042 (+1) 2147
분석
1. 각 로그 항목은 6개의 열로 구성되며, 각 열은 다음 정보를 나타냅니다
- keys: Redis 데이터베이스에 저장된 키의 수
- mem: 사용 중인 메모리 양
- clients: 현재 연결된 클라이언트 수
- blocked: 차단된 클라이언트 수
- requests: 처리된 요청의 총 수 (괄호 안은 이전 로그 대비 증가량)
- connections: 서버 시작 이후 총 연결 시도 횟수
2. 모든 로그 항목에서 다음 값들이 일정하게 유지됩니다
- 키 수: 15
- 메모리 사용량: 1.93M
- 현재 연결된 클라이언트 수: 6
- 차단된 클라이언트 수: 0
- 총 연결 시도 횟수: 2147
- requests 열만 매 초마다 1씩 증가하고 있습니다.
3. 로그 출력 특성
- 명령어 실행 직후 헤더 정보와 함께 첫 번째 데이터 행이 즉시 표시됩니다.
- 이후 매 초마다 새로운 데이터 행이 추가됩니다.
- 이미지에 13개의 데이터 행이 보이는 것은 명령어 실행 후 약 12초가 경과했음을 의미합니다.
- 계속 실행 상태라면 새로운 행이 계속 추가되며, 화면 크기에 따라 오래된 행들은 위로 스크롤되어 보이지 않게 됩니다.
이 로그는 Redis 서버의 실시간 통계 정보를 보여줍니다. 서버가 안정적으로 운영되고 있으며, 지속적으로 요청을 처리하고 있지만 새로운 데이터는 추가되지 않고 있음을 나타냅니다. 현재 6개의 클라이언트가 연결되어 있으며, 서버 시작 이후 총 2147번의 연결 시도가 있었습니다.
모니터링 관점에서, 이 통계 정보는 Redis 서버의 전반적인 상태와 성능을 빠르게 파악하는 데 유용합니다. 메모리 사용량, 현재 클라이언트 연결 수, 요청 처리량 등을 실시간으로 확인할 수 있어 서버의 건강 상태를 모니터링하는 데 도움이 됩니다. 또한, 시간에 따른 변화를 관찰할 수 있어 서버의 동작 패턴을 이해하는 데도 유용합니다.
1.3 redis-cli --bigkeys
Redis의 --bigkeys
명령어를 사용한 결과를 보여줍니다. 이 명령어는 Redis 데이터베이스의 키 공간을 스캔하여 가장 큰 키와 각 데이터 타입별 평균 크기를 찾습니다.
~ docker exec -it d4b14a834ba7 redis-cli --bigkeys
# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type. You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).
[00.00%] Biggest set found so far '"user"' with 3 members
[00.00%] Biggest list found so far '"mylist"' with 200000 items
[00.00%] Biggest string found so far '"counter:__rand_int__"' with 6 bytes
[00.00%] Biggest hash found so far '"user:100"' with 3 fields
-------- summary -------
Sampled 15 keys in the keyspace!
Total key length in bytes is 217 (avg len 14.47)
Biggest list found '"mylist"' has 200000 items
Biggest hash found '"user:100"' has 3 fields
Biggest string found '"counter:__rand_int__"' has 6 bytes
Biggest set found '"user"' has 3 members
1 lists with 200000 items (06.67% of keys, avg size 200000.00)
4 hashes with 10 fields (26.67% of keys, avg size 2.50)
3 strings with 12 bytes (20.00% of keys, avg size 4.00)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
7 sets with 9 members (46.67% of keys, avg size 1.29)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
주요 분석 내용
1. 총 15개의 키를 샘플링했으며, 전체 키 길이는 217바이트(평균 길이 14.47바이트)입니다.
2. 가장 큰 키들:
- 가장 큰 리스트: "mylist"로 200,000개 항목
- 가장 큰 해시: "user:100"으로 3개 필드
- 가장 큰 문자열: "counter:rand_int"로 6바이트
- 가장 큰 셋: "user"로 3개 멤버
3. 데이터 타입별 통계:
- 리스트: 1개, 200,000개 항목 (전체 키의 6.67%, 평균 크기 200,000)
- 해시: 4개, 총 10개 필드 (전체 키의 26.67%, 평균 크기 2.50)
- 문자열: 3개, 총 12바이트 (전체 키의 20.00%, 평균 크기 4.00)
- 스트림: 0개
- 셋: 7개, 총 9개 멤버 (전체 키의 46.67%, 평균 크기 1.29)
- 정렬된 셋(zset): 0개
이 결과는 Redis 데이터베이스의 구조와 데이터 분포를 이해하는 데 도움이 됩니다. 특히 "mylist"라는 리스트가 200,000개의 항목으로 가장 큰 키임을 알 수 있으며, 셋이 가장 많은 비율(46.67%)을 차지하고 있습니다. 이러한 정보는 메모리 사용 최적화와 성능 튜닝에 유용할 수 있습니다.
이 명령어는 Redis 데이터베이스에서 가장 큰 키들을 찾아 보여줍니다. 메모리 사용량이 많은 키를 식별하고 최적화하는 데 유용합니다.
1.4 redis-cli --memkeys
~ docker exec -it 9e25cfa12f59 redis-cli --memkeys
# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type. You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).
[00.00%] Biggest string found so far '"KEY2"' with 48 bytes
[00.00%] Biggest string found so far '"key:__rand_int__"' with 69 bytes
[00.00%] Biggest hash found so far '"myhash"' with 86 bytes
[00.00%] Biggest list found so far '"mylist"' with 860473 bytes
-------- summary -------
Sampled 7 keys in the keyspace!
Total key length in bytes is 60 (avg len 8.57)
Biggest list found '"mylist"' has 860473 bytes
Biggest hash found '"myhash"' has 86 bytes
Biggest string found '"key:__rand_int__"' has 69 bytes
1 lists with 860473 bytes (14.29% of keys, avg size 860473.00)
1 hashes with 86 bytes (14.29% of keys, avg size 86.00)
5 strings with 277 bytes (71.43% of keys, avg size 55.40)
0 streams with 0 bytes (00.00% of keys, avg size 0.00)
0 sets with 0 bytes (00.00% of keys, avg size 0.00)
0 zsets with 0 bytes (00.00% of keys, avg size 0.00)
Redis의 --memkeys
명령어를 사용한 결과를 보여줍니다. 이 명령어는 Redis 데이터베이스의 키 공간을 스캔하여 메모리 사용량이 가장 큰 키와 각 데이터 타입별 평균 크기를 찾습니다.
주요 분석 내용
1. 총 7개의 키를 샘플링했으며, 전체 키 길이는 60바이트(평균 길이 8.57바이트)입니다.
2. 가장 큰 키들:
- 가장 큰 리스트: "mylist"로 860473 바이트
- 가장 큰 해시: "myhash"로 86 바이트
- 가장 큰 문자열: "key:rand_int"로 69 바이트
3. 데이터 타입별 통계:
- 리스트: 1개, 860473 바이트 (전체 키의 14.29%, 평균 크기 860473.00 바이트)
- 해시: 1개, 86 바이트 (전체 키의 14.29%, 평균 크기 86.00 바이트)
- 문자열: 5개, 총 277 바이트 (전체 키의 71.43%, 평균 크기 55.40 바이트)
- 스트림, 셋, 정렬된 셋(zset): 각각 0개
이 결과는 Redis 데이터베이스의 메모리 사용 패턴을 보여줍니다. "mylist"가 가장 많은 메모리(860473 바이트)를 사용하고 있으며, 문자열 타입의 키가 가장 많은 비율(71.43%)을 차지하고 있습니다. 이 정보는 메모리 최적화와 성능 개선에 유용하게 사용될 수 있습니다.
1.5 redis-cli --latency
Redis 서버의 지연 시간(latency)을 측정한 결과를 보여줍니다. Docker 컨테이너 내에서 Redis CLI의 --latency 옵션을 사용
~ docker exec -it 9e25cfa12f59 redis-cli --latency
min: 0, max: 7, avg: 0.38 (472 samples)
분석
- 최소 지연 시간(min): 0 밀리초
- 최대 지연 시간(max): 7 밀리초
- 평균 지연 시간(avg): 0.38 밀리초
- 샘플 수: 472개
이 결과는 Redis 서버의 응답 시간이 매우 빠르고 안정적임을 보여줍니다. 평균 지연 시간이 1밀리초 미만이며, 최대 지연 시간도 7밀리초로 상대적으로 낮습니다. 이는 Redis 서버가 효율적으로 작동하고 있으며, 클라이언트 요청에 신속하게 응답하고 있다는 것을 의미합니다.
2. Prometheus와 Grafana를 이용한 고급 모니터링
기본 CLI 도구 외에도, Prometheus와 Grafana를 이용하면 더욱 강력하고 시각적인 모니터링 환경을 구축할 수 있습니다.
1. 메트릭 수집:
- Jobs/exporters: 다양한 서비스와 애플리케이션에서 메트릭을 수집하는 주요 소스입니다.
- Short-lived jobs: 짧은 시간 동안만 실행되는 작업의 메트릭을 Pushgateway를 통해 Prometheus에 전달합니다.
- Pushgateway: 일시적인 작업의 메트릭을 중간에서 받아 Prometheus로 전달하는 중개자 역할을 합니다.
2. Service Discovery:
- Kubernetes: 쿠버네티스 클러스터 내의 서비스와 포드를 자동으로 발견합니다.
- file_sd: 파일 기반 서비스 디스커버리로, 정적인 타겟 설정에 사용됩니다.
- 이를 통해 Prometheus가 동적으로 변하는 환경에서도 모니터링 대상을 자동으로 찾아 수집할 수 있습니다.
3. Prometheus Server:
- Retrieval: 메트릭을 주기적으로 가져오는 컴포넌트입니다.
- TSDB (Time Series Database): 수집된 메트릭을 시계열 데이터로 저장합니다.
- HTTP server: 쿼리 및 API 요청을 처리합니다.
- 서비스 디스커버리를 통해 발견된 타겟으로부터 메트릭을 pull 방식으로 수집합니다.
4. Alertmanager:
- Prometheus Server에서 정의된 규칙에 따라 알림을 받아 처리합니다.
- 알림을 그룹화, 중복 제거, 억제 등의 처리를 한 후 적절한 채널(PagerDuty, Email, 기타)로 전달합니다.
5. 데이터 시각화 및 분석:
- Prometheus web UI: 기본적인 쿼리 및 그래프 기능을 제공합니다.
- Grafana: 더 강력하고 유연한 대시보드 기능을 제공하여 데이터를 시각화합니다.
- API clients: 외부 시스템이나 커스텀 애플리케이션에서 Prometheus 데이터에 접근할 수 있게 합니다.
6. 스토리지:
- Node: Prometheus Server가 실행되는 물리적 또는 가상 머신입니다.
- HDD/SSD: 시계열 데이터를 영구적으로 저장하는 디스크 스토리지입니다.
7. PromQL (Prometheus Query Language):
- Prometheus의 자체 쿼리 언어로, 복잡한 데이터 분석과 집계를 가능하게 합니다.
- Grafana, API clients, Prometheus web UI 등에서 사용되어 데이터를 조회하고 처리합니다.
이 아키텍처는 확장성, 유연성, 강력한 모니터링 기능을 제공합니다. 특히 Kubernetes와의 통합이 뛰어나 클라우드 네이티브 환경에서 효과적으로 작동하며, 다양한 알림 옵션과 시각화 도구를 통해 시스템 관리자와 개발자에게 중요한 인사이트를 제공합니다.
2.1 Prometheus 소개
Prometheus는 시계열 데이터베이스로, 메트릭을 수집하고 저장하는 데 특화되어 있습니다. CNCF(Cloud Native Computing Foundation)의 졸업 프로젝트로, 클라우드 네이티브 환경에서 널리 사용됩니다.
2.2 Prometheus Redis Exporter
Redis 메트릭을 Prometheus로 보내기 위해서는 Redis Exporter를 사용합니다. 이 익스포터는 Redis의 다양한 메트릭을 수집하여 Prometheus가 이해할 수 있는 형식으로 변환합니다.
2.3 Grafana를 이용한 시각화
Prometheus에 저장된 Redis 메트릭 데이터는 Grafana를 통해 시각화할 수 있습니다. Grafana는 다양한 차트와 대시보드를 제공하여 Redis의 성능과 상태를 한눈에 파악할 수 있게 해줍니다.
3. Redis 메모리 관리와 Eviction 정책
Redis의 효율적인 운영을 위해서는 메모리 관리가 중요합니다. Redis는 메모리 한계에 도달했을 때 어떻게 동작할지를 결정하는 Eviction 정책을 제공합니다.
Eviction의 뜻
퇴거 또는 쫓아냄을 의미합니다. 일반적으로는 법적으로 누군가를 집이나 건물에서 강제로 내보내는 상황을 설명할 때 사용됩니다. 예를 들어, 집세를 제때 내지 않으면 건물주가 세입자를 강제로 내보내는 것을 "eviction"이라고 부를 수 있습니다.
IT 분야에서는 메모리 관리와 관련된 상황에서 "eviction"이라는 용어를 사용할 수 있습니다. 예를 들어, 캐시 메모리가 꽉 찼을 때 오래된 데이터를 제거하는 것을 캐시 eviction이라고 합니다.
3.1 maxmemory 설정
maxmemory
설정은 Redis가 사용할 수 있는 최대 메모리 양을 지정합니다. 기본값은 0으로, 이는 제한이 없음을 의미합니다. 예를 들어, 4GB로 제한하려면:
maxmemory 4G
3.2 maxmemory-policy 옵션
maxmemory-policy
옵션을 선택할 때는 Redis의 사용 목적과 애플리케이션 요구 사항에 따라 가장 적절한 정책을 선택해야 합니다. 각 정책을 어떤 상황에서 사용해야 하는지 실제 운영 환경에서의 케이스를 예시로 설명해 드릴게요.
1. noeviction (기본값):
- 적용할 때: 데이터의 영속성이 중요한 경우. 데이터 손실을 절대 허용할 수 없는 시스템에서는 메모리 한계에 도달하면 새로운 쓰기 명령을 거부하는 것이 적절합니다.
- 예시: 은행 거래 기록, 중요 로그 파일 저장, 주문 처리 시스템 등에서 사용합니다. 데이터 손실이 발생하면 안 되는 시스템입니다.
2. allkeys-lru (Least Recently Used):
- 적용할 때: Redis가 캐시로 사용될 때, 주로 가장 최근에 사용된 데이터가 자주 요청되는 경우에 적합합니다.
- 예시: 웹 세션 데이터, 자주 사용되는 사용자 프로필 정보 등을 저장할 때 사용됩니다. 이전에 한 번 요청된 데이터는 다시 요청될 가능성이 높지만, 오래된 데이터는 제거됩니다.
3. allkeys-lfu (Least Frequently Used):
- 적용할 때: 자주 사용되지 않은 데이터를 제거하고 싶을 때, 즉 가장 적게 사용된 데이터부터 삭제하는 것이 유리한 경우.
- 예시: 자주 조회되지 않는 보고서나 문서 캐시. 데이터가 오랫동안 자주 조회되는 경우가 많은 시스템에서 효과적입니다.
4. volatile-lru:
- 적용할 때: 만료 시간이 설정된 데이터만 유지 관리해야 하고, 해당 데이터 중에서 오래된 것을 제거하고 싶을 때 적합합니다.
- 예시: TTL(Time To Live)이 설정된 사용자 세션, 임시 데이터를 캐시하는 서비스에서 사용됩니다.
5. volatile-lfu:
- 적용할 때: 만료 시간이 설정된 데이터 중에서도 자주 사용되지 않는 데이터를 우선적으로 제거하고 싶을 때 사용됩니다.
- 예시: 자주 사용되지 않는 임시 파일이나 세션 데이터가 많은 시스템. 예를 들어, 로그인 세션이 설정된 사용자가 많지만, 일부 사용자만 자주 활동하는 경우.
6. allkeys-random:
- 적용할 때: 데이터를 랜덤하게 제거하는 방식으로 메모리를 확보하고자 할 때 사용됩니다. 하지만 이 방법은 효율적이지 않을 수 있습니다.
- 예시: 캐시의 데이터가 매우 고르게 분포되어 있고, 특정 키를 우선적으로 제거할 필요가 없는 시스템에서 사용될 수 있습니다. 이 경우는 거의 드뭅니다.
7. volatile-random:
- 적용할 때: 만료 시간이 있는 데이터 중 무작위로 삭제할 때.
volatile-lru
나volatile-lfu
보다 간단한 정책이지만, 일반적으로 랜덤 삭제는 비효율적일 수 있습니다. - 예시: 이 정책도 실전에서는 잘 사용되지 않지만, 메모리 관리가 덜 중요한 환경에서 사용할 수 있습니다.
8. volatile-ttl:
- 적용할 때: 만료 시간이 가까운 데이터를 우선적으로 제거하고 싶을 때 적합합니다.
- 예시: 세션 데이터처럼 일정 시간 내에 유효성이 만료되는 데이터를 관리하는 시스템에서 유용합니다. TTL 값이 가까운 데이터가 자동으로 제거되면서 메모리가 확보됩니다.
실제 운영 환경에서의 적용 예시:
- 캐시 시스템:
allkeys-lru
또는allkeys-lfu
가 일반적입니다. 캐시 데이터를 최신 상태로 유지하고, 오래된 데이터를 자연스럽게 제거하는 방식입니다. - 임시 세션 데이터:
volatile-lru
나volatile-ttl
이 적합합니다. 만료 시간이 설정된 임시 세션 데이터를 사용 중인 서비스에서 자주 사용됩니다. - 빈번히 사용하는 데이터를 오래 유지해야 하는 경우:
allkeys-lfu
를 사용하여 자주 사용되는 데이터를 가능한 오랫동안 유지하고, 사용 빈도가 낮은 데이터를 제거합니다.
정리하자면, 애플리케이션의 요구에 따라 Redis의 사용 목적과 데이터 패턴을 잘 분석하고, 이를 바탕으로 가장 적절한 eviction 정책을 선택하는 것이 중요합니다.
4. 실전 모니터링 팁
- 정기적인 모니터링:
redis-cli --stat
를 사용하여 주기적으로 기본 상태를 확인 - 대용량 키 식별:
redis-cli --bigkeys
로 큰 키들을 주기적으로 확인하고 필요하다면 최적화 - 지연 시간 모니터링:
redis-cli --latency
로 응답 시간을 체크하여 성능 이슈를 조기에 발견 - Prometheus + Grafana 설정: 장기적인 트렌드 분석과 알림 설정을 위해 Prometheus와 Grafana를 구축
- 메모리 사용량 관리:
maxmemory
와maxmemory-policy
를 적절히 설정하여 메모리 사용을 최적화
요약
Redis 모니터링은 시스템의 안정성과 성능을 유지하는 데 필수적입니다. 기본 CLI 도구부터 Prometheus와 Grafana 같은 고급 도구까지, 다양한 방법을 통해 Redis의 상태를 꾸준히 관찰하고 관리해야 합니다. 또한, 메모리 관리 정책을 잘 이해하고 적용하는 것도 중요합니다.
이러한 모니터링 방법과 도구들을 적절히 활용한다면, Redis 기반 시스템의 성능을 최적화하고 문제를 사전에 방지할 수 있을 것입니다. 지속적인 모니터링과 튜닝을 통해 Redis의 강력한 성능을 최대한 활용하세요!
Docker Compose를 이용한 Prometheus, Grafana, Redis 및 Redis Exporter 설정과 모니터링
Prometheus, Grafana, Redis, 그리고 Redis Exporter를 사용해 Docker Compose로 모니터링 시스템을 구성하는 방법을 다룹니다.
이 방법은 Redis 데이터베이스를 실시간으로 모니터링하고 성능을 분석하는 데 유용합니다. 구성 과정에서 Prometheus가 메트릭 데이터를 수집하고, Grafana가 이를 시각화하는 방식을 살펴보겠습니다.
컴포즈 설치
도커 컴포즈를 이용하여 실습 환경을 구성해보겠습니다.
Mac M1 OS에서 Docker Compose를 설치하기 위해서는 Docker가 이미 설치된 상태라면, Docker Compose는 Docker Desktop에 기본적으로 포함되어 있습니다. 그렇기 때문에 별도의 설치가 필요하지 않을 가능성이 큽니다.
하지만 혹시라도 Docker Compose를 CLI 방식으로 따로 설치하고자 한다면, Homebrew를 통해 설치할 수 있습니다. 순서대로 설치하는 방법은 다음과 같습니다:
1. Homebrew 설치 확인 (이미 설치되어 있다면 이 단계는 건너뛰어도 됩니다):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
2. Docker Compose 설치:
brew install docker-compose
3. 설치 확인:
docker-compose --version
위 명령어를 통해 Docker Compose가 제대로 설치되었는지 확인할 수 있습니다.
Docker Desktop을 사용하는 경우에는 CLI에서 별도로 설치할 필요 없이, docker compose
명령어로 Docker Compose를 사용할 수 있습니다.
만약 이미 Docker Desktop을 사용 중이라면, 아래와 같이 docker compose
명령어로 실행하면 됩니다:
docker compose up
프로젝트 트리 구조
tree .
.
├── docker-compose-start.yaml
├── grafana
│ ├── data
│ └── provisioning
└── prometheus
├── config
│ └── prometheus.yml
└── data
기본 설정: Prometheus와 Grafana 구성
우선, Prometheus와 Grafana를 구성합니다. Prometheus는 메트릭을 수집하고 시계열 데이터를 저장하는 도구이고, Grafana는 이를 시각화하는 대시보드를 제공합니다.
docker-compose-start.yaml
파일을 아래와 같이 작성합니다.
version: '3.8'
networks:
monitor:
driver: bridge
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
user: root
volumes:
- ./prometheus/config:/etc/prometheus
- ./prometheus/data:/prometheus
ports:
- 9090:9090
networks:
- monitor
restart: always
grafana:
image: grafana/grafana:latest
container_name: grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- ./grafana/data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
ports:
- 3000:3000
depends_on:
- prometheus
networks:
- monitor
restart: always
docker-compose.yml
파일에서 volumes
는 컨테이너 내부 파일 시스템과 호스트 파일 시스템 사이의 데이터를 영구적으로 저장하거나 공유하기 위해 사용됩니다. 이를 통해 데이터를 영구적으로 유지할 수 있으며, 컨테이너가 재시작되거나 삭제되더라도 데이터가 보존됩니다. 이제 Prometheus와 Grafana에서 정의된 각 volumes
가 어떤 역할을 하는지 설명하겠습니다.
1. Prometheus의 volumes
volumes:
- ./prometheus/config:/etc/prometheus
- ./prometheus/data:/prometheus
1. ./prometheus/config:/etc/prometheus
- 호스트 시스템의
./prometheus/config
디렉터리를 컨테이너 내부의/etc/prometheus
에 마운트합니다. prometheus.yml
과 같은 구성 파일들이 저장된 디렉터리입니다. Prometheus가 메트릭을 수집할 때 어떤 타겟을 모니터링할지, 스크래핑 간격 등을 정의한 설정 파일들을 여기서 관리합니다.- 즉, Prometheus 설정을 외부에서 쉽게 관리하고 변경할 수 있게 해줍니다.
2. ./prometheus/data:/prometheus
- 호스트 시스템의
./prometheus/data
디렉터리를 컨테이너 내부의/prometheus
디렉터리에 마운트합니다. - Prometheus는 메트릭 데이터를 시계열 데이터베이스로 저장하므로, 이 데이터가 이 디렉터리에 저장됩니다.
- 이 볼륨을 설정하면, Prometheus 컨테이너가 중지되거나 재시작되어도 수집한 메트릭 데이터가 영구적으로 저장됩니다.
2. Grafana의 volumes
volumes:
- ./grafana/data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
1. ./grafana/data:/var/lib/grafana
- 호스트 시스템의
./grafana/data
디렉터리를 Grafana 컨테이너 내부의/var/lib/grafana
디렉터리에 마운트합니다. - Grafana에서 생성된 대시보드, 사용자 설정, 데이터 소스 등의 영구 저장소입니다.
- 이를 통해 Grafana 설정이 저장되고 컨테이너가 재시작되거나 삭제되더라도 대시보드 및 설정이 유지됩니다.
./grafana/provisioning:/etc/grafana/provisioning
- 호스트 시스템의
./grafana/provisioning
디렉터리를 컨테이너 내부의/etc/grafana/provisioning
에 마운트합니다. - Grafana의 데이터 소스와 대시보드를 자동으로 설정하기 위한 설정 파일들이 위치하는 디렉터리입니다.
- 프로비저닝을 통해 Grafana를 재시작하더라도 미리 정의된 대시보드나 데이터 소스가 자동으로 구성됩니다.
- 호스트 시스템의
Prometheus 설정: prometheus.yml
Prometheus가 Redis Exporter와 같은 외부 시스템의 메트릭을 수집할 수 있도록 prometheus.yml 파일을 설정해야 합니다. 아래는 Redis Exporter 설정을 포함한 Prometheus 설정 예시입니다.
global:
scrape_interval: 1m
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 1m
static_configs:
- targets: ['localhost:9090']
docker-compose -f docker-compose-start.yaml up -d
Creating network "monitor_monitor" with driver "bridge"
Pulling prometheus (prom/prometheus:latest)...
latest: Pulling from prom/prometheus
6ce8b87a9754: Pull complete
d2f8aae8d80e: Pull complete
b168ffa8f33a: Pull complete
6cff268ec4d7: Pull complete
420957d23add: Pull complete
a63cf2b766b6: Pull complete
8a289f97ad1d: Pull complete
1fd5d47e09da: Pull complete
1afe4a0d7329: Pull complete
bd55ccfa5aad: Pull complete
6179424432d2: Pull complete
09a7ac33c11a: Pull complete
Digest: sha256:f6639335d34a77d9d9db382b92eeb7fc00934be8eae81dbc03b31cfe90411a94
Status: Downloaded newer image for prom/prometheus:latest
Pulling grafana (grafana/grafana:latest)...
latest: Pulling from grafana/grafana
bca4290a9639: Already exists
35ffea0c044a: Pull complete
fbbaca673c19: Pull complete
73d7d01a1d2c: Pull complete
f257bec43f81: Pull complete
15e31fbe4904: Pull complete
8ff0366d982d: Pull complete
1e825da9c63a: Pull complete
ffca16271da6: Pull complete
27a3c8ebdfbf: Pull complete
Digest: sha256:408afb9726de5122b00a2576763a8a57a3c86d5b0eff5305bc994ceb3eb96c3f
Status: Downloaded newer image for grafana/grafana:latest
Creating prometheus ... done
Creating grafana ... done
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b1eff66f0bde grafana/grafana:latest "/run.sh" 3 minutes ago Up 3 minutes 0.0.0.0:3000->3000/tcp grafana
da73d4bb4155 prom/prometheus:latest "/bin/prometheus --c…" 3 minutes ago Up 3 minutes 0.0.0.0:9090->9090/tcp prometheus
각 서버가 정상적으로 연결 된 것을 docker ps 명령어로 확인 할 수 있습니다.
grafana와 prometheus에서 제공하는 web UI에도 접속해봅니다.
현재 구성에서는 그라파나와 프로메테우스가 서로 연결된 상태가 아닙니다.
grafana와 prometheus간의 연결이 필요합니다.
그라파나의 첫 홈 화면에서 DATA SOURCES가 있는 버튼을 눌러줍니다.(바로 위 이미지)
그럼 프로메테우스 아이콘이 있는 블럭이 보입니다.(아래 이미지). 클릭!
Settings -> Connection의 Prometheus server URL * 입력란에 URL을 넣어주어야 합니다.
현재 구성상 localhost를 입력하면 docker network 연결이 되지 않습니다.
왜냐하면, docker-compose-start.yaml 파일에서 monitor라는 네트워크로 서로 연결하도록 했으며 이는 서비스 이름으로 해당 monitor. network를 공유하는 서비스간의 통신이 가능하게 됩니다.
아래 이미지에 입력된 URL과 같이 http://prometheus:9090으로 입력해주고 save&test를 클릭해줍니다. 정상적인 접속이 되면 초록색 UI로 정상 접속이 나타남을 육안으로 식별 할 수 있습니다.
다음은 redis exporter, redis를 구성하겠습니다. 이를 위해서는 2개의 이미지가 추가로 필요합니다.
이후 redis exporter, redis 컨테이너 서버가 정상적으로 기동한다면 prometheus는 redis exporter로 pull을 요청하여 metric 정보를 받을 수 있게 됩니다. 그리고 이를 prometheus에서 그 데이터를 적재하고 grafana에 전달하여 grafana에서는 시각화하여 볼 수 있게 됩니다.
redis_exporter에 대한 설정 정보는 아래 이미지와 같이 간단하게 볼수 있습니다.
해당 URL의 github 주소에서 README.md 파일을 통해서 설치, 구성등 정보를 확인 할 수 있습니다.
https://github.com/oliver006/redis_exporter
추가로 docker-compose 파일을 만들겠습니다. 단, 이전과 다른 이름의 파일을 생성하겠습니다.
cp docker-compose-start.yml docker-compose-with-exporter.yml
그리고 docker-compose-with-exporter.yml 파일을 열고 최하단에 아래 내용을 추가해줍니다.
redis-exporter는 redis의 정보를 가져와야하므로 redis의 정보를 가져와야 합니다.
redis-exporter:
container_name: redis-exporter
image: oliver006/redis_exporter:latest
environment:
- REDIS_ADDR=redis://redis:6379
ports:
- 9121:9121
depends_on:
- prometheus
networks:
- monitor
restart: always
추가적으로 필요한 환경변수에 대한 설정은 아래 URL에 접속하여서 CommandLine flags를 참고합니다.(아래 이미지)
최종버전 docker-compose.yml 파일을 이용하여서 4개의 컨테이너 서버를 구성해봅시다.
version: '3.8'
networks:
monitor:
driver: bridge
services:
redis:
image: redis:6.2
container_name: redis
ports:
- 6379:6379
networks:
- monitor
restart: always
prometheus:
image: prom/prometheus:latest
container_name: prometheus
user: root
volumes:
- ./prometheus/config:/etc/prometheus
- ./prometheus/data:/prometheus
ports:
- 9090:9090
networks:
- monitor
restart: always
grafana:
image: grafana/grafana:latest
container_name: grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- ./grafana/data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
ports:
- 3000:3000
depends_on:
- prometheus
networks:
- monitor
restart: always
redis-exporter:
container_name: redis-exporter
image: oliver006/redis_exporter:latest
environment:
- REDIS_ADDR=redis://redis:6379
ports:
- 9121:9121
depends_on:
- prometheus
networks:
- monitor
restart: always
정상적으로 컨테이너 서버가 기동되었는지 확인합니다.
docker-compose -f docker-compose.yml up -d
Creating network "monitor_monitor" with driver "bridge"
Pulling redis (redis:6.2)...
6.2: Pulling from library/redis
92c3b3500be6: Already exists
631720f833ee: Already exists
704a08909867: Already exists
090311ee98f0: Already exists
bbba1a60ba32: Pull complete
224e51cf38f8: Pull complete
4f4fb700ef54: Pull complete
0e30156b3e22: Pull complete
Digest: sha256:7919fdd5300e7abf7ae95919e6f144b37c55df16553302dbbcc7495a5aa0c079
Status: Downloaded newer image for redis:6.2
Pulling redis-exporter (oliver006/redis_exporter:latest)...
latest: Pulling from oliver006/redis_exporter
cf04c63912e1: Pull complete
2886b3db1360: Pull complete
a1a8684391e4: Pull complete
Digest: sha256:8dde0136b66ec4dfb25802283fe89852a405368b095b3893841d90499a8d4e17
Status: Downloaded newer image for oliver006/redis_exporter:latest
Creating prometheus ... done
Creating redis ... done
Creating redis-exporter ... done
Creating grafana ... done
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bad278f78125 oliver006/redis_exporter:latest "/redis_exporter" 7 seconds ago Up 6 seconds 0.0.0.0:9121->9121/tcp redis-exporter
8775b121e4c4 grafana/grafana:latest "/run.sh" 7 seconds ago Up 6 seconds 0.0.0.0:3000->3000/tcp grafana
89e2d5d2a5f2 prom/prometheus:latest "/bin/prometheus --c…" 7 seconds ago Up 7 seconds 0.0.0.0:9090->9090/tcp prometheus
3ca3eb26cc40 redis:6.2 "docker-entrypoint.s…" 7 seconds ago Up 7 seconds 0.0.0.0:6379->6379/tcp redis
redis expoter가 정상적으로 기동되었는지 localhost:9121에 접속하여 web UI화면에서도 확인 가능합니다.
또한 redis expoter가 집계하고 있는 데이터 역시 Metrics 버튼을 클릭하여 확인 할 수 있습니다.
localhost:9121/metrics에 접속하면 redis expoter가 redis로부터 가져온 데이터를 볼 수 있습니다. 이는 결국 프로메테우스로 전달되어서 확인 할 수 있습니다. redis_commands_total이라는 데이터가 prometheus에서도 식별 할 수 있는지 확인해보겠습니다.
그러기 위해서는 기존 prometheus.yml 파일을 수정해주어야 합니다.
추가 job 정보로 redis-exporter를 아래 yml 파일 정의와 같이 만들고 저장합니다.
global:
scrape_interval: 1m
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 1m
static_configs:
- targets: ['localhost:9090']
- job_name: 'redis-exporter'
scrape_interval: 5s
static_configs:
- targets: ['redis-exporter:9121']
만약 기존 실행되었던 docker-compose가 있다면 down 시키고 다시 실행 시켜 줍니다.
docker-compose down
Removing grafana ... done
Removing redis-exporter ... done
Removing prometheus ... done
Removing redis ... done
Removing network monitor_monitor
docker-compose up -d
Creating network "monitor_monitor" with driver "bridge"
Creating redis ... done
Creating prometheus ... done
Creating redis-exporter ... done
Creating grafana ... done
prometheus에서 redis exporter로부터 잘 데이터를 scraping 하였는지 localhost:9090에서 redis_commands_total이라고 검색해봅니다. 그러면 아래 이미지와 같이 확인 할 수 있습니다. 5초가 지나서 새로고침하면 데이터가 변경되었다는 사실을 알 수 있습니다.
그라파나에서는 레디스 익스포터에서 수집되는 메트릭 정보를 대시보드로 볼 수 있습니다.
https://grafana.com/oss/prometheus/exporters/redis-exporter/?tab=dashboards
해당 링크로 가서 You can fetch the dashboard JSON here을 클릭하면 설정 정보를 다운받을 수 있습니다.
그라파나 화면으로 가서 우측 상단의 + 버튼을 클릭하고 Import dashboard를 클릭합니다.
1) 다운 받은 파일을 drag and drop으로 넣어도 되고
2) json 파일을 열어 복사한 내용을 그대로 json 입력 정보란에 넣어줍니다. 그리고 Load 버튼을 클릭합니다.
그 다음 Import 버튼을 눌러 주면 정상적으로 대시보드가 나타나게 됩니다.
필터링 조건에 따라 시간별 혹은 분단위로 지표를 볼 수 있습니다.
'DB > Redis' 카테고리의 다른 글
Redis Replication (1) | 2024.09.17 |
---|---|
Spring Boot Cache 실습 (1) | 2024.09.14 |
Redis Cache 실습(Aka. Write Back) (1) | 2024.09.14 |
Redis Cache 실습(Aka. Jedis, Cache Aside) (0) | 2024.09.14 |
Redis Cache 활용법: 성능 최적화를 위한 캐시 전략 (0) | 2024.09.12 |