Amaç
Kubernetes üzerinde iki ayrı kurulum yapıp (vanilla PostgreSQL + TimescaleDB) küçük bir veri setiyle storage kullanımını kıyaslamak.
Not: TimescaleDB zaten PostgreSQL üzerinde çalışır. Burada "TimescaleDB kurulumu" dediğimiz şey, içinde PostgreSQL + Timescale extension bulunan ayrı bir kurulumdur. "vanilla PostgreSQL" de kuruyoruz ki sonuçlar daha net olsun.
Ön koşullar
- Çalışan bir Kubernetes cluster'ı ve
kubectlerişimi - Helm
- Kurulum tek node'lu bir cluster'da yapılmıştır ve StorageClass local-path'tir.
1. Aşama: Kurulum
1.1 Namespace
kubectl create namespace database
1.2 Helm repo'ları
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add timescaledb 'https://charts.timescale.com'
helm repo update
2. Aşama: Vanilla PostgreSQL (bitnami) kurulumu
postgres-values.yaml oluşturalım:
cat > postgres-values.yaml << 'EOF'
auth:
postgresPassword: "postgres123"
primary:
persistence:
storageClass: "local-path"
EOF
Kurulum:
helm install postgres bitnami/postgresql -n database -f postgres-values.yaml
Pod'un ayağa kalkmasını bekleyelim:
kubectl get pods -n database -w
3. Aşama: TimescaleDB kurulumu (Timescale chart)
timescaledb-values.yaml oluşturalım:
cat > timescaledb-values.yaml << 'EOF'
replicaCount: 1
image:
repository: timescale/timescaledb-ha
tag: pg14.6-ts2.9.1-p1
secrets:
credentials:
PATRONI_SUPERUSER_PASSWORD: "postgres123"
PATRONI_REPLICATION_PASSWORD: "replication123"
PATRONI_admin_PASSWORD: "admin123"
backup:
enabled: false
EOF
Kurulum:
helm install timescaledb timescaledb/timescaledb-single -n database -f timescaledb-values.yaml
Pod'un ayağa kalkmasını bekleyelim:
kubectl get pods -n database -w
4. Aşama: Bağlantı (2 ayrı terminal açabilirsiniz)
4.1 PostgreSQL’e bağlanma (Şifre: postgres123)
PGPOD="$(kubectl get pod -n database -l app.kubernetes.io/instance=postgres,app.kubernetes.io/name=postgresql -o name | head -n 1)"
kubectl exec -it -n database ${PGPOD} -- psql -U postgres
4.2 TimescaleDB’ye bağlanma (Şifre: postgres123)
MASTERPOD="$(kubectl get pod -o name --namespace database -l release=timescaledb,role=master)"
kubectl exec -it --namespace database ${MASTERPOD} -- psql -U postgres
Not: İki ayrı pod'a bağlanıyoruz. Aynı işlemleri iki farklı DB kurulumunda da çalıştırıyoruz.
5. Aşama: Küçük veri setiyle test
Aşağıdaki SQL'i iki tarafta da uygulayacağız:
- PostgreSQL'de
sensor_pgnormal tablo olacak - TimescaleDB'de
sensor_tshypertable olacak
Veri az olsun diye 30 gün yerine 1 gün üretiyoruz.
5.1 PostgreSQL:
PostgreSQL pod'unda psql içindeyken:
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:
TimescaleDB pod'unda psql içindeyken:
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;
Not: TimescaleDB'de hypertable tek tablo gibi görünür ama arkada chunk'lara ayrılır. Az veri testinde bile en azından bir chunk oluşur.
6. Aşama: Storage ölçümü
Bu işi iki seviyede ölçmek daha somut sonuçlar sağlar:
1) Relation size (SQL ile): tablo+index boyutları için
2) Data directory (filesystem ile): gerçek disk kullanımı için
6.1 PostgreSQL: SQL ile tablo boyutu
PostgreSQL pod'unda:
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 ile hypertable boyutu (chunk bazında)
TimescaleDB pod'unda:
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);
Chunk bazında bakmamızın nedeni hypertable fiziksel olarak chunk tablolardan oluşur. Yani gerçek data+index boyutu chunk'ların toplamıdır.
7. Benim ortamımdaki çıktı
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) boyutları
Tabloların ve indexlerin PostgreSQL içinde kapladığı alanlar.
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 iki tarafta da aynı iken indexes kısmı Timescale tarafında daha fazla.
8. Neden Timescale küçük veride daha büyük çıkabiliyor?
- TimescaleDB tarafında hypertable fiziksel olarak chunk tablolardan oluşur. Her chunk kendi tablo/index yapısını taşır.
- Küçük veri setlerinde bu yapı "overhead" olarak daha görünür olur.
Sonuç olarak üzerinde çok veri olmayan bir tablo senaryosunda, Timescale hypertable'ın chunk/index overhead'i yüzünden PostgreSQL biraz daha küçük göründü.
Top comments (0)