plantpulse-storage (스토리지 계층)
역할
PlantPulse 의 모든 데이터를 영구 저장하는 계층입니다. 데이터 종류에 따라 4개의 전문화된 엔진을 단일 모듈로 묶어 운영합니다. pd 의 기동 순서에서 첫 번째이고, 안 뜨면 뒤의 모든 서비스가 시도되지 않는 문지기입니다.
| 항목 | 값 |
|---|---|
| 모듈명 | plantpulse-storage |
| 설치 경로 | /opt/kopens/plantpulse-platform/plantpulse-storage/ |
| 데이터 위치 | /data1/pp-data/ (PP_DATA_DIR, 볼륨 pp-data) |
| 백업 위치 | /data1/pp-backup/ (PP_BACKUP_DIR, 볼륨 pp-backup) |
pd 서비스 | storage — MASTER · WORKER 모두 (MinIO 는 MASTER 만) |
| 기동 순서 안에서 | valkey → postgres → cassandra → minio |
구성
디렉토리 구조
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 가 기동하지 않습니다
conf/ 아래 파일은 전부 생성물입니다. 고치는 자리는 호스트의 /etc/kopens/conf/*.template 입니다 → 설정 바꾸는 법
각 엔진
Cassandra — 시계열 · 이벤트
| 항목 | 값 |
|---|---|
| 포트 | 9042 (CQL) · 7000/7001 (노드 간) · 7099 (JMX) |
| 키스페이스 | pp (PP_KEYSPACE) |
| 계정 | cassandra (PP_CASSANDRA_USER) / PP_CASSANDRA_PASSWORD — PasswordAuthenticator |
| 설정 | cassandra.yaml.template · jvm-server.options.template (WORKER 는 cluster/ 판) |
| 광고 주소 | broadcast_rpc_address — 127.0.0.1 이면 렌더가 거부합니다 |
대표 테이블: pp.ts_data_points(시계열 엔진의 데이터 포인트, 행마다 TTL), pp.tm_tag_point · tm_tag_point_archive · tm_tag_point_snapshot(태그), pp.tm_asset_data(에셋), pp.tw_*(콜드 티어로 옮긴 것의 기록). 테이블별 TTL · 압축 전략 · 크기는 pd retention 이 보여 줍니다.
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 # 파괴적 — 스냅샷 삭제
| 튜닝 포인트 | 템플릿 | 권장 |
|---|---|---|
| 힙 | jvm-server.options.template | 호스트 메모리의 1/4, 최대 32GB |
compaction_throughput | cassandra.yaml.template | 128 MB/s (NVMe) / 16 MB/s (HDD) |
concurrent_compactors | cassandra.yaml.template | min(코어 수, 8) |
Cassandra Reaper 는 이미지 tools/reaper/ 에 들어 있지만 pd 가 기동하지 않는 수동 도구입니다. 정기 repair 는 pd node repair 로 합니다.
PostgreSQL — 메타데이터
| 항목 | 값 |
|---|---|
| 포트 | 5432 |
| 데이터베이스 | pp (PP_DB_NAME) — 그 밖에 temporal · temporal_visibility · kestra · hive-metastore-230 |
| 계정 | plantpulse / PP_PG_PASSWORD. 역할 temporal · hive · gravitino · kestra · replica 도 여기에 |
| 인증 | scram-sha-256 (pg_hba.conf.template) |
| 설정 | postgresql.conf.template · pg_hba.conf.template |
첫 부팅 때 스키마와 역할이 비밀번호 없이 만들어지고, pd 가 사이드카 값으로 역할 비밀번호를 맞춥니다(부팅마다 ALTER ROLE — 멱등). 그래서 PP_GRAVITINO_PASSWORD · PP_KESTRA_DB_PASSWORD 처럼 회전 도구가 다루지 않는 PostgreSQL 계정은 사이드카를 고치고 재시작하면 됩니다.
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 # 논리 덤프
| 튜닝 포인트 | 권장 |
|---|---|
shared_buffers | 호스트 메모리의 25% |
effective_cache_size | 50 ~ 75% |
max_connections | 200 (대규모 500) |
max_slot_wal_keep_size | 상한을 두세요 — 제거된 워커의 슬롯이 WAL 을 무한정 붙잡는 것을 막습니다(이미지 기본 8GB) |
Valkey — 인메모리 캐시
| 항목 | 값 |
|---|---|
| 포트 | 6379 (평문) · 6380 (TLS) |
| 계정 | redis (PP_REDIS_USER) / PP_REDIS_PASSWORD — requirepass |
| 설정 | valkey.conf.template (WORKER 는 cluster/ 판 — replicaof 마스터) |
| 로그 | /data1/pp-data/valkey/logs/system.log — 데이터 볼륨 아래입니다 |
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 — 오브젝트 스토리지
| 항목 | 값 |
|---|---|
| 포트 | 9000 (S3 API — pd 가 감시) · 9001 (콘솔 — 사람이 여는 화면) |
| 계정 | minio (PP_MINIO_USER) / PP_MINIO_PASSWORD — 기동 env MINIO_ROOT_* 로 주입 |
| 기본 버킷 | plantpulse (PP_MINIO_BUCKET). Iceberg 데이터 · 백업 · 첨부 |
| 콘솔 | http://<서버IP>:9001/ — 로그인은 위 계정과 같은 값 |
MinIO 는 MASTER 노드에서만 뜹니다. mc 클라이언트가 이미지에 있고 기동 스크립트가 pp-minio 별칭을 등록합니다.
통합 운영
docker exec plantpulse-datalake pd status storage # 넷의 UP/DOWN
docker exec plantpulse-datalake pd restart storage # 넷 전부 — 의존하는 모든 서비스가 연결을 잃습니다
docker exec plantpulse-datalake pd storage # 볼륨 · WAL · 슬롯 · 스냅샷 · 크기
storage 만 재시작하면 위의 전부가 끊깁니다가능하면 호스트의 restart-datalake.sh 로 데이터레이크 전체를 재시작하세요. 의존 앱 판정까지 해 줍니다 → 시작 · 정지 · 재시작
백업 / 복구
| 엔진 | 도구 | 방식 |
|---|---|---|
| PostgreSQL | pgBackRest (물리) · pg_dump (논리) | full / diff · 시점 복구 |
| Cassandra | Medusa | full / diff 스냅샷 |
| MinIO | mc mirror | 외부 S3 복제 |
절차는 백업 · 복원에 있습니다.
자주 발생하는 문제
| 증상 | 원인 | 조치 |
|---|---|---|
Cassandra WriteTimeout | 디스크 I/O 포화 | pd node compactionstats, throughput 조정 |
| Cassandra 노드 down | 네트워크 · 디스크 · OOM | pd logs storage 의 GC pause, 호스트 dmesg |
PostgreSQL Too many connections | 연결 풀 누수 | max_connections 상향 + 애플리케이션 풀 점검 |
| WAL 이 계속 자람 | 제거된 워커의 복제 슬롯 | pd storage 의 slot.orphan → 호스트 ops-check.sh --reclaim |
| Valkey 메모리 부족 | maxmemory-policy 미설정 | allkeys-lru 또는 volatile-lru |
| MinIO 디스크 가득 | Iceberg · 백업 누적 | 콘솔 9001 에서 라이프사이클 정책 |
| 재시작 후 응답 지연 | Cassandra warmup | 정상 (3 ~ 5분) |
디스크 레이아웃 권장
/data1/
├── pp-data/ # 데이터 볼륨 (NVMe SSD)
│ ├── cassandra/ # SSTable · commitlog · saved_caches
│ ├── postgres/ # data · dump
│ ├── minio/
│ ├── valkey/
│ └── kafka/
├── pp-temp/
└── pp-backup/ # pgbackrest · medusa
Cassandra commitlog 과 data 를 별도 디스크(또는 별도 LV)로 분리하면 쓰기 처리량이 크게 오릅니다.