Skip to main content

plantpulse-storage (Storage Layer)

Role

The layer that persistently stores all PlantPulse data. Four specialized engines are bundled into a single module, organized by data type. It is first in the startup sequence defined in pd, and acts as a gatekeeper — if it does not start, no subsequent services are attempted.

ItemValue
Module nameplantpulse-storage
Installation path/opt/kopens/plantpulse-platform/plantpulse-storage/
Data location/data1/pp-data/ (PP_DATA_DIR, volume pp-data)
Backup location/data1/pp-backup/ (PP_BACKUP_DIR, volume pp-backup)
pd servicestorage — both MASTER and WORKER (MinIO on MASTER only)
Startup ordervalkey → postgres → cassandra → minio

Architecture

Directory Structure

plantpulse-storage/
├── cache/valkey/ # conf/valkey.conf (생성물) · 로그는 /data1/pp-data/valkey/logs
├── db/
│ ├── cassandra/ # bin/ (cqlsh · nodetool) · conf/cassandra.yaml · jvm-server.options (생성물) · logs/
│ └── postgres/ # bin/ (psql · pg_ctl) · conf/postgresql.conf · pg_hba.conf (생성물) · logs/
├── object/
│ ├── minio/ # bin/ · logs/
│ ├── rustfs/ weedfs/ # 대안 오브젝트 스토어 — 이미지에 있지만 pd 가 기동하지 않습니다
├── graph/janusgraph/ # 그래프 DB — 이미지에 있지만 pd 가 기동하지 않습니다
└── tools/reaper/ # Cassandra Reaper — 이미지에 있지만 pd 가 기동하지 않습니다

All files under conf/ are generated artifacts. The place to modify is the host's /etc/kopens/conf/*.templateHow to Change Configuration

Each Engine

Cassandra — Time Series and Events

ItemValue
Port9042 (CQL) · 7000/7001 (inter-node) · 7099 (JMX)
Keyspacepp (PP_KEYSPACE)
Accountcassandra (PP_CASSANDRA_USER) / PP_CASSANDRA_PASSWORDPasswordAuthenticator
Configurationcassandra.yaml.template · jvm-server.options.template (WORKER uses cluster/ variant)
Advertised addressbroadcast_rpc_address — rendering fails if 127.0.0.1

Key tables: pp.ts_data_points (time series engine data points, per-row TTL), pp.tm_tag_point · tm_tag_point_archive · tm_tag_point_snapshot (tags), pp.tm_asset_data (assets), pp.tw_* (record of cold tier migrations). pd retention shows TTL, compaction strategy, and size per table.

docker exec plantpulse-datalake pd node status # 링 상태 — UN 이 정상
docker exec plantpulse-datalake pd node cql # cqlsh
docker exec plantpulse-datalake pd node errors # 최근 WARN/ERROR
docker exec plantpulse-datalake pd node compactionstats
docker exec plantpulse-datalake pd node repair # 무겁습니다
docker exec plantpulse-datalake pd node cleanup # 파괴적 — 스냅샷 삭제
Tuning PointTemplateRecommended
Heapjvm-server.options.template1/4 of host memory, max 32 GB
compaction_throughputcassandra.yaml.template128 MB/s (NVMe) / 16 MB/s (HDD)
concurrent_compactorscassandra.yaml.templatemin(코어 수, 8)

Cassandra Reaper is included in image tools/reaper/ but is a manual tool that pd does not start. Schedule repairs via pd node repair.

PostgreSQL — Metadata

ItemValue
Port5432
Databasepp (PP_DB_NAME) — others include temporal · temporal_visibility · kestra · hive-metastore-230
Accountplantpulse / PP_PG_PASSWORD. Roles temporal · hive · gravitino · kestra · replica also here
Authenticationscram-sha-256 (pg_hba.conf.template)
Configurationpostgresql.conf.template · pg_hba.conf.template

On first boot, schema and roles are created without passwords, and pd syncs role passwords via sidecar values (on every boot, ALTER ROLE — idempotent). Thus PostgreSQL accounts not handled by rotation tools like PP_GRAVITINO_PASSWORD · PP_KESTRA_DB_PASSWORD can be managed by editing the sidecar and restarting.

docker exec -it plantpulse-datalake pd node psql # postgres OS 사용자로 psql
docker exec plantpulse-datalake pd storage # WAL · 복제 슬롯 · max_slot_wal_keep_size
docker exec plantpulse-datalake pd backup # 논리 덤프
Tuning PointRecommended
shared_buffers25% of host memory
effective_cache_size50–75%
max_connections200 (500 for large deployments)
max_slot_wal_keep_sizeSet an upper limit — prevents replication slots from removed workers from holding WAL indefinitely (image default 8 GB)

Valkey — In-Memory Cache

ItemValue
Port6379 (plain) · 6380 (TLS)
Accountredis (PP_REDIS_USER) / PP_REDIS_PASSWORDrequirepass
Configurationvalkey.conf.template (WORKER uses cluster/ variant — replicaof master)
Log/data1/pp-data/valkey/logs/system.log — located under data volume
docker exec -it plantpulse-datalake bash -c '"$PP_HOME/tools/valkey/bin/valkey-cli" -h 127.0.0.1 -a "$PP_REDIS_PASSWORD"'
> INFO memory
> CONFIG GET maxmemory

MinIO — Object Storage

ItemValue
Port9000 (S3 API — monitored by pd) · 9001 (console — user-facing)
Accountminio (PP_MINIO_USER) / PP_MINIO_PASSWORD — injected via startup env MINIO_ROOT_*
Default bucketplantpulse (PP_MINIO_BUCKET). Iceberg data, backups, attachments
Consolehttp://<server-ip>:9001/ — login uses the same credentials as above

MinIO runs on MASTER nodes only. The mc client is in the image, and the startup script registers the pp-minio alias.

Unified Operations

docker exec plantpulse-datalake pd status storage # 넷의 UP/DOWN
docker exec plantpulse-datalake pd restart storage # 넷 전부 — 의존하는 모든 서비스가 연결을 잃습니다
docker exec plantpulse-datalake pd storage # 볼륨 · WAL · 슬롯 · 스냅샷 · 크기
Restarting only storage breaks everything above

When possible, restart the entire datalake via host restart-datalake.sh. It also determines dependent apps → Start · Stop · Restart

Backup / Recovery

EngineToolMethod
PostgreSQLpgBackRest (physical) · pg_dump (logical)full / diff · point-in-time recovery
CassandraMedusafull / diff snapshots
MinIOmc mirrorexternal S3 replication

Procedures are in Backup and Restore.

Common Issues

SymptomCauseAction
Cassandra WriteTimeoutdisk I/O saturationpd node compactionstats, adjust throughput
Cassandra node downnetwork · disk · OOMGC pause in pd logs storage, check host dmesg
PostgreSQL Too many connectionsconnection pool leakraise max_connections + inspect application pool
WAL grows continuouslyreplication slot from removed workerpd storageslot.orphan → restart host ops-check.sh --reclaim
Valkey out of memorymaxmemory-policy not setallkeys-lru or volatile-lru
MinIO disk fullIceberg · backup accumulationset lifecycle policy in console 9001
delayed response after restartCassandra warmupnormal (3–5 min)
/data1/
├── pp-data/ # 데이터 볼륨 (NVMe SSD)
│ ├── cassandra/ # SSTable · commitlog · saved_caches
│ ├── postgres/ # data · dump
│ ├── minio/
│ ├── valkey/
│ └── kafka/
├── pp-temp/
└── pp-backup/ # pgbackrest · medusa

Separating Cassandra commitlog and data onto separate disks (or separate LVs) significantly improves write throughput.