Kubernetes에서 소량 데이터베이스를 위한 PostgreSQL 및 TimescaleDB 스토리지 비교
Source: Dev.to
목적
Kubernetes에서 두 개의 별도 설치를 수행하여 (vanilla PostgreSQL + TimescaleDB) 작은 데이터 세트로 스토리지 사용량을 비교합니다.
참고: TimescaleDB는 이미 PostgreSQL 위에서 동작합니다. 여기서 “TimescaleDB 설치”라고 하는 것은 PostgreSQL + Timescale 확장이 포함된 별도 설치를 의미합니다. “Vanilla PostgreSQL”도 설치하여 결과를 더 명확히 합니다.
전제 조건
- 작동 중인 Kubernetes 클러스터와
kubectl접근 권한 - Helm
- 설치는 단일 노드 클러스터에서 수행되었으며
StorageClasslocal‑path입니다.
1. 단계 – 설치
1.1 네임스페이스
kubectl create namespace database
1.2 Helm 저장소
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add timescaledb https://charts.timescale.com
helm repo update
2단계 – Vanilla PostgreSQL (Bitnami) 설치
postgres-values.yaml 생성
# postgres-values.yaml içeriği burada tanımlanacak
주의: 두 개의 별도 pod에 연결합니다. 동일한 작업을 두 개의 다른 DB 설치에서도 실행할 것입니다.
5. 단계 – 작은 데이터 세트로 테스트
아래 SQL을 두 환경 모두에서 적용합니다:
- PostgreSQL에서는
sensor_pg가 일반 테이블이 됩니다. - TimescaleDB에서는
sensor_ts가 하이퍼테이블이 됩니다.
데이터를 적게 만들기 위해 1일을 생성합니다.
5.1 PostgreSQL
psql 안에서:
CREATE TABLE sensor_pg (
time TIMESTAMPTZ NOT NULL,
device_id INT,
temperature FLOAT
);
CREATE INDEX sensor_pg_time_idx ON sensor_pg(time);
INSERT INTO sensor_pg
SELECT
generate_series(NOW() - INTERVAL '1 day', NOW(), INTERVAL '1 minute'),
(random() * 10)::int,
random() * 100;
SELECT count(*) FROM sensor_pg;
5.2 TimescaleDB
psql 안에서:
CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE TABLE sensor_ts (
time TIMESTAMPTZ NOT NULL,
device_id INT,
temperature FLOAT
);
SELECT create_hypertable('sensor_ts', 'time');
CREATE INDEX sensor_ts_time_idx ON sensor_ts(time);
INSERT INTO sensor_ts
SELECT
generate_series(NOW() - INTERVAL '1 day', NOW(), INTERVAL '1 minute'),
(random() * 10)::int,
random() * 100;
SELECT count(*) FROM sensor_ts;
참고: TimescaleDB에서 하이퍼테이블은 단일 테이블처럼 보이지만 백그라운드에서는 청크로 나뉩니다. 적은 데이터 테스트라도 최소 하나의 청크가 생성됩니다.
6. 단계 – 스토리지 측정
두 단계로 측정하여 보다 구체적인 결과를 얻습니다:
- Relation size (SQL 사용) – 테이블 + 인덱스 크기
- Data directory (파일시스템 사용) – 실제 디스크 사용량
6.1 PostgreSQL – SQL로 테이블 크기
SELECT
pg_size_pretty(pg_table_size('sensor_pg')) AS table_only,
pg_size_pretty(pg_indexes_size('sensor_pg')) AS indexes,
pg_size_pretty(pg_total_relation_size('sensor_pg')) AS total;
6.2 TimescaleDB – SQL로 hypertable (청크 단위) 크기
SELECT
pg_size_pretty(SUM(pg_table_size(chunk.id::regclass))) AS table_only,
pg_size_pretty(SUM(pg_indexes_size(chunk.id::regclass))) AS indexes,
pg_size_pretty(SUM(pg_total_relation_size(chunk.id::regclass))) AS total
FROM show_chunks('sensor_ts') AS chunk(id);
설명: Hypertable은 물리적으로 청크 테이블들로 구성됩니다; 따라서 실제 데이터 + 인덱스 크기는 청크들의 총합입니다.
7. 내 환경에서의 출력
PostgreSQL
postgres=# SELECT count(*) FROM sensor_pg;
count
-------
1441
(1 row)
TimescaleDB
postgres=# SELECT count(*) FROM sensor_ts;
count
-------
1441
(1 row)
(계속되는 측정 결과와 비교는 여기 추가할 수 있습니다.)
7.1 SQL (relation) 크기
PostgreSQL 내에서 테이블과 인덱스가 차지하는 공간.
PostgreSQL (sensor_pg)
table_only | indexes | total
------------+---------+--------
112 kB | 48 kB | 160 kB
(1 row)
TimescaleDB (sensor_ts)
table_only | indexes | total
------------+---------+--------
112 kB | 72 kB | 184 kB
(1 row)
table_only는 양쪽 모두 동일하지만 indexes 부분은 Timescale 쪽이 더 많습니다.
8. 왜 Timescale은 작은 데이터에서 더 크게 보일 수 있나요?
- TimescaleDB에서는 hypertable이 물리적으로 청크 테이블들로 구성됩니다. 각 청크는 자체 테이블/인덱스 구조를 가지고 있습니다.
- 작은 데이터 세트에서는 이 구조가 “오버헤드”로 더 눈에 띕니다.
결과: 데이터가 많지 않은 테이블 상황에서는, Timescale hypertable의 청크/인덱스 오버헤드 때문에 PostgreSQL이 약간 더 작게 보입니다.