HBase 테이블에 TTL 을 걸었는데 데이터가 지워지지 않는다. TTL 을 바꾸려고 alter 를 실행하면 Unknown argument ignored: TTL 이 나온다. TTL 이 지난 데이터가 디스크 사용량에서 줄어들지 않는다.
TTL 은 테이블 속성이 아니라 컬럼 패밀리(column family) 속성이며 단위는 초다. alter 명령에서 TTL 을 컬럼 패밀리 해시 밖에 두면 HBase 셸이 그 인자를 테이블 속성으로 해석하려다 실패하고 Unknown argument ignored: TTL 을 출력한 뒤 아무것도 바꾸지 않는다. 이 메시지는 버전 문제가 아니라 문법 문제다.
create 'my_table', { NAME => 'cf1', TTL => 604800 }
alter 'my_table', { NAME => 'cf1', TTL => 86400 }
describe 'my_table'
컬럼 패밀리가 여러 개면 패밀리마다 따로 alter 를 실행한다. 지정하지 않으면 기본값은 FOREVER(2147483647초)이므로 만료되지 않는다.
셀 하나에만 TTL 을 주려면 put 의 마지막 해시 인자로 TTL 을 넘긴다. 단위는 밀리초다.
put 'my_table', 'row1', 'cf1:col1', 'value1', { TTL => 60000 }
put 'my_table', 'row1', 'cf1:col1', 'value1', 300 처럼 다섯 번째에 숫자를 그냥 두면 그것은 TTL 이 아니라 타임스탬프로 해석된다. 이 형태로 TTL 을 주려다 1970년대 타임스탬프를 가진 셀을 만들어 버리는 사고가 잦다.
TTL 이 지난 셀은 get 과 scan 결과에서 즉시 사라진다. 읽기 경로에서 걸러내기 때문이다. 그러나 HFile 안의 실제 바이트는 남아 있으며, major compaction 이 돌아야 물리적으로 제거된다. 디스크 사용량이 줄지 않는 이유가 이것이다.
| 구분 | minor compaction | major compaction |
|---|---|---|
| 대상 | 작은 HFile 여러 개 | 스토어의 모든 HFile |
| TTL 만료분 제거 | 부분적 | 제거 |
| 삭제 마커 정리 | 하지 않음 | 정리 |
| 부하 | 낮음 | 높음 |
major_compact 'my_table'
major_compact 'my_table', 'region_name'
compaction_state 'my_table'
자동 major compaction 주기는 hbase.hregion.majorcompaction 이며 기본값은 604800000ms(7일)이다. 1일(86400000)이라고 적힌 자료가 많은데 그것은 HBase 0.94 이전 기준이다. 값을 0 으로 두면 자동 major compaction 을 끄고 운영자가 배치로 직접 돌린다는 뜻이며, 이 경우 TTL 만료분은 수동 실행 전까지 디스크에 남는다.
<property>
<name>hbase.hregion.majorcompaction</name>
<value>604800000</value>
</property>
describe 'table' 로 TTL 이 실제로 반영됐는지 먼저 본다. alter 가 조용히 무시됐을 수 있다. 다음으로 단위를 확인한다. 컬럼 패밀리는 초, 셀은 밀리초이므로 TTL => 1 은 1초이지 1일이 아니다. 셀 타임스탬프도 본다. 적재할 때 타임스탬프를 직접 넣는 파이프라인이라면 미래 시각이 찍혀 만료되지 않을 수 있으므로 scan 출력의 timestamp= 값을 epoch milliseconds 로 해석해 확인한다. 여기까지 정상이면 major_compact 로 물리 삭제를 강제하고, 그래도 용량이 줄지 않으면 archive 디렉터리에 걸려 있는지 확인한다.
major compaction 은 스토어의 모든 HFile 을 다시 쓰므로 디스크 I/O 와 네트워크를 크게 먹는다. 운영 시간대에 전체 테이블을 대상으로 돌리면 읽기 지연이 눈에 띄게 늘어난다. 테이블이 크면 리전 단위로 나눠 돌린다.