DEV Community

Tarık Anafarta for Açıklab

Posted on Edited on

Kubernetes Üzerinde Az Veri İçeren Veritabanı İçin PostgreSQL ve TimescaleDB Storage Kıyaslaması

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 kubectl eriş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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Kurulum:

helm install postgres bitnami/postgresql   -n database   -f postgres-values.yaml
Enter fullscreen mode Exit fullscreen mode

Pod'un ayağa kalkmasını bekleyelim:

kubectl get pods -n database -w
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Kurulum:

helm install timescaledb timescaledb/timescaledb-single   -n database   -f timescaledb-values.yaml
Enter fullscreen mode Exit fullscreen mode

Pod'un ayağa kalkmasını bekleyelim:

kubectl get pods -n database -w
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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_pg normal tablo olacak
  • TimescaleDB'de sensor_ts hypertable 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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

TimescaleDB

postgres=# SELECT count(*) FROM sensor_ts;
 count 
-------
  1441
(1 row)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

TimescaleDB (sensor_ts)

 table_only | indexes | total  
------------+---------+--------
 112 kB     | 72 kB   | 184 kB
(1 row)
Enter fullscreen mode Exit fullscreen mode

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)