tablet server 로그에 다음과 같은 메시지가 반복되거나, 기동 자체가 되지 않는다.
unable to read clock for last 73.342s: Service unavailable: Error reading clock. Clock considered unsynchronized
Service unavailable: clock error estimate (12345678us) too high (clock considered unsynchronized by the kernel)
Kudu 는 하이브리드 논리 시계(HybridClock)로 쓰기 연산에 타임스탬프를 부여하고, 그 타임스탬프로 스냅샷 읽기와 다중 태블릿 쓰기의 일관성을 판정한다. 타임스탬프는 물리 시각 부분과 논리 카운터 부분을 합친 값이므로 물리 시각이 흔들리면 일관성 판정 자체가 성립하지 않는다. 그래서 Kudu 는 커널이 보고하는 시각뿐 아니라 시각의 최대 오차 추정값(max error) 까지 읽어서, 그 값이 허용 범위를 넘으면 정상 동작을 포기하고 오류를 돌려준다.
이 판정은 "시각이 얼마나 틀렸는가" 가 아니라 "커널이 시각을 얼마나 믿을 수 있다고 보고하는가" 를 본다. 두 노드의 시각이 우연히 같아도 NTP 가 동기화되지 않은 상태면 오차 추정값이 크게 잡히므로 Kudu 는 거부한다.
| 플래그 | 기본값 | 의미 |
|---|---|---|
--time_source |
system(플랫폼에 따라 auto) |
시각 공급원. system(커널 NTP) · builtin(Kudu 내장 NTP 클라이언트) · auto · system_unsync(테스트 전용) · mock(테스트 전용) |
--max_clock_sync_error_usec |
10000000 (10초) | 허용하는 최대 시각 오차 추정값. 넘으면 Service unavailable |
--ntp_initial_sync_wait_secs |
60 | 기동 시 시각 동기화를 기다리는 시간. 0 이면 기다리지 않고 바로 실패 |
--builtin_ntp_servers |
환경에 따라 | --time_source=builtin 일 때 참조할 NTP 서버 |
system_unsync 와 mock 은 --unlock_unsafe_flags=true 없이는 기동이 거부된다. 운영 클러스터에서 "NTP 때문에 안 뜨니 검사를 끄자" 는 방향으로 가면 안 된다는 뜻이다.
timedatectl status
chronyc tracking
chronyc sources -v
ntpq -p
System clock synchronized: yes 와 NTP service: active 두 가지가 모두 나와야 한다. chrony 를 쓰면 chronyc tracking 의 System time 과 Root dispersion 값이 Kudu 가 보는 오차 추정과 직결된다.
서버 쪽에서는 웹 UI 메트릭으로 확인한다.
curl -s http://<tserver>:8050/metrics | grep -i hybrid_clock
hybrid_clock_error 가 --max_clock_sync_error_usec 에 근접하는지, hybrid_clock_extrapolating 이 true 로 올라가는지 본다. 후자는 커널에서 시각을 읽지 못해 마지막 성공 값으로 외삽(extrapolate)하고 있다는 뜻이고, 그 상태가 이어지면 오차가 누적되어 결국 거부 상태로 넘어간다.
먼저 chronyd 가 떠 있고 상위 시각원에 도달하는지 확인한다.
systemctl enable --now chronyd
chronyc makestep
chronyc sources -v
클러스터 전 노드가 같은 시각원을 보게 맞춘다. 서로 다른 상위 서버를 보면 각자는 동기화된 것으로 보이면서도 노드 간 편차가 남는다. 폐쇄망이면 내부에 NTP 서버를 두고 전 노드가 그것을 보게 한다.
unable to read clock for last N 처럼 시각을 아예 읽지 못하는 경우는 NTP 문제가 아니라 프로세스가 CPU 를 받지 못하거나 I/O 로 멈춰 있는 상황일 수 있다. 부하(uptime, iostat -x 1), 스왑 발생, 가상화 호스트의 시각 공급(kvm-clock 등)을 함께 본다.
--max_clock_sync_error_usec 를 키워서 기동시키는 것은 근본 조치가 아니다. 오차가 큰 상태로 쓰기를 받으면 스냅샷 읽기 결과가 어긋날 수 있다.chronyc makestep 은 서비스를 내린 상태에서 적용하는 편이 안전하다.