# 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**: 메모리 절약 우선 (검색 속도 느림)