mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 19:36:23 +00:00
596 lines
12 KiB
Markdown
596 lines
12 KiB
Markdown
# pgvector Extension PostgreSQL 설치 가이드
|
|
|
|
## 개요
|
|
벡터 유사도 검색을 위한 pgvector extension이 포함된 PostgreSQL 데이터베이스 설치 가이드입니다.
|
|
|
|
---
|
|
|
|
## 1. 사전 요구사항
|
|
|
|
### 1.1 필수 확인 사항
|
|
- [ ] Kubernetes 클러스터 접속 가능 여부 확인
|
|
- [ ] Helm 3.x 이상 설치 확인
|
|
- [ ] kubectl 명령어 사용 가능 여부 확인
|
|
- [ ] 기본 StorageClass 존재 여부 확인
|
|
|
|
### 1.2 버전 정보
|
|
| 구성요소 | 버전 | 비고 |
|
|
|---------|------|------|
|
|
| PostgreSQL | 16.x | pgvector 0.5.0 이상 지원 |
|
|
| pgvector Extension | 0.5.1+ | 최신 안정 버전 권장 |
|
|
| Helm Chart | bitnami/postgresql | pgvector 포함 커스텀 이미지 |
|
|
|
|
---
|
|
|
|
## 2. 설치 방법
|
|
|
|
### 2.1 Kubernetes 환경 (Helm Chart)
|
|
|
|
#### 2.1.1 개발 환경 (dev)
|
|
|
|
**Step 1: Namespace 생성**
|
|
```bash
|
|
kubectl create namespace vector-dev
|
|
```
|
|
|
|
**Step 2: Helm Repository 추가**
|
|
```bash
|
|
helm repo add bitnami https://charts.bitnami.com/bitnami
|
|
helm repo update
|
|
```
|
|
|
|
**Step 3: values.yaml 작성**
|
|
```yaml
|
|
# values-pgvector-dev.yaml
|
|
global:
|
|
postgresql:
|
|
auth:
|
|
postgresPassword: "dev_password"
|
|
username: "vector_user"
|
|
password: "dev_vector_password"
|
|
database: "vector_db"
|
|
|
|
image:
|
|
registry: docker.io
|
|
repository: pgvector/pgvector
|
|
tag: "pg16"
|
|
pullPolicy: IfNotPresent
|
|
|
|
primary:
|
|
initdb:
|
|
scripts:
|
|
init-pgvector.sql: |
|
|
-- pgvector extension 활성화
|
|
CREATE EXTENSION IF NOT EXISTS vector;
|
|
|
|
-- 설치 확인
|
|
SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';
|
|
|
|
resources:
|
|
limits:
|
|
memory: 2Gi
|
|
cpu: 1000m
|
|
requests:
|
|
memory: 1Gi
|
|
cpu: 500m
|
|
|
|
persistence:
|
|
enabled: true
|
|
size: 10Gi
|
|
storageClass: "" # 기본 StorageClass 사용
|
|
|
|
service:
|
|
type: ClusterIP
|
|
ports:
|
|
postgresql: 5432
|
|
|
|
metrics:
|
|
enabled: true
|
|
serviceMonitor:
|
|
enabled: false
|
|
|
|
volumePermissions:
|
|
enabled: true
|
|
```
|
|
|
|
**Step 4: Helm 설치 실행**
|
|
```bash
|
|
helm install pgvector-dev bitnami/postgresql \
|
|
--namespace vector-dev \
|
|
--values values-pgvector-dev.yaml \
|
|
--wait
|
|
```
|
|
|
|
**Step 5: 설치 확인**
|
|
```bash
|
|
# Pod 상태 확인
|
|
kubectl get pods -n vector-dev
|
|
|
|
# 서비스 확인
|
|
kubectl get svc -n vector-dev
|
|
|
|
# pgvector 설치 확인
|
|
kubectl exec -it pgvector-dev-postgresql-0 -n vector-dev -- \
|
|
psql -U vector_user -d vector_db -c "SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';"
|
|
```
|
|
|
|
**예상 출력:**
|
|
```
|
|
extname | extversion
|
|
---------+------------
|
|
vector | 0.5.1
|
|
(1 row)
|
|
```
|
|
|
|
#### 2.1.2 운영 환경 (prod)
|
|
|
|
**Step 1: Namespace 생성**
|
|
```bash
|
|
kubectl create namespace vector-prod
|
|
```
|
|
|
|
**Step 2: values.yaml 작성 (고가용성 구성)**
|
|
```yaml
|
|
# values-pgvector-prod.yaml
|
|
global:
|
|
postgresql:
|
|
auth:
|
|
postgresPassword: "CHANGE_ME_PROD_PASSWORD"
|
|
username: "vector_user"
|
|
password: "CHANGE_ME_VECTOR_PASSWORD"
|
|
database: "vector_db"
|
|
|
|
image:
|
|
registry: docker.io
|
|
repository: pgvector/pgvector
|
|
tag: "pg16"
|
|
pullPolicy: IfNotPresent
|
|
|
|
architecture: replication # 고가용성 구성
|
|
|
|
primary:
|
|
initdb:
|
|
scripts:
|
|
init-pgvector.sql: |
|
|
-- pgvector extension 활성화
|
|
CREATE EXTENSION IF NOT EXISTS vector;
|
|
|
|
-- 성능 최적화 설정
|
|
ALTER SYSTEM SET shared_buffers = '2GB';
|
|
ALTER SYSTEM SET effective_cache_size = '6GB';
|
|
ALTER SYSTEM SET maintenance_work_mem = '512MB';
|
|
ALTER SYSTEM SET max_wal_size = '2GB';
|
|
|
|
-- pgvector 최적화
|
|
ALTER SYSTEM SET max_parallel_workers_per_gather = 4;
|
|
|
|
resources:
|
|
limits:
|
|
memory: 8Gi
|
|
cpu: 4000m
|
|
requests:
|
|
memory: 4Gi
|
|
cpu: 2000m
|
|
|
|
persistence:
|
|
enabled: true
|
|
size: 100Gi
|
|
storageClass: "" # 기본 StorageClass 사용
|
|
|
|
podAntiAffinity:
|
|
preset: hard # Primary와 Replica 분리 배치
|
|
|
|
readReplicas:
|
|
replicaCount: 2
|
|
|
|
resources:
|
|
limits:
|
|
memory: 8Gi
|
|
cpu: 4000m
|
|
requests:
|
|
memory: 4Gi
|
|
cpu: 2000m
|
|
|
|
persistence:
|
|
enabled: true
|
|
size: 100Gi
|
|
|
|
backup:
|
|
enabled: true
|
|
cronjob:
|
|
schedule: "0 2 * * *" # 매일 새벽 2시 백업
|
|
storage:
|
|
size: 50Gi
|
|
|
|
metrics:
|
|
enabled: true
|
|
serviceMonitor:
|
|
enabled: true
|
|
|
|
networkPolicy:
|
|
enabled: true
|
|
allowExternal: false
|
|
```
|
|
|
|
**Step 3: Helm 설치 실행**
|
|
```bash
|
|
helm install pgvector-prod bitnami/postgresql \
|
|
--namespace vector-prod \
|
|
--values values-pgvector-prod.yaml \
|
|
--wait
|
|
```
|
|
|
|
**Step 4: 설치 확인**
|
|
```bash
|
|
# 모든 Pod 상태 확인 (Primary + Replicas)
|
|
kubectl get pods -n vector-prod
|
|
|
|
# Replication 상태 확인
|
|
kubectl exec -it pgvector-prod-postgresql-0 -n vector-prod -- \
|
|
psql -U postgres -c "SELECT * FROM pg_stat_replication;"
|
|
```
|
|
|
|
---
|
|
|
|
### 2.2 Docker Compose 환경 (로컬 개발)
|
|
|
|
**docker-compose.yml**
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
pgvector:
|
|
image: pgvector/pgvector:pg16
|
|
container_name: pgvector-local
|
|
environment:
|
|
POSTGRES_DB: vector_db
|
|
POSTGRES_USER: vector_user
|
|
POSTGRES_PASSWORD: local_password
|
|
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
|
|
ports:
|
|
- "5432:5432"
|
|
volumes:
|
|
- pgvector_data:/var/lib/postgresql/data
|
|
- ./init-scripts:/docker-entrypoint-initdb.d
|
|
command:
|
|
- "postgres"
|
|
- "-c"
|
|
- "shared_buffers=256MB"
|
|
- "-c"
|
|
- "max_connections=200"
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U vector_user -d vector_db"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
pgvector_data:
|
|
driver: local
|
|
```
|
|
|
|
**init-scripts/01-init-pgvector.sql**
|
|
```sql
|
|
-- pgvector extension 활성화
|
|
CREATE EXTENSION IF NOT EXISTS vector;
|
|
|
|
-- 테스트 테이블 생성 (선택사항)
|
|
CREATE TABLE IF NOT EXISTS vector_test (
|
|
id SERIAL PRIMARY KEY,
|
|
content TEXT,
|
|
embedding vector(384) -- 384차원 벡터 (예시)
|
|
);
|
|
|
|
-- 인덱스 생성 (HNSW - 고성능)
|
|
CREATE INDEX ON vector_test
|
|
USING hnsw (embedding vector_cosine_ops);
|
|
|
|
-- 확인 쿼리
|
|
SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';
|
|
```
|
|
|
|
**실행 명령**
|
|
```bash
|
|
# 시작
|
|
docker-compose up -d
|
|
|
|
# 로그 확인
|
|
docker-compose logs -f pgvector
|
|
|
|
# 접속 테스트
|
|
docker exec -it pgvector-local psql -U vector_user -d vector_db
|
|
|
|
# 종료
|
|
docker-compose down
|
|
```
|
|
|
|
---
|
|
|
|
## 3. 설치 검증
|
|
|
|
### 3.1 Extension 설치 확인
|
|
```sql
|
|
-- Extension 버전 확인
|
|
SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';
|
|
|
|
-- 지원 연산자 확인
|
|
SELECT oprname, oprleft::regtype, oprright::regtype
|
|
FROM pg_operator
|
|
WHERE oprname IN ('<=>', '<->', '<#>');
|
|
```
|
|
|
|
**예상 결과:**
|
|
```
|
|
oprname | oprleft | oprright
|
|
---------+---------+----------
|
|
<=> | vector | vector
|
|
<-> | vector | vector
|
|
<#> | vector | vector
|
|
```
|
|
|
|
### 3.2 벡터 연산 테스트
|
|
```sql
|
|
-- 테스트 데이터 삽입
|
|
CREATE TABLE test_vectors (
|
|
id SERIAL PRIMARY KEY,
|
|
embedding vector(3)
|
|
);
|
|
|
|
INSERT INTO test_vectors (embedding) VALUES
|
|
('[1,2,3]'),
|
|
('[4,5,6]'),
|
|
('[1,1,1]');
|
|
|
|
-- 코사인 거리 계산 테스트
|
|
SELECT id, embedding, embedding <=> '[1,2,3]' AS cosine_distance
|
|
FROM test_vectors
|
|
ORDER BY cosine_distance
|
|
LIMIT 3;
|
|
```
|
|
|
|
### 3.3 인덱스 성능 테스트
|
|
```sql
|
|
-- HNSW 인덱스 생성
|
|
CREATE INDEX ON test_vectors USING hnsw (embedding vector_cosine_ops);
|
|
|
|
-- 인덱스 사용 여부 확인
|
|
EXPLAIN ANALYZE
|
|
SELECT id FROM test_vectors
|
|
ORDER BY embedding <=> '[1,2,3]'
|
|
LIMIT 10;
|
|
```
|
|
|
|
---
|
|
|
|
## 4. 연결 정보
|
|
|
|
### 4.1 Kubernetes 환경
|
|
|
|
**개발 환경 (cluster 내부)**
|
|
```
|
|
Host: pgvector-dev-postgresql.vector-dev.svc.cluster.local
|
|
Port: 5432
|
|
Database: vector_db
|
|
Username: vector_user
|
|
Password: dev_vector_password
|
|
```
|
|
|
|
**운영 환경 (cluster 내부)**
|
|
```
|
|
Host: pgvector-prod-postgresql.vector-prod.svc.cluster.local
|
|
Port: 5432
|
|
Database: vector_db
|
|
Username: vector_user
|
|
Password: CHANGE_ME_VECTOR_PASSWORD
|
|
```
|
|
|
|
**외부 접속 (Port-Forward)**
|
|
```bash
|
|
# 개발 환경
|
|
kubectl port-forward -n vector-dev svc/pgvector-dev-postgresql 5432:5432
|
|
|
|
# 운영 환경
|
|
kubectl port-forward -n vector-prod svc/pgvector-prod-postgresql 5433:5432
|
|
```
|
|
|
|
### 4.2 Docker Compose 환경
|
|
```
|
|
Host: localhost
|
|
Port: 5432
|
|
Database: vector_db
|
|
Username: vector_user
|
|
Password: local_password
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Python 연결 예제
|
|
|
|
### 5.1 필수 라이브러리
|
|
```bash
|
|
pip install psycopg2-binary pgvector
|
|
```
|
|
|
|
### 5.2 연결 코드
|
|
```python
|
|
import psycopg2
|
|
from pgvector.psycopg2 import register_vector
|
|
|
|
# 연결
|
|
conn = psycopg2.connect(
|
|
host="localhost",
|
|
port=5432,
|
|
database="vector_db",
|
|
user="vector_user",
|
|
password="local_password"
|
|
)
|
|
|
|
# pgvector 타입 등록
|
|
register_vector(conn)
|
|
|
|
# 벡터 검색 예제
|
|
cur = conn.cursor()
|
|
cur.execute("""
|
|
SELECT id, embedding <=> %s::vector AS distance
|
|
FROM test_vectors
|
|
ORDER BY distance
|
|
LIMIT 5
|
|
""", ([1, 2, 3],))
|
|
|
|
results = cur.fetchall()
|
|
for row in results:
|
|
print(f"ID: {row[0]}, Distance: {row[1]}")
|
|
|
|
cur.close()
|
|
conn.close()
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 트러블슈팅
|
|
|
|
### 6.1 Extension 설치 실패
|
|
```sql
|
|
-- 에러: extension "vector" is not available
|
|
-- 해결: pgvector 이미지 사용 확인
|
|
```
|
|
**확인 명령:**
|
|
```bash
|
|
# Pod의 이미지 확인
|
|
kubectl describe pod pgvector-dev-postgresql-0 -n vector-dev | grep Image
|
|
```
|
|
|
|
### 6.2 인덱스 생성 실패
|
|
```sql
|
|
-- 에러: operator class "vector_cosine_ops" does not exist
|
|
-- 해결: Extension 재생성
|
|
DROP EXTENSION vector CASCADE;
|
|
CREATE EXTENSION vector;
|
|
```
|
|
|
|
### 6.3 성능 이슈
|
|
```sql
|
|
-- 인덱스 통계 업데이트
|
|
ANALYZE test_vectors;
|
|
|
|
-- HNSW 파라미터 조정 (m=16, ef_construction=64)
|
|
CREATE INDEX ON test_vectors
|
|
USING hnsw (embedding vector_cosine_ops)
|
|
WITH (m = 16, ef_construction = 64);
|
|
```
|
|
|
|
---
|
|
|
|
## 7. 보안 권장사항
|
|
|
|
### 7.1 비밀번호 관리
|
|
```bash
|
|
# Kubernetes Secret 생성
|
|
kubectl create secret generic pgvector-credentials \
|
|
--from-literal=postgres-password='STRONG_PASSWORD' \
|
|
--from-literal=password='STRONG_VECTOR_PASSWORD' \
|
|
-n vector-prod
|
|
|
|
# values.yaml에서 참조
|
|
global:
|
|
postgresql:
|
|
auth:
|
|
existingSecret: "pgvector-credentials"
|
|
```
|
|
|
|
### 7.2 네트워크 정책
|
|
```yaml
|
|
# network-policy.yaml
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: NetworkPolicy
|
|
metadata:
|
|
name: pgvector-policy
|
|
namespace: vector-prod
|
|
spec:
|
|
podSelector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: postgresql
|
|
policyTypes:
|
|
- Ingress
|
|
ingress:
|
|
- from:
|
|
- namespaceSelector:
|
|
matchLabels:
|
|
name: vector-prod
|
|
- podSelector:
|
|
matchLabels:
|
|
app: vector-service
|
|
ports:
|
|
- protocol: TCP
|
|
port: 5432
|
|
```
|
|
|
|
---
|
|
|
|
## 8. 모니터링
|
|
|
|
### 8.1 Prometheus Metrics (운영 환경)
|
|
```yaml
|
|
# ServiceMonitor가 활성화된 경우 자동 수집
|
|
metrics:
|
|
enabled: true
|
|
serviceMonitor:
|
|
enabled: true
|
|
namespace: monitoring
|
|
interval: 30s
|
|
```
|
|
|
|
### 8.2 주요 메트릭
|
|
- `pg_up`: PostgreSQL 가용성
|
|
- `pg_database_size_bytes`: 데이터베이스 크기
|
|
- `pg_stat_database_tup_fetched`: 조회된 행 수
|
|
- `pg_stat_database_conflicts`: 복제 충돌 수
|
|
|
|
---
|
|
|
|
## 9. 백업 및 복구
|
|
|
|
### 9.1 수동 백업
|
|
```bash
|
|
# Kubernetes 환경
|
|
kubectl exec -n vector-prod pgvector-prod-postgresql-0 -- \
|
|
pg_dump -U vector_user vector_db > backup_$(date +%Y%m%d).sql
|
|
|
|
# Docker Compose 환경
|
|
docker exec pgvector-local pg_dump -U vector_user vector_db > backup.sql
|
|
```
|
|
|
|
### 9.2 복구
|
|
```bash
|
|
# Kubernetes 환경
|
|
cat backup.sql | kubectl exec -i pgvector-prod-postgresql-0 -n vector-prod -- \
|
|
psql -U vector_user -d vector_db
|
|
|
|
# Docker Compose 환경
|
|
cat backup.sql | docker exec -i pgvector-local psql -U vector_user -d vector_db
|
|
```
|
|
|
|
---
|
|
|
|
## 10. 참고 자료
|
|
|
|
- [pgvector GitHub](https://github.com/pgvector/pgvector)
|
|
- [PostgreSQL Documentation](https://www.postgresql.org/docs/16/)
|
|
- [Bitnami PostgreSQL Helm Chart](https://github.com/bitnami/charts/tree/main/bitnami/postgresql)
|
|
- [pgvector Performance Tips](https://github.com/pgvector/pgvector#performance)
|
|
|
|
---
|
|
|
|
## 부록: 차원별 인덱스 권장사항
|
|
|
|
| 벡터 차원 | 인덱스 타입 | 파라미터 | 비고 |
|
|
|----------|-----------|---------|------|
|
|
| < 768 | HNSW | m=16, ef_construction=64 | 일반적인 임베딩 |
|
|
| 768-1536 | HNSW | m=24, ef_construction=100 | OpenAI ada-002 |
|
|
| > 1536 | IVFFlat | lists=100 | 매우 높은 차원 |
|
|
|
|
**인덱스 선택 가이드:**
|
|
- **HNSW**: 검색 속도 우선 (메모리 사용량 높음)
|
|
- **IVFFlat**: 메모리 절약 우선 (검색 속도 느림)
|