Kubernetes에서 소량 데이터베이스를 위한 PostgreSQL 및 TimescaleDB 스토리지 비교

발행: (2026년 3월 2일 오후 07:09 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

목적

Kubernetes에서 두 개의 별도 설치를 수행하여 (vanilla PostgreSQL + TimescaleDB) 작은 데이터 세트로 스토리지 사용량을 비교합니다.

참고: TimescaleDB는 이미 PostgreSQL 위에서 동작합니다. 여기서 “TimescaleDB 설치”라고 하는 것은 PostgreSQL + Timescale 확장이 포함된 별도 설치를 의미합니다. “Vanilla PostgreSQL”도 설치하여 결과를 더 명확히 합니다.

전제 조건

  • 작동 중인 Kubernetes 클러스터와 kubectl 접근 권한
  • Helm
  • 설치는 단일 노드 클러스터에서 수행되었으며 StorageClass local‑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. 단계 – 스토리지 측정

두 단계로 측정하여 보다 구체적인 결과를 얻습니다:

  1. Relation size (SQL 사용) – 테이블 + 인덱스 크기
  2. 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이 약간 더 작게 보입니다.

0 조회
Back to Blog

관련 글

더 보기 »

일이 정신 건강 위험이 될 때

markdown !Ravi Mishrahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fu...