Hierarchical Storage
Old windows are compressed into column-oriented chunks and moved to a side table, and SELECT reads them by
automatically merging them. Applications don't need to know whether data is compressed.
쓰기 ──▶ [ 핫 구간 ] ── hot_window 경과 ──▶ [ 콜드 청크 ] ── cold_window 경과 ──▶ 삭제
행 저장 <테이블>__chunks
◀────── SELECT 이 알아서 합친다 ──────▶
Configuration
The policy is set as a JSON string in the timeseries_tiering key of the table's extensions map.
ALTER TABLE pp.tm_tag_point WITH extensions = {
'timeseries_tiering': '{"hot_window":"2d","chunk_window":"1d","cold_window":"3650d","interval":"1h"}'
};
| Key | Required | Default | Description |
|---|---|---|---|
hot_window | Required | — | Rows younger than this age are left untouched. Must be chunk_window or higher |
chunk_window | 1h | Length of the re-encoding window. 1 chunk = 1 tag × 1 window | |
cold_window | None | Chunks older than this are deleted entirely. Must be greater than hot_window | |
consistency | LOCAL_QUORUM | CL used by the re-encoder. Quorum series only | |
interval | 5m | Re-encoding interval for this table |
Duration syntax follows <양의 정수><m|h|d>. Unknown keys or rule violations
(hot_window < chunk_window, cold_window <= hot_window, CL below the quorum, etc.) are rejected when ALTER TABLE occurs — not silently ignored.
The column type determines the encoding. double supports only ALP/ALP-RD, columns with no
value changes are handled as CONSTANT, and all-null columns as ALL_NULL, in O(1) regardless of row count.
Including a codec key in the policy JSON points to that key and is rejected.
Release
ALTER TABLE pp.tm_tag_point WITH extensions = {};
Only new encoding stops; data already in chunks continues to appear merged.
Operations
# 지금 즉시 한 사이클 (interval 무시)
nodetool retier <keyspace> <table>
# 정책이 걸린 모든 테이블의 상태
nodetool tieringstatus
The same content can be viewed via CQL.
SELECT * FROM system_views.timeseries_tiering;
tags_skipped is not 0This means the last completed cycle didn't encode everything up to the cutoff — so it's not as compressed
as other counters suggest. retier fails with a non-zero exit code if any tag was skipped.
Original rows are untouched, so no data is lost. Check the logs for the cause and re-run.
Statistics are node-local · in-memory and based on the last completed run — they reset on restart. On multiple nodes, each node re-encodes only the tags in its own primary token range, dividing the work.
Things to Know
- Cold data is immutable. Deletes are rejected for intervals already in chunks.
- Late-arriving rows are merged column by column.
- 🔴 Full-scan aggregations without a partition key return incorrect values on hierarchical tables. That path does not merge chunks. Send such queries to Spark SQL.
- The payload format is v4 only. If an old removed format is encountered,
SELECTwill fail, not silently skip — better than continuing to return results missing only historical data.
See Also
- Time Series Compaction (TSCS)
- Time Series Functions — still work as-is on compressed intervals