산전수전KUDU전
서동진 매니저
서동진 (logan.seo)
- 카카오뱅크 빅데이터 파트 소속 - Data Platform Engineer (DPE) - DPE Family Lead
- a.k.a ex-clouderian
발표자
오늘의 이야깃거리
• Apache Kudu 빠르게 훑어보기
• 카카오뱅크는 어떻게 사용하고 있을까?
• 썰 (Case Study)
• 소소한 Tips
Kudu 누구냐 넌..?
Kudu 는 동남 아프리카에서 서식하고
있는 영양의 한 종류로서.. =_=?
는 아니고, Kudu는 이런 놈입니다.
Columnar Storage
컬럼형태로 비슷한 패턴의 데이터를
저장하여 Read 효율성과 압축률이 좋고
Table
가독성 좋게 테이블 구조로 보고
Mutable
데이터 변경이 가능하고!
Distribution
클러스터 확장과
Big 한 데이터 저장이 용이하고
Fault Tolerance
장애에 강하고
Low-latency Random Access
Scan 도 빠른데 Random Access까지?
어떻게 이런게 가능해요?
Tablet Replica CFile WAL
MemRowset BlockCache DiskRowset DeltaMemStore DeltaFiles
Flush
Compaction
Raft Consensus Algorithm
숨은 주역들
카카오뱅크는 그렇다면
어떻게 사용하고 있을까?
실시간 스트리밍 데이터 수집
하루 데이터 유입량 5
지금 이 순간에도 데이터는
무궁무진하게 증가하고 있습니다.
저의 의사와는 상관없이 증가하죠.
(거절을 못해요)
저장만해서는 의미 없겠죠?
D 3
(Data-Driven Decision)
아키텍처를 단순하게 +
Fresh 데이터를 활용 가능하게
DE: 요청하신 데이터들 마트 구성해서 EDW 에서 매일매일 열심히 ETL 해서 데이터 적재 해놨어요~
데이터 소급
EDW: 데이터가 일부 변경됐고요. 아.. 일부는 삭제 됐어요.
DS: 변경된 데이터로 분석해야 겠…
HDFS 였다면.. 기술의 향연
아주 매우 간단한 예:
일자별로 Partitioning 된 경우
변경 기간의 Partition들을 DROP하고 , 다시 ETL 해오고 검증하고,
Compute State를 하고하고하고..
하지만 우린 Kudu 좌나
UPSERT
DELETE
하지만 과연 좋기만 한가?
어떻게든 막아 CASE1
WAL* 폭증 현상
WAL 디스크 총 용량
아.. 안돼..
Issue Clarification
1. 특정 Kudu 테이블에 대해 초당 최대 9백만 건 가까운 초대량 Update 수행 됨
2. 여파로 해당 테이블 Tablet 들의 WAL, DeltaMemStore 사이즈 급격하게 증가
✘ WAL DISK 사용량이 임계치 근접
✘ 해당 Kudu 테이블의 Tablet 을 많이 보유한 Tablet Server의 Memory 사용률(DeltaMemStore) 증가로 Memory Hard Limit 에 근접
3. 해당 Tablet Server 에서 Memory Pressure Rejection 발생으로
Write workload Failed 및 Retry 발생
1. Memory Pressure Rejection 이 발생된 Tablet Server 에서 특정 Tablet의
DeltaMemStore 사이즈가 36GB 인 것과 Flush를 못하고 있는 현상을 발견함 2. 아래 내용을 근거로 해당 Tablet 을 Bootstrapping 을 유도하기 위해 다른 Tablet
Server 로 이동(move_replica)을 수행
***Bootstrap replay process 중 다음을 수행: DMS Flush -> (Compaction) -> LogGC
3. 2번 완료 후 해당 WAL 은 GC 되고, WAL DISK 가용량이 확보 됨
4. 1번의 결과를 확인 후 해당 테이블에 대해 kudu rebalance 를 수행하여 나머지 Tablet 들에 해당하는 DMS, WAL 이 차지하고 있는 DISK 사용량을 해소 시킴
(4번 과정의 경우 Table의 Tablet들이 고르게 분포되어 있다면 수동 이동 수행이 필요)
Resolution
Before After
초대량 DELETE도 조심하세요.
그 놈(UPDATE)과 똑같습니다.
위급한 상황에 도움이 되셨음
좋겠습니다.
연쇄 성능 Drop범 CASE2
Write Workload Drop
작년 어느 추운 겨울날..
따란
WHY?
사건 현장
사건 당시의 Kudu Tablet Server Configuration 중
--rpc_num_service_threads=30 (RPC worker thread 의 수)
--rpc_service_queue_length=150 (incoming RPC request 를 위한 queue length)
사건 당시의 Kudu Tablet Server Log 중
사건 정황
Write request on kudu.tserver.TabletServerService from <TServer IP>:42003 dropped due to backpressure. The service queue is full; it has 150 items.
Write request on kudu.tserver.TabletServerService from <TServer IP>:47069 dropped due to backpressure. The service queue is full; it has 150 items.
Write request on kudu.tserver.TabletServerService from <TServer IP>:47069 dropped due to backpressure. The service queue is full; it has 150 items.
Write request on kudu.tserver.TabletServerService from <TServer IP>:47069 dropped due to backpressure. The service queue is full; it has 150 items.
...
Call kudu.tserver.TabletServerService.Scan from <TServer IP>:40809 (request call id 0) took 501917ms (client timeout 10000).
읭? 501917ms (8분 36초) 동안 Scan 을 처리하고 있었다??
30 threads with same stack:
...
TID 35780(rpc worker-3578):
@ 0x3f01c0f7e0 (unknown)
@ 0x3f014e0e34 (unknown)
@ 0x1c5373d (unknown)
@ 0x1c53afe (unknown)
@ 0x1c5fd6e kudu::internal::Descriptor<>::ReadV()
@ 0x1a91a8e kudu::fs::internal::LogBlockContainer::ReadVData()
@ 0x1a97307 kudu::fs::internal::LogReadableBlock::ReadV()
@ 0x1a2d45a kudu::cfile::CFileReader::ReadBlock()
@ 0x1a3b2f4 kudu::cfile::IndexTreeIterator::LoadBlock()
@ 0x1a3c6d9 kudu::cfile::IndexTreeIterator::SeekAtOrBefore()
@ 0x1a30bc8 kudu::cfile::CFileIterator::SeekToOrdinal()
@ 0xaa90c4 kudu::tablet::CFileSet::Iterator::PrepareColumn()
@ 0xaaa4ae kudu::tablet::CFileSet::Iterator::MaterializeColumn()
@ 0xabb352 kudu::tablet::DeltaApplier::MaterializeColumn()
@ 0x1bca515 kudu::MaterializingIterator::MaterializeBlock()
@ 0x1bca5e9 kudu::MaterializingIterator::NextBlock()
사건 정황
사건 당시 Kudu Tablet Server Stack Trace
Trace:
0115 15:49:57.812532 (+ 0us) service_pool.cc:163] Inserting onto call queue 0115 15:49:57.812545 (+ 13us) service_pool.cc:222] Handling call
0115 15:49:57.812816 (+ 271us) tablet_service.cc:1749] Creating iterator
0115 15:49:57.812823 (+ 7us) tablet_service.cc:2075] Waiting safe time to advance 0115 15:49:57.812825 (+ 2us) tablet_service.cc:2083] Waiting for operations to commit
0115 15:49:57.812828 (+ 3us) tablet_service.cc:2097] All operations in snapshot committed. Waited for 3 microseconds
0115 15:58:19.219526 (+501406698us) tablet_service.cc:1793] Iterator init: OK 0115 15:58:19.219531 (+ 5us) tablet_service.cc:1842] has_more: true
0115 15:58:19.219533 (+ 2us) tablet_service.cc:1857] Continuing scan request
0115 15:58:19.219614 (+ 81us) tablet_service.cc:1905] Found scanner be908690d6334aabafdaca3d83e2cab2 0115 15:58:19.720981 (+501367us) tablet_service.cc:1964] Deadline expired - responding early
0115 15:58:19.730486 (+ 9505us) inbound_call.cc:157] Queueing success response Metrics:
{"cfile_cache_hit":79552,"cfile_cache_hit_bytes":4352001,"cfile_cache_miss":60626,"cfile_cache_miss_bytes
":2919765,"delta_iterators_relevant":3219,"lbm_read_time_us":500096611,"lbm_reads_1- 10_ms":37747,"lbm_reads_10-
미네랄의 실체를 알아보자
Metrics:
{"cfile_cache_hit":79552,"cfile_cache_hit_bytes":4352001,"cfile_cache_miss":60626,"cfile_cache_miss_bytes
":2919765,"delta_iterators_relevant":3219,"lbm_read_time_us":500096611,"lbm_reads_1- 10_ms":37747,"lbm_reads_10-
100_ms":16957,"lbm_reads_gt_100_ms":5,"lbm_reads_lt_1ms":5917,"spinlock_wait_cycles":10983936}
Metrics key 설명
● cfile_cache_hit: block cache 에서 hit 된 block 개수
● cfile_cache_miss: block cache 에 존재하지 않는 block 들로 on-disk 에서 read 해야하는 대상 block 개수
○ cfile_cache_miss = lbm_reads_1-10_ms + lbm_reads_10-100_ms + lbm_reads_gt_100_ms + lbm_reads_lt_1ms
● delta_iterators_relevant: iterator 를 통해 연관된 DeltaFile 을 반복하여 찾는 과정 횟수
● lbm_read_time_us: miss 된 block 을 on-disk 에서 read 하는데 소요된 시간
● spinlock_wait_cycles: spinlock 이란 lock을 획득할 때까지 해당 스레드가 빙빙 돌고 있다(spinning)는 것을 의미하며, 이에 해당하는 cycle 횟수
미네랄의 실체(1)
Metrics:
{"cfile_cache_hit":79552,"cfile_cache_hit_bytes":4352001,"cfile_cache_miss":60626,"cfile_cache_miss_bytes
":2919765,"delta_iterators_relevant":3219,"lbm_read_time_us":500096611,"lbm_reads_1- 10_ms":37747,"lbm_reads_10-
100_ms":16957,"lbm_reads_gt_100_ms":5,"lbm_reads_lt_1ms":5917,"spinlock_wait_cycles":10983936}
Metrics 해설
● Scan 에서 처리하는데 소요된 리소스
○ 총 block 수: 79552 + 60626 = 140,178 blocks
○ 총 block 크기: 4352001 + 2919765 = 7,271,766 bytes (6.9MB)
○ miss 된 block 을 on-disk 에서 read 하는데 소요된 시간: 500096611 us (8분33초)
●
cfile_cache_miss
된 block 수 만큼 DISK 에서 read 하여 block cache 에 insert 하는 작업만큼의 리소스를 소비하 는 것을 확인할 수 있었음미네랄의 실체(2)
잡았다 요놈!
용의자 프로파일링
이 미네랄은 어떻게 생겨난걸까?
= 왜 이렇게 많은 block들이 생겨난걸까?
Kudu 에 저장되는 데이터의 마지막 landing zone 인 DISK 로 flush될 때특정 조건에 의해 너무 작은 단위 block (default 32MB) 으로 저장되고 있는 상태를 확인하였고, 이에 따라 엄청난 양의 RowSet block 들이 생성된 것을 확인하였음
● 사건 당시 Kudu에 저장된 총 Tablet Size: 385.5 TiB = 7,016,342,860 blocks
● 특정조건: Tablet Server 당 할당된 총 Memory의 Percentage consumed 가 60%를 초과하면 설정된 flush의 임계 값에 관계 없이 flush가 트리거 됨
○ Scheduling FlushMRSOp(091362ff2abe423fba770e1d4007ebdd): under memory pressure (60.09% used, can flush 11403031 bytes)
● RowSet Compaction은 time series 형태의 PK 성격상 범위가 겹치지 않아 기대치가 낮았으며, 과거 RowSet block 들에 대한 수동 Compaction 도 제공하지 않았음
참고) 사건 당시의 Kudu Tablet Server 의 관련 Configuration
--flush_threshold_mb=1024 (1GB) --flush_threshold_secs=120 (2분)
--budgeted_compaction_target_rowset_size=33554432 (32MB) --memory_limit_hard_bytes=137438953472 (128GB)
--memory_pressure_percentage=60 (76.8GB)
용의자 프로파일
악순환의 고리
Scan Bottleneck
Write Workload Drop
Memory Overhead Kudu 서비스 재시작 시간 증가 Memory Pressure
RowSet block 수 증가 Flushing
Aggressively
Tuning 고려사항
1. Memory Overhead 상황을 해소 시키면, Flush 주기가 길어지기 때문에 MemRowSets 의 사이즈가 증가됨에 따라 필요로 하는 Memory 사용률이 증가될 것으로 예상 됨
2. Tablet Server 별 할당된 총 Memory의 Percentage consumed 가 60%를 초과되는 상황으로 최대한 초과되지 못 하도록 수치 조정이 필요할 것으로 예상 됨
3. Flush, Compaction 시 RowSet size 는 최대한 크게 하도록 유도
적용한 Kudu Tablet Server Configuration
--flush_threshold_mb=2048 (2GB) --flush_threshold_secs=3600 (1시간)
--budgeted_compaction_target_rowset_size=134217728 (128MB) --memory_limit_hard_bytes=163208757248 (152GB)
--memory_pressure_percentage=70 (106.4GB)
예상한 기대 효과
1. RowSet block 개수 감소
Scan 시 발생한 Bottleneck 구간 해소
갱생(Tuning)
Budgeted compaction selection:
[ ] RowSet(5716)( 128M) [0.0000, 0.0006] [<redacted>,<redacted>]
[ ] RowSet(5717)( 128M) [0.0006, 0.0012] [<redacted>,<redacted>]
[ ] RowSet(5718)( 128M) [0.0012, 0.0017] [<redacted>,<redacted>]
[ ] RowSet(9819)( 127M) [0.0017, 0.3904] [<redacted>,<redacted>]
[ ] RowSet(5720)( 128M) [0.0017, 0.0023] [<redacted>,<redacted>]
...
이룩한 결과들
Before After
Before After
Before After
운영에 도움이 되셨음
좋겠습니다.
이런 삽질을 무색하게 할 기다리고 기다리던
KUDU-1400
(Improve rowset compaction policy to consider merging small DRSs)
Apache Kudu 1.9.0
(CDH-6.2.0)
Before After
ASIS: 7,016,342,860 blocks - 6,954,499,602 감소
TOBE: 61,843,258 blocks
아직 하위 버전을 사용하고 계신다면
CDH-6.2.0 이상 버전 업글을
적극적으로 추천 드립니다.
경험상 안정성의 격이 달라요.
난 결백해 CASE3
Negotiation failed
소문의 시작..
소문의 정황
com.streamsets.pipeline.api.StageException: KUDU_03 - Errors while interacting with Kudu: Row error for primary key=”<pk_key>", tablet=null, server=null, status=Timed out:
can not complete before timeout: Batch{operations=43,
tablet="ab2929f39edd4bdeb2d2da89f3307145" [0x00000004, 0x00000005), ignoreAllDuplicateRows=false,
rpc=KuduRpc(method=Write, tablet=ab2929f39edd4bdeb2d2da89f3307145, attempt=2, DeadlineTracker(timeout=10000, elapsed=10188),
Traces:
[0ms] sending RPC to server <tablet server uuid>,
[3031ms] received from server <tablet server uuid> response Network error: [peer <tablet server uuid>] unexpected exception from downstream on [id: 0x92ad64ae, /<streamsets>:50906 =>
<tablet server>:7050],
[3034ms] delaying RPC due to Network error: [peer <tablet server uuid>] unexpected exception from downstream on [id: 0x92ad64ae, /<streamsets>:50906 => <tablet server>:7050],
정말 Kudu 가 범인??
[4915ms] querying master,
당시 StreamSets Log
소문의 정황
해당 시점에 불특정 다수의 Tablet Server 에서 비정기적으로 다수의 ‘Failed RPC negotiation’
WARNING 로그 발생
W0902 22:06:24.973554 6451 negotiation.cc:313] Failed RPC negotiation.
Trace:
0902 22:06:21.973423 (+ 0us) reactor.cc:583] Submitting negotiation task for server connection from <StreamSets>:44242
0902 22:06:21.973472 (+ 49us) server_negotiation.cc:176] Beginning negotiation 0902 22:06:21.973474 (+ 2us) server_negotiation.cc:365] Waiting for connection header
0902 22:06:22.240971 (+267497us) server_negotiation.cc:373] Connection header received
0902 22:06:24.973500 (+2732529us) negotiation.cc:304] Negotiation complete: Timed out:
Server connection negotiation failed: server connection from <StreamSets>:44242
음? 뭔가 이상한데?
소문이 사실이 맞긴 한건가?
소문의 실체를 알아보자
Kudu Negotiation
After the initial connection header is sent, negotiation begins. Negotiation consists of a sequence of request/response messages sent between
the client and server.
→ 협상의 법칙은 ‘주거니 받거니’Step1. Negotiate: The client and server swap RPC feature flags, supported authentication types, and supported SASL mechanisms. This step
always takes exactly one round trip.
→ 일단 Kudu가 받았으니 Client 에게 줘야한다.소문의 실체(1)
0902 22:06:21.973423 (+ 0us) reactor.cc:583] Submitting negotiation task for server connection from <StreamSets>:44242
→ StreamSets 이 Kudu 서버 연결 negotiation task 를 submit 함
0902 22:06:21.973472 (+ 49us) server_negotiation.cc:176] Beginning negotiation
→ StreamSets 와 Kudu 간 Negotiation 이 시작 됨
0902 22:06:21.973474 (+ 2us) server_negotiation.cc:365] Waiting for connection header
→ Kudu 가 StreamSets 에게 connection header 를 받기를 기다림
0902 22:06:22.240971 (+267497us) server_negotiation.cc:373] Connection header received
→ Kudu 가 connection header 를 받음
0902 22:06:24.973500 (+2732529us) negotiation.cc:304] Negotiation complete: Timed out: Server connection negotiation failed: server connection from <StreamSets>:44242
→ 받으니까 줬다는 뭔가가 나와야 하지만 Timeout 으로 Negotiation 실패
→ 2732529+267497+2+49=3000077us 으로 Tablet Server 의 ‘rpc_negotiation_timeout_ms=3000’ 3초를 초과
소문의 실체(2)
Are you pooling clients? Are you sure that your storm workers are not suffering GC pauses? It would be worth running the storm workers with
verbose GC logging and check that you aren't seeing GC around the same time.
The server side log indicates that the workers are connecting and then
taking 6-10 seconds to perform the necessary round trips for RPC connection negotiation. So, the client's disconnecting them.
소문을 따라가 보자 → StreamSets GC log
소문을 추적하던 중 결정적인 단서인 ‘GC Pauses’를 포착
https://community.cloudera.com/t5/Support-Questions/quot-BlockingRecv-error-quot-when-inserting-rows-into-KUDU-1/m-p/52484
결백의 증거
2019-09-02T22:06:22.640+0900: 1039689.060: [Full GC (Allocation Failure) 1022M->658M(1024M), 4.7151635 secs]
[Eden: 0.0B(51.0M)->0.0B(167.0M) Survivors: 0.0B->0.0B Heap: 1022.1M(1024.0M)-
>658.1M(1024.0M)], [Metaspace: 468235K->468160K(1486848K)]
[Times: user=3.23 sys=0.00, real=4.72 secs]
→ StreamSets 에서 Full GC 로 인해 4.72 초 동안 응답을 받을 수 없는 상태가 됨 (Full GC 완료 시간: 22:06:27.355 )
StreamSets Full GC
W0902 22:06:24.973554 6451 negotiation.cc:313] Failed RPC negotiation. Trace:
0902 22:06:21.973423 (+ 0us) reactor.cc:583] Submitting negotiation task for server connection from 10.13.17.47:44242
0902 22:06:21.973472 (+ 49us) server_negotiation.cc:176] Beginning negotiation
0902 22:06:21.973474 (+ 2us) server_negotiation.cc:365] Waiting for connection header 0902 22:06:22.240971 (+267497us) server_negotiation.cc:373] Connection header received
0902 22:06:24.973500 (+2732529us) negotiation.cc:304] Negotiation complete: Timed out: Server
동일한 시간대 Kudu Tablet Server 의 Negotiation failed Trace
조금이라도 도움이 되셨음
좋겠습니다.
그냥가면 아쉽겠죠?
정말 소소한 Tip을 준비했습
니다.
Kudu 운영 시 유용한 Chart 모음
"title":"Table별 Tablet size on disk ","tsquery":"select total_kudu_on_disk_size_across_kudu_replicas where category=KUDU_TABLE and serviceName=\"kudu\""
"title":"TServer별 총 Tablet Size On Disk","tsquery":"select total_kudu_on_disk_size_across_kudu_replicas where category=ROLE and roleType=KUDU_TSERVER"
"title":"TServer Memory 사용(Total)","tsquery":"select mem_rss where hostname RLIKE \"<slave서버명>\" and roleType=KUDU_TSERVER"
"title":"TServer Memory 사용(Application)","tsquery":"SELECT kudu_generic_current_allocated_bytes where category=ROLE and roleType=KUDU_TSERVER"
"title":"Tablet Server의 pageheap freelist","tsquery":"select kudu_tcmalloc_pageheap_free_bytes where category=ROLE and roleType=KUDU_TSERVER"
"title":"RPC reqs rejected(Leader) - Mem Pressure","tsquery":"select 10, total_kudu_leader_memory_pressure_rejections_rate_across_kudu_replicas where hostname RLIKE \"<slave서버명>\" and roleType=KUDU_TSERVER"
"title":"RPC reqs rejected(Follower) - Mem Pressure","tsquery":"select 10, total_kudu_follower_memory_pressure_rejections_rate_across_kudu_replicas where hostname RLIKE \"<slave서버명>\" and roleType=KUDU_TSERVER"
"title":"TServer별 RPC queue overflow","tsquery":"select 100, kudu_rpcs_queue_overflow_rate WHERE roleType=KUDU_TSERVER AND category = ROLE"
"title":"TServer별 RPC queue timeout","tsquery":"select kudu_rpcs_timed_out_in_queue_rate WHERE roleType=KUDU_TSERVER AND category = ROLE"
"title":"Table별 Insert/Update/Delete/Upsert 워크로드","tsquery":"select total_kudu_rows_inserted_rate_across_kudu_replicas, total_kudu_rows_deleted_rate_across_kudu_replicas, total_kudu_rows_updated_rate_across_kudu_replicas,
total_kudu_rows_upserted_rate_across_kudu_replicas where category = KUDU_TABLE"
"title":"Total Insert/Update/Delete/Upsert워크로드","tsquery":"select total_kudu_rows_inserted_rate_across_kudu_replicas, total_kudu_rows_deleted_rate_across_kudu_replicas, total_kudu_rows_updated_rate_across_kudu_replicas, total_kudu_rows_upserted_rate_across_kudu_replicas where entityName=\"kudu\""
"title":"Total Scanner Bytes Scanned From Disk Across Kudu Replicas","tsquery":"select
total_kudu_scanner_bytes_scanned_from_disk_rate_across_kudu_replicas where entityName=\"kudu\""
"title":"Total Scanner Bytes Scanned From Table","tsquery":"SELECT total_kudu_scanner_bytes_scanned_from_disk_rate_across_kudu_replicas where category=KUDU_TABLE"
"title":"Tablet Server별 WAL Size On Disk","tsquery":"select capacity, capacity_used where mountpoint=\"<WAL 디스크명>\" and category=FILESYSTEM AND hostname RLIKE \"<slave서버명>\""
"title":"Cluster Network IO","tsquery":"select 10737418240, total_bytes_receive_rate_across_network_interfaces, total_bytes_transmit_rate_across_network_interfaces where category = CLUSTER"
"title":"Total DeltaMemStore Flush Duration: Total Across Kudu Replicas","tsquery":"select total_kudu_flush_dms_duration_sum_rate_across_kudu_replicas where category=KUDU_TABLE and serviceName=\"kudu\""
"title":"Cluster Disk IO","tsquery":"select 10737418240, total_read_bytes_rate_across_disks, total_write_bytes_rate_across_disks where category = CLUSTER and clusterName=\"cluster\""
"title":"Total MemRowSet Flush Duration: Total Across Kudu Replicas","tsquery":"select total_kudu_flush_mrs_duration_sum_rate_across_kudu_replicas where category=KUDU_TABLE"
"title":"전체 네트워크 프레임 오류","tsquery":"SELECT frame_receive_rate_across_network_interfaces"
"title":"Write RPC Time","tsquery":"select kudu_handler_latency_kudu_tserver_tabletserverservice_write_sum_rate where category=ROLE and roleType=KUDU_TSERVER"
"title":"Bloom Lookups","tsquery":"SELECT total_kudu_bloom_lookups_per_op_sum_rate_across_kudu_replicas WHERE category = KUDU_TABLE"
"title":"Compact Rowsets Duration","tsquery":"SELECT total_kudu_compact_rs_duration_sum_rate_across_kudu_replicas WHERE category = KUDU_TABLE"
Cloudera Manager Dashboard for Kudu
사용시 유의점: Query 시 가용 네트워크 리소스 고려, Query에 대한 explain 확인 필요. ad-hoc query 가 많지 않은 테이블 등등.