깊이 파고들기, 외부 도구 사용
깊이 파고들기, 외부 도구 사용 (Diving Deep, Use External Tools)
머신에 접근할 수 있으면 운영자는 로그와 nodetool이 허용하는 것보다 더 깊이 파고들 수 있어요. 모든 Cassandra 운영자가 각자 선호하는 문제 해결 도구 세트를 가지고 있겠지만, 이 페이지에는 가장 흔한 운영 기법과 그 도구들의 예시가 담겨 있습니다. 이 명령들 중 상당수는 Linux에서만 동작하지만, 다른 운영체제에서 배포 중이라면 유사한 OS 레벨 메트릭과 프로세스를 평가하는 상당히 유사한 도구가 있을 수 있어요.
본문
JVM 도구
JVM에는 유용한 도구들이 함께 제공됩니다. 그중 일부는 특히 힙과 실행 스택과 관련된 Cassandra 문제를 디버깅하는 데 유용해요.
NOTE: JVM 도구와 Cassandra에는 두 가지 흔한 함정이 있습니다.
- 기본적으로 Cassandra는
-XX:+PerfDisableSharedMem을 설정해 장시간 일시 정지를 방지합니다(자세한 내용은 CASSANDRA-9242와 CASSANDRA-9483 참고). JVM 도구를 사용하고 싶다면 그 대신/tmp를 인메모리tmpfs로 마운트할 수 있는데, 이 역시 CASSANDRA-9242를 효과적으로 우회합니다. - 도구를 Cassandra가 실행 중인 것과 같은 사용자로 실행해야 합니다. 예를 들어 데이터베이스가
cassandra사용자로 실행 중이라면 도구도sudo -u cassandra <cmd>처럼cassandra사용자로 실행해야 합니다.
가비지 컬렉션 상태 (jstat)
힙 압력을 의심한다면 jstat으로 Cassandra 프로세스의 가비지 컬렉션 상태를 깊이 들여다볼 수 있어요. 이 명령은 항상 실행해도 안전하며, eden 힙 사용량(E), 구세대(old) 힙 사용량(O), eden 컬렉션 횟수(YGC), eden 컬렉션에 소요된 시간(YGCT), 구/혼합 세대 컬렉션(FGC)과 그 소요 시간(FGCT)을 포함한 상세 힙 정보를 제공합니다.
jstat -gcutil <cassandra pid> 500ms
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 81.53 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 82.36 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 82.36 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 83.19 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 83.19 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 84.19 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 84.19 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 85.03 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 85.03 31.16 93.07 88.20 12 0.151 3 0.257 0.408
0.00 0.00 85.94 31.16 93.07 88.20 12 0.151 3 0.257 0.408
이 경우 구세대 힙 사용량 31.16%, eden 83%로 비교적 건강한 힙 프로파일을 볼 수 있어요. 구세대가 정기적으로 75%를 넘는다면(CMS의 75% 점유 임계값 가정) 힙이 더 필요할 가능성이 높습니다. 그런 지속적으로 높은 구세대가 있다면 구세대 힙을 과소 프로비저닝했거나, Cassandra가 수집하기에 힙에 라이브 데이터가 너무 많다는 뜻인 경우가 많습니다(예: 멤테이블 때문). 또 하나 지켜볼 것은 영(young) 가비지 컬렉션(YGC) 사이의 시간으로, eden 힙이 얼마나 자주 수집되는지를 나타냅니다. 각 영 GC 일시 정지는 약 20-50ms이므로, 그것이 많다면 클라이언트는 높은 백분위수 지연에서 그 영향을 경험하게 됩니다.
스레드 정보 (jstack)
Cassandra가 정확히 무엇을 하고 있는지 시점 스냅샷을 얻으려면 Cassandra PID에 대해 jstack을 실행하세요. 참고: 이것은 JVM을 매우 짧은 시간(<20ms) 동안 일시 정지시킵니다.
$ jstack <cassandra pid> > threaddump
# display the threaddump
$ cat threaddump
# look at runnable threads
$grep RUNNABLE threaddump -B 1
"Attach Listener" #15 daemon prio=9 os_prio=0 tid=0x00007f829c001000 nid=0x3a74 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
--
"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x00007f82e800e000 nid=0x2a19 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
--
"JPS thread pool" #10 prio=5 os_prio=0 tid=0x00007f82e84d0800 nid=0x2a2c runnable [0x00007f82d0856000]
java.lang.Thread.State: RUNNABLE
--
"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007f82e80d7000 nid=0x2a2a runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
--
"C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007f82e80cc000 nid=0x2a29 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
--
# Note that the nid is the Linux thread id
스레드 덤프에서 가장 중요한 정보 중 일부는 대기/블로킹 중인 스레드와, 그 스레드가 어떤 락이나 모니터에서 블로킹/대기 중인지를 포함합니다.
기본 OS 도구
Cassandra 문제를 디버깅할 때 좋은 출발점은 Cassandra가 시스템 리소스와 어떻게 상호작용하는지 이해하는 것입니다. 다음은 모두 Cassandra가 많이 사용하는 리소스입니다.
- CPU 코어. 동시 사용자 쿼리 실행용
- CPU 처리 시간. 쿼리 활동용(데이터 압축 해제, 행 병합 등)
- CPU 처리 시간(낮은 우선순위). 백그라운드 작업용(컴팩션, 스트리밍 등)
- Java 힙용 RAM. 내부 데이터 구조와 기본적으로 Cassandra 멤테이블을 보유하는 데 사용. 힙 공간은 일반적으로 그리고 쓰기 성능의 핵심 구성 요소입니다.
- OS 디스크 캐시용 RAM. 자주 접근되는 SSTable 블록을 캐시하는 데 사용. OS 디스크 캐시는 읽기 성능의 핵심 구성 요소입니다.
- 디스크. Cassandra는 디스크 읽기 지연, 디스크 쓰기 처리량, 그리고 당연히 디스크 공간에 대해 많은 관심을 가집니다.
- 네트워크 지연. Cassandra는 많은 노드 간 요청을 하므로, 노드 간 네트워크 지연이 성능에 직접 영향을 줄 수 있어요.
- 네트워크 처리량. Cassandra(다른 데이터베이스와 마찬가지로)는 작은 요청(예:
SELECT * from foo.bar)이 거대한 결과 집합(예: 전체 데이터셋)을 반환하는 소위 "incast" 문제를 자주 겪습니다. 그런 상황에서는 송신 대역폭이 중요합니다.
종종 Cassandra 문제 해결은 머신이나 클러스터가 어떤 리소스를 소진하고 있는지 규명하는 것으로 귀결됩니다. 그러면 그 리소스를 더 확보하거나, 쿼리 패턴을 바꿔 그 리소스를 덜 사용하게 만들면 됩니다.
높은 수준의 리소스 사용량 (top/htop)
Cassandra는 시스템 리소스를 상당히 많이 사용하므로, 가장 먼저 하는 유용한 행동이 top이나 htop(웹사이트)을 실행해 머신 상태를 보는 경우가 많아요.
살펴볼 만한 유용한 것들:
- 시스템 로드 수준. 이 숫자는 혼란스러울 수 있지만, 일반적으로 로드 평균이 CPU 코어 수보다 크면 Cassandra의 지연(100ms 미만)이 그리 좋지 않을 가능성이 높습니다. 자세한 내용은 Linux Load Averages을 참고하세요.
- CPU 사용률. 특히
htop은 CPU 사용률을user(낮고 보통 우선순위),system(커널),io-wait로 나누어 보여주는 데 도움이 됩니다. Cassandra 쿼리 스레드는 보통 우선순위의user스레드로 실행되는 반면, 컴팩션 스레드는 낮은 우선순위의user스레드로 실행됩니다. 높은system시간은 스레드 경합 같은 문제를 나타낼 수 있고, 높은io-wait는 느린 디스크 드라이브를 나타낼 수 있어요. 이것은 Cassandra가 처리 리소스를 무엇에 쓰고 있는지 이해하는 데 도움이 됩니다. - 메모리 사용량. 어떤 프로그램이 가장 많은 상주 메모리를 사용하는지 확인하세요. 아마 Cassandra일 겁니다. Linux가 (2018년 기준) 메모리 매핑 파일 메모리를 회계하는 방식 때문에, Cassandra의 숫자는 부정확하게 높을 가능성이 높아요.
IO 사용량 (iostat)
iostat을 사용해 데이터 드라이브의 상태(지연 분포, 처리량, 사용률 포함)를 파악하세요.
$ sudo iostat -xdm 2
Linux 4.13.0-13-generic (hostname) 07/03/2018 _x86_64_ (8 CPU)
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.28 0.32 5.42 0.01 0.13 48.55 0.01 2.21 0.26 2.32 0.64 0.37
sdb 0.00 0.00 0.00 0.00 0.00 0.00 79.34 0.00 0.20 0.20 0.00 0.16 0.00
sdc 0.34 0.27 0.76 0.36 0.01 0.02 47.56 0.03 26.90 2.98 77.73 9.21 1.03
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.00 2.00 32.00 0.01 4.04 244.24 0.54 16.00 0.00 17.00 1.06 3.60
sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdc 0.00 24.50 0.00 114.00 0.00 11.62 208.70 5.56 48.79 0.00 48.79 1.12 12.80
이 경우 /dev/sdc1이 매우 느린 드라이브임을 알 수 있어요. await가 50밀리초에 가깝고 avgqu-sz가 약 5 IO입니다. 드라이브가 특별히 포화되지는 않았지만(사용률 12.8%), 전형적인 Cassandra 작업에 50ms는 꽤 길기 때문에 p99 지연에 어떤 영향을 미칠지 우려해야 합니다. 다만 이 경우 지연 대부분이 쓰기에 있습니다(보통 쓰기가 읽기보다 지연이 큼), 이는 Cassandra의 LSM 특성상 사용자에게 종종 숨겨집니다.
iostat으로 평가할 중요한 메트릭:
- 초당 읽기와 쓰기. 이 숫자는 워크로드에 따라 변하지만, 일반적으로 Cassandra가 디스크에서 읽어야 하는 횟수가 많을수록 Cassandra 읽기 지연은 느려집니다. 초당 많은 읽기는 클러스터에 OS 페이지 캐싱용 메모리가 부족하다는 확실한 신호일 수 있어요.
- 쓰기 처리량. Cassandra의 LSM 모델은 사용자 쓰기를 지연시키고 배치로 묶으므로, 기본 매체로의 처리량이 Cassandra에게 가장 중요한 쓰기 메트릭입니다.
- 읽기 지연(
r_await). Cassandra가 OS 페이지 캐시를 놓쳐 SSTable에서 읽을 때, 읽기 지연이 데이터 응답 속도를 직접 결정합니다. - 쓰기 지연. Cassandra는 commit log를 동기화할 때를 제외하면 쓰기 지연에 덜 민감합니다. 이것은 보통 쓰기 지연의 아주 높은 백분위수에 들어갑니다.
상세한 지연 구간을 얻으려면 더 고급 도구가 필요하다는 점에 유의하세요.
OS 페이지 캐시 사용량
Cassandra는 메모리 매핑 파일을 많이 사용하므로, 운영체제의 Page Cache 건강 상태가 성능에 매우 중요합니다. 먼저 시스템에 사용 가능한 캐시가 얼마나 있는지 찾아보세요.
$ free -g
total used free shared buff/cache available
Mem: 15 9 2 0 3 5
Swap: 0 0 0
이 경우 사용자 프로세스(Cassandra 힙)가 9GB 메모리를 사용하고, 8GB가 OS 페이지 캐시로 사용 가능합니다. 그중 3GB가 실제로 파일 캐시에 사용됩니다. 메모리가 대부분 사용되어 페이지 캐시에 사용할 수 없다면 Cassandra 성능이 크게 저하될 수 있어요. 그래서 Cassandra는 힙에 예약하는 메모리를 합리적으로 작게 시작하는 것입니다.
OS 페이지 캐시를 자주 놓친다고 의심된다면 고급 도구로 더 깊이 들여다볼 수 있습니다.
네트워크 지연과 신뢰성
Cassandra가 다른 복제본을 포함하는 쓰기나 읽기(예: LOCAL_QUORUM 읽기)를 할 때마다, 지연에 영향을 주는 주요 요인 중 하나는 네트워크 지연입니다. 다중 머신 작업 문제를 디버깅할 때 네트워크는 조사할 중요한 리소스가 될 수 있어요. ping과 traceroute, 그리고 가장 효과적으로는 mtr 같은 도구로 노드 간 지연을 확인할 수 있습니다.
$ mtr -nr www.google.com
Start: Sun Jul 22 13:10:28 2018
HOST: hostname Loss% Snt Last Avg Best Wrst StDev
1.|-- 192.168.1.1 0.0% 10 2.0 1.9 1.1 3.7 0.7
2.|-- 96.123.29.15 0.0% 10 11.4 11.0 9.0 16.4 1.9
3.|-- 68.86.249.21 0.0% 10 10.6 10.7 9.0 13.7 1.1
4.|-- 162.141.78.129 0.0% 10 11.5 10.6 9.6 12.4 0.7
5.|-- 162.151.78.253 0.0% 10 10.9 12.1 10.4 20.2 2.8
6.|-- 68.86.143.93 0.0% 10 12.4 12.6 9.9 23.1 3.8
7.|-- 96.112.146.18 0.0% 10 11.9 12.4 10.6 15.5 1.6
9.|-- 209.85.252.250 0.0% 10 13.7 13.2 12.5 13.9 0.0
10.|-- 108.170.242.238 0.0% 10 12.7 12.4 11.1 13.0 0.5
11.|-- 74.125.253.149 0.0% 10 13.4 13.7 11.8 19.2 2.1
12.|-- 216.239.62.40 0.0% 10 13.4 14.7 11.5 26.9 4.6
13.|-- 108.170.242.81 0.0% 10 14.4 13.2 10.9 16.0 1.7
14.|-- 72.14.239.43 0.0% 10 12.2 16.1 11.0 32.8 7.1
15.|-- 216.58.195.68 0.0% 10 25.1 15.3 11.1 25.1 4.8
이 mtr 예시에서 패킷이 취하는 경로와 전형적인 손실·지연을 빠르게 평가할 수 있어요. 패킷 손실은 보통 200ms에서 3s 사이의 추가 지연으로 이어지므로, 지연 문제의 흔한 원인이 될 수 있습니다.
네트워크 처리량
Cassandra는 송신 대역폭 제한에 민감하므로, 때로는 네트워크 처리량이 제한되었는지 확인하는 것이 유용합니다. 이를 위한 편리한 도구 중 하나가 iftop으로, 대역폭 사용량과 연결 정보를 한눈에 보여줍니다. 로컬 ccm 클러스터에 대해 스트레스 실행하는 동안의 트래픽 예시입니다.
$ # remove the -t for ncurses instead of pure text
$ sudo iftop -nNtP -i lo
interface: lo
IP address is: 127.0.0.1
MAC address is: 00:00:00:00:00:00
Listening on lo
# Host name (port/service if enabled) last 2s last 10s last 40s cumulative
--------------------------------------------------------------------------------------------
1 127.0.0.1:58946 => 869Kb 869Kb 869Kb 217KB
127.0.0.3:9042 <= 0b 0b 0b 0B
2 127.0.0.1:54654 => 736Kb 736Kb 736Kb 184KB
127.0.0.1:9042 <= 0b 0b 0b 0B
3 127.0.0.1:51186 => 669Kb 669Kb 669Kb 167KB
127.0.0.2:9042 <= 0b 0b 0b 0B
4 127.0.0.3:9042 => 3.30Kb 3.30Kb 3.30Kb 845B
127.0.0.1:58946 <= 0b 0b 0b 0B
5 127.0.0.1:9042 => 2.79Kb 2.79Kb 2.79Kb 715B
127.0.0.1:54654 <= 0b 0b 0b 0B
6 127.0.0.2:9042 => 2.54Kb 2.54Kb 2.54Kb 650B
127.0.0.1:51186 <= 0b 0b 0b 0B
7 127.0.0.1:36894 => 1.65Kb 1.65Kb 1.65Kb 423B
127.0.0.5:7000 <= 0b 0b 0b 0B
8 127.0.0.1:38034 => 1.50Kb 1.50Kb 1.50Kb 385B
127.0.0.2:7000 <= 0b 0b 0b 0B
9 127.0.0.1:56324 => 1.50Kb 1.50Kb 1.50Kb 383B
127.0.0.1:7000 <= 0b 0b 0b 0B
10 127.0.0.1:53044 => 1.43Kb 1.43Kb 1.43Kb 366B
127.0.0.4:7000 <= 0b 0b 0b 0B
--------------------------------------------------------------------------------------------
Total send rate: 2.25Mb 2.25Mb 2.25Mb
Total receive rate: 0b 0b 0b
Total send and receive rate: 2.25Mb 2.25Mb 2.25Mb
--------------------------------------------------------------------------------------------
Peak rate (sent/received/total): 2.25Mb 0b 2.25Mb
Cumulative (sent/received/total): 576KB 0B 576KB
============================================================================================
이 경우 대역폭이 많은 피어 사이에 비교적 고르게 나누어져 있지만, 총량이 NIC의 정격 용량에 가까워지거나 특정 클라이언트에 집중된다면 어떤 문제가 발생하고 있는지에 대한 단서가 될 수 있어요.
고급 도구
때로는 운영자로서 정말 깊이 파고들 필요가 있습니다. 이때 고급 OS 도구가 요긴할 수 있어요.
bcc-tools
대부분의 현대 Linux 배포판(4.1보다 새로운 커널)은 성능 문제를 깊이 파고드는 bcc-tools를 지원합니다. 먼저 bcc-tools를 설치하세요(예: Debian에서 apt 사용).
$ apt install bcc-tools
그런 다음 bcc-tools가 포함하는 모든 도구를 사용할 수 있어요. 가장 유용한 도구 중 하나는 cachestat(cachestat examples)으로, OS 페이지 캐시 적중/실패가 정확히 얼마나 발생하는지 확인할 수 있습니다.
$ sudo /usr/share/bcc/tools/cachestat -T 1
TIME TOTAL MISSES HITS DIRTIES BUFFERS_MB CACHED_MB
18:44:08 66 66 0 64 88 4427
18:44:09 40 40 0 75 88 4427
18:44:10 4353 45 4308 203 88 4427
18:44:11 84 77 7 13 88 4428
18:44:12 2511 14 2497 14 88 4428
18:44:13 101 98 3 18 88 4428
18:44:14 16741 0 16741 58 88 4428
18:44:15 1935 36 1899 18 88 4428
18:44:16 89 34 55 18 88 4428
이 경우 페이지 캐시 MISSES가 그리 많지 않아 합리적인 크기의 캐시를 의미합니다. 이 메트릭은 Cassandra 노드의 "핫" 데이터셋을 가장 직접적으로 측정한 것입니다. 캐시가 충분하지 않으면 MISSES가 높아지고 성능이 느려집니다. 캐시가 충분하면 MISSES가 낮고 (거의 모든 읽기가 메모리에서 제공되므로) 성능이 빠릅니다.
biolatency(biolatency examples)로 디스크 지연 분포를 측정해, 읽기가 OS 페이지 캐시를 놓치고 디스크에 닿을 때 Cassandra가 얼마나 느려질지 가늠할 수도 있어요.
$ sudo /usr/share/bcc/tools/biolatency -D 10
Tracing block device I/O... Hit Ctrl-C to end.
disk = 'sda'
usecs : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 12 |****************************************|
32 -> 63 : 9 |****************************** |
64 -> 127 : 1 |*** |
128 -> 255 : 3 |********** |
256 -> 511 : 7 |*********************** |
512 -> 1023 : 2 |****** |
disk = 'sdc'
usecs : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 0 | |
32 -> 63 : 0 | |
64 -> 127 : 41 |************ |
128 -> 255 : 17 |***** |
256 -> 511 : 13 |*** |
512 -> 1023 : 2 | |
1024 -> 2047 : 0 | |
2048 -> 4095 : 0 | |
4096 -> 8191 : 56 |***************** |
8192 -> 16383 : 131 |****************************************|
16384 -> 32767 : 9 |** |
이 경우 데이터 드라이브(sdc)의 대부분 IO는 빠르지만, 많은 IO가 8~16밀리초 사이가 걸립니다.
마지막으로 biosnoop(examples)으로 더 깊이 들어가 IO별 지연을 확인할 수 있어요.
$ sudo /usr/share/bcc/tools/biosnoop | grep java | head
0.000000000 java 17427 sdc R 3972458600 4096 13.58
0.000818000 java 17427 sdc R 3972459408 4096 0.35
0.007098000 java 17416 sdc R 3972401824 4096 5.81
0.007896000 java 17416 sdc R 3972489960 4096 0.34
0.008920000 java 17416 sdc R 3972489896 4096 0.34
0.009487000 java 17427 sdc R 3972401880 4096 0.32
0.010238000 java 17416 sdc R 3972488368 4096 0.37
0.010596000 java 17427 sdc R 3972488376 4096 0.34
0.011236000 java 17410 sdc R 3972488424 4096 0.32
0.011825000 java 17427 sdc R 3972488576 16384 0.65
... time passes
8.032687000 java 18279 sdc R 10899712 122880 3.01
8.033175000 java 18279 sdc R 10899952 8192 0.46
8.073295000 java 18279 sdc R 23384320 122880 3.01
8.073768000 java 18279 sdc R 23384560 8192 0.46
biosnoop으로 모든 IO와 그 소요 시간을 볼 수 있어요. 이 데이터로 biolatency의 지연 분포를 구성할 수 있지만, 디스크 지연이 성능에 어떻게 영향을 미치는지 더 잘 이해하는 데에도 쓸 수 있습니다. 예를 들어 이 특정 드라이브는 read_ahead_kb의 큰 기본값(128kb) 때문에 메모리 매핑 읽기를 처리하는 데 약 3ms가 걸립니다. 포인트 읽기 성능을 개선하려면 SSD 같은 빠른 데이터 볼륨에서는 read_ahead_kb를 줄이고 싶을 수 있으며, HDD에서는 128kb 같은 더 높은 값을 유지하는 것이 아마 맞을 겁니다. 절충이 있으므로 자세한 내용은 queue-sysfs 문서를 참고하세요. 어쨌든 biosnoop은 Cassandra가 드라이브를 어떻게 사용하는지 이해하는 데 유용합니다.
vmtouch
Cassandra 데이터 파일 중 OS가 얼마나 많이 캐시하고 있는지 아는 것이 유용할 때가 있어요. 이 질문에 답하는 훌륭한 도구가 vmtouch입니다.
먼저 설치하세요.
$ git clone https://github.com/hoytech/vmtouch.git
$ cd vmtouch
$ make
그런 다음 Cassandra 데이터 디렉토리에서 실행합니다.
$ ./vmtouch /var/lib/cassandra/data/
Files: 312
Directories: 92
Resident Pages: 62503/64308 244M/251M 97.2%
Elapsed: 0.005657 seconds
이 경우 거의 전체 데이터셋이 OS 페이지 캐시에서 핫 상태입니다. 일반적으로 읽기가 캐시를 놓치지 않는 한 백분율은 크게 중요하지 않으며, 그 경우 추가 메모리가 읽기 성능에 도움이 될 수 있어요.
CPU 플레임그래프
Cassandra는 종종 CPU를 많이 사용하지만, 정확히 무엇을 하는지 말하기는 어려울 수 있어요. Cassandra가 CPU 시간에 무엇을 하는지 분석하는 가장 좋은 방법 중 하나는 CPU Flamegraphs를 사용하는 것으로, Cassandra 코드의 어떤 영역이 CPU를 사용하는지 유용하게 표시합니다. 이것은 컴팩션 문제를 "툼스톤을 드롭하는 컴팩션 문제"로 좁히는 데 도움이 되거나, 문제가 있는 동안 Cassandra가 무엇을 하고 있는지 일반적으로 좁히는 데 도움이 됩니다. CPU 플레임그래프를 얻으려면 Java Flamegraphs 지침을 따르세요.
일반적으로:
- Cassandra의
jvm.options설정 파일에서-XX:+PreserveFramePointer옵션을 활성화하세요. 이것은 무시할 만한 성능 영향을 주지만, Cassandra가 실제로 무엇을 하고 있는지 볼 수 있게 해줍니다. perf를 실행해 데이터를 얻으세요.- 그 데이터를 FlameGraph 도구 세트의 관련 스크립트로 보내 플레임그래프로 변환하세요. 결과 SVG 이미지를 브라우저나 다른 이미지 뷰어로 보세요.
예를 들어 github에서 바로 클론해, 먼저 perf-map-agent를 우리 JVM의 위치( /usr/lib/jvm으로 가정)에 설치합니다.
$ sudo bash
$ export JAVA_HOME=/usr/lib/jvm/java-8-oracle/
$ cd /usr/lib/jvm
$ git clone --depth=1 https://github.com/jvm-profiling-tools/perf-map-agent
$ cd perf-map-agent
$ cmake .
$ make
이제 플레임그래프를 얻습니다.
$ git clone --depth=1 https://github.com/brendangregg/FlameGraph
$ sudo bash
$ cd FlameGraph
$ # Record traces of Cassandra and map symbols for all java processes
$ perf record -F 49 -a -g -p <CASSANDRA PID> -- sleep 30; ./jmaps
$ # Translate the data
$ perf script > cassandra_stacks
$ cat cassandra_stacks | ./stackcollapse-perf.pl | grep -v cpu_idle | \
./flamegraph.pl --color=java --hash > cassandra_flames.svg
결과 SVG는 검색 가능하고, 확대/축소 가능하며, 일반적으로 브라우저로 살펴보기 쉽습니다.
패킷 캡처
때로는 문제를 해결하기 위해 Cassandra 노드가 지금 수행하고 있는 쿼리를 이해해야 할 때가 있어요. 그럴 때 tcpdump와 Wireshark 같은 믿음직한 패킷 캡처 도구가 패킷 캡처를 분석하는 데 매우 도움이 됩니다. Wireshark에는 네이티브 CQL 지원도 있지만, 더 새로운 Cassandra 프로토콜 릴리스와 호환성 문제가 가끔 있습니다.
패킷 캡처를 얻으려면 먼저 패킷을 캡처하세요.
$ sudo tcpdump -U -s0 -i <INTERFACE> -w cassandra.pcap -n "tcp port 9042"
이제 wireshark로 열어보세요.
$ wireshark cassandra.pcap
CQL 같은 문장이 보이지 않으면, 9042로 가는 패킷을 우클릭해 Decode as → 9042 포트용 드롭다운에서 CQL을 선택해 CQL로 디코딩해 보세요.
이것을 수동으로 하거나 GUI를 사용하고 싶지 않다면, cqltrace 같은 것을 사용해 CQL 패킷 캡처의 획득과 파싱을 쉽게 할 수도 있어요.