본문 바로가기
서버구축 (WEB,DB)

PostgreSQL 성능 향상 Performance Tuning & Optimization

by 날으는물고기 2023. 12. 15.

PostgreSQL 성능 향상 Performance Tuning & Optimization

PostgreSQL의 성능을 향상시키기 위해 다양한 튜닝 옵션을 사용할 수 있습니다. 다음은 PostgreSQL을 Docker Compose로 기본으로 올린 후 성능을 향상시키기 위한 몇 가지 일반적인 조치입니다.

  1. 컨테이너 자원 할당 조정
    • docker-compose.yml 파일에서 PostgreSQL 컨테이너에 할당된 자원을 적절하게 조정합니다. mem_limitcpus와 같은 옵션을 사용하여 메모리 및 CPU 제한을 설정할 수 있습니다.
      services:
        postgres:
          image: postgres:latest
          mem_limit: 2g
          cpus: 2
          ...
  2. PostgreSQL 설정 튜닝
    • PostgreSQL 설정을 변경하여 성능을 향상시킬 수 있습니다. PostgreSQL 컨테이너 내에서 postgresql.conf 파일을 수정하거나, 컨테이너 시작 시 환경 변수를 사용하여 설정 값을 변경할 수 있습니다.
    • 예를 들어, shared_buffers, work_mem, maintenance_work_mem 등의 설정을 조정할 수 있습니다.
  3. 데이터 디렉터리 분리
    • PostgreSQL 데이터 디렉터리를 호스트 시스템과 별도로 유지하면 성능이 향상될 수 있습니다. 호스트 시스템과 컨테이너 간의 파일 시스템 마운트를 사용하여 데이터를 유지할 수 있습니다.
  4. 인덱스 및 쿼리 튜닝
    • 테이블에 적절한 인덱스를 추가하고, 쿼리를 최적화하여 성능을 향상시킬 수 있습니다. 쿼리 실행 계획을 확인하고 인덱스를 효과적으로 활용할 수 있도록 쿼리를 작성합니다.
  5. 캐싱 활용
    • 컨테이너에 캐시를 적극적으로 사용하면 I/O 성능을 향상시킬 수 있습니다. 예를 들어, 데이터베이스 캐시 및 쿼리 결과 캐시를 활용할 수 있습니다.
  6. 컨테이너 네트워크 최적화
    • 컨테이너 간의 통신이 느릴 경우 네트워크 설정을 확인하고 최적화합니다. 예를 들어, 호스트 네트워크 대신 브리지 네트워크를 사용하거나, 컨테이너 간의 통신을 최소화합니다.
  7. Docker Volume 사용
    • 데이터 디렉터리를 Docker Volume을 사용하여 호스트 시스템과 공유하는 것이 효율적일 수 있습니다.

이러한 조치들은 각각의 상황에 따라 다르게 적용될 수 있습니다. 성능 튜닝은 상황에 따라 다르며, 실제로는 몇 가지 테스트를 통해 최적의 조합을 찾는 것이 중요합니다.

 

keepalive는 TCP 연결을 유지하는 데 사용되는 옵션으로, 일반적으로 커넥션의 지속성을 높일 수 있습니다. 그러나 이것이 항상 성능을 향상시킨다고 말할 수는 없습니다. 일반적으로는 커넥션을 재사용하는 데 유용하지만, 이것이 항상 원하는 성능 개선을 가져오지는 않을 수 있습니다.

 

TCP Keepalive 옵션은 커넥션의 유효성을 확인하고 필요한 경우 연결을 유지하는 데 사용됩니다. 이 설정은 연결이 활성 상태인지 확인하고 필요한 경우 연결을 유지하기 위해 사용됩니다. 다만, PostgreSQL과 같은 데이터베이스 시스템에서는 일반적으로 커넥션 풀링을 사용하여 연결을 효과적으로 관리하므로, keepalive를 조정하는 것이 성능 향상에 직접적으로 영향을 미칠 수 있는 경우는 상대적으로 적습니다.

 

만약 PostgreSQL의 성능을 향상시키고 싶다면, 앞서 언급한 것처럼 PostgreSQL 설정을 살펴보고 튜닝하는 것이 더 효과적일 수 있습니다. 특히 postgresql.conf 파일에서 shared_buffers, work_mem, effective_cache_size 등을 조정하여 성능을 최적화할 수 있습니다.

 

그렇다면 keepalive를 조정하려면, Kubernetes Secret으로 설정을 구성한 경우에는 해당 설정을 찾아서 변경하는 것이 필요합니다. 이 설정은 대부분 TCP 소켓 레벨에서 조정되므로, Kubernetes Secret에서 제공하는 PostgreSQL 연결 정보 이외에도 PostgreSQL 클라이언트 라이브러리 설정이나, 애플리케이션 레벨에서의 설정을 확인해야 할 수 있습니다. PostgreSQL 클라이언트 라이브러리에서는 일반적으로 keepalives_idle, keepalives_interval, keepalives_count 등의 옵션을 제공합니다.

 

다시 한번 강조하면, 성능 최적화는 상황에 따라 다르며 여러 요소가 조합되어 영향을 미칩니다. 특히 데이터베이스의 크기와 트래픽 패턴에 따라 최적의 설정을 찾기 위해 여러 가지 테스트가 필요합니다. keepalives 설정을 추가하려면 PostgreSQL 클라이언트 라이브러리의 구체적인 설정에 따라 매니페스트를 수정해야 합니다. PostgreSQL 클라이언트 라이브러리의 일반적인 설정 중 하나는 keepalives 설정이며, 이는 주로 connection string이나 PostgreSQL 클라이언트 라이브러리에서 직접 설정됩니다.

 

예를 들어, psycopg2 Python 라이브러리를 사용하는 경우, 다음과 같이 keepalives 옵션을 설정할 수 있습니다.

apiVersion: v1
kind: Secret
metadata:
  name: awx-pageskr-postgres-configuration
  namespace: awx
stringData:
  host: "postgres"
  port: "5432"
  database: "awx"
  username: "awx"
  password: "awx"
  sslmode: prefer
  type: unmanaged
  connection_options: "keepalives_idle=60 keepalives_interval=6 keepalives_count=5"
type: Opaque

위의 예에서는 connection_options라는 새로운 필드를 추가하여 PostgreSQL 연결 시 사용되는 추가 옵션을 정의했습니다. 이 옵션에는 keepalives_idle, keepalives_interval, keepalives_count 등의 TCP keepalive 관련 옵션을 설정할 수 있습니다. 이 값들은 각각 keepalive 시작 후 대기 시간, keepalive 간격 및 keepalive 실패 후 연결을 종료하기 전 시도 횟수를 나타냅니다.

 

PostgreSQL의 이중화(High Availability, HA)를 구성하는 것은 데이터베이스 시스템의 가용성을 향상시키는 중요한 과제 중 하나입니다. 이중화를 구성하면 하나의 노드가 실패해도 시스템이 계속 작동할 수 있습니다. PostgreSQL의 이중화를 위한 주요 방법으로는 스트리밍 복제와 레플리케이션을 이용한 방법이 있습니다.

 

다음은 PostgreSQL 이중화를 위한 기본적인 스트리밍 복제 구성 방법입니다. 이 예제에서는 PostgreSQL 13을 기준으로 설명합니다.

1. 스트리밍 복제 설정

  1. Master 노드 설정
    • PostgreSQL 설정 파일 (postgresql.conf)에서 스트리밍 복제를 활성화합니다.
      wal_level = replica
      max_wal_senders = 3
      archive_mode = on
      archive_command = 'cp %p /path/to/your/archive/%f'
  2. Master 노드와 슬레이브 노드 간의 연결 설정
    • pg_hba.conf 파일에서 마스터와 슬레이브 간의 연결을 허용합니다.
      host    replication     replicator     slave_ip/32      md5
  3. Slave 노드 설정
    • PostgreSQL 설정 파일 (postgresql.conf)에서 스트리밍 복제 설정을 추가합니다.여기서 master_ip, replicator, your_password는 각각 마스터의 IP 주소, 복제를 위한 사용자, 사용자의 패스워드를 나타냅니다.
      primary_conninfo = 'host=master_ip port=5432 user=replicator password=your_password'
  4. 슬레이브 노드 시작
    • PostgreSQL 서버를 시작하고 슬레이브 노드로 설정합니다.

2. 테스트

  1. 복제 상태 확인
    • 마스터 노드에서 pg_stat_replication 뷰를 사용하여 복제 상태를 확인합니다.
      SELECT * FROM pg_stat_replication;
  2. 테스트
    • 마스터 노드에 데이터를 추가하고 슬레이브 노드에서 해당 데이터가 동기화되는지 확인합니다.

3. 자동화와 모니터링

  1. 페일오버 (Failover) 스크립트 작성
    • 슬레이브가 마스터로 승격되는 페일오버 스크립트를 작성합니다.
  2. 모니터링
    • 클러스터의 상태를 지속적으로 모니터링하고, 페일오버나 장애 시에 적절한 조치를 취할 수 있도록 모니터링 도구를 도입합니다. 예를 들면 patroni, pgpool-II, 또는 기타 클러스터 관리 도구를 사용할 수 있습니다.

참고사항

  • 이중화를 구성할 때는 데이터의 일관성과 가용성을 고려해야 합니다. 데이터를 어떻게 백업하고, 페일오버가 어떻게 이루어지는지 등에 대한 계획이 필요합니다.
  • 이중화를 위한 도구나 플랫폼을 사용하는 것도 고려할 만합니다. 예를 들면, PostgreSQL Automatic Failover (PAF), Patroni, pgpool-II 등이 있습니다.
  • PostgreSQL 버전에 따라 설정이 약간 다를 수 있으므로, 해당 버전의 문서를 참고하는 것이 좋습니다.

 

Kubernetes (k8s)에서 애플리케이션을 확장하는 방법은 여러 가지가 있습니다. 주요 확장 방법 중 하나는 파드를 증가 또는 감소시켜 리소스를 동적으로 조정하는 것입니다. 이는 Kubernetes의 ReplicationController, ReplicaSet, 또는 Deployment와 같은 리소스 관리 객체를 사용하여 수행됩니다. 아래는 간단한 설명과 예제입니다.

ReplicaSet을 사용한 확장

1. ReplicaSet 생성

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: myapp-image

2. ReplicaSet 적용

kubectl apply -f myapp-replicaset.yaml

3. 스케일 아웃 (확장)

kubectl scale --replicas=5 replicaset myapp

Deployment를 사용한 확장

1. Deployment 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: myapp-image

2. Deployment 적용

kubectl apply -f myapp-deployment.yaml

3. 스케일 아웃 (확장)

kubectl scale --replicas=5 deployment myapp

Horizontal Pod Autoscaler (HPA)를 사용한 확장

1. HPA 설정

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 2
  maxReplicas: 5
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 80

2. HPA 적용

kubectl apply -f myapp-hpa.yaml

3. 자동 확장 테스트 (예를 들어 CPU 부하 생성)

kubectl run -i --tty load-generator --image=busybox /bin/sh
while true; do wget -q -O- http://myapp-service; done

위의 예제에서는 ReplicaSet, Deployment, Horizontal Pod Autoscaler를 사용하여 애플리케이션을 확장하는 방법을 보여주었습니다. 선택할 리소스 관리 객체 및 확장 방법은 상황에 따라 다를 수 있습니다. 이중화된 환경을 구성하거나 다른 확장 옵션을 고려하기 위해서는 클러스터의 특성 및 애플리케이션의 요구에 따라 적절한 방법을 선택하시기 바랍니다.

 

Kubernetes에서 PostgreSQL을 확장하는 또다른 방법입니다.

스트리밍 복제를 사용한 PostgreSQL 데이터베이스 복제

이 방법은 기본 PostgreSQL 스트리밍 복제를 사용하여 데이터베이스를 복제하는 방법입니다. 간단한 마스터-슬레이브 구성을 사용하여 가용성을 확보할 수 있습니다.

1. 마스터 Pod 및 슬레이브 Pod을 위한 YAML 파일 작성

# postgres-master.yaml
apiVersion: v1
kind: Pod
metadata:
  name: postgres-master
spec:
  containers:
  - name: postgres
    image: postgres:latest
    env:
      - name: POSTGRES_DB
        value: mydb
      - name: POSTGRES_USER
        value: myuser
      - name: POSTGRES_PASSWORD
        value: mypassword

# postgres-slave.yaml
apiVersion: v1
kind: Pod
metadata:
  name: postgres-slave
spec:
  containers:
  - name: postgres
    image: postgres:latest
    env:
      - name: POSTGRES_DB
        value: mydb
      - name: POSTGRES_USER
        value: myuser
      - name: POSTGRES_PASSWORD
        value: mypassword
      - name: POSTGRES_MASTER_HOST
        value: postgres-master
      - name: POSTGRES_MASTER_PORT
        value: "5432"
      - name: POSTGRES_MASTER_USER
        value: myuser
      - name: POSTGRES_MASTER_PASSWORD
        value: mypassword

2. 마스터와 슬레이브 Pod 배포

kubectl apply -f postgres-master.yaml
kubectl apply -f postgres-slave.yaml

Patroni를 사용한 PostgreSQL 클러스터링

Patroni는 PostgreSQL 클러스터를 관리하기 위한 오픈 소스 도구로, 이중화와 장애 조치(failover)를 관리합니다.

1. Patroni를 사용한 PostgreSQL 클러스터를 위한 YAML 파일 작성

# patroni.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
data:
  config.yaml: |-
    scope: patroni
    namespace: mynamespace
    name: mycluster
    restapi:
      listen: 0.0.0.0:8008
      connect_address: "{{ POD_IP }}"
    postgresql:
      listen: 0.0.0.0:5432
      data_dir: /data/patroni
      pgpass: /tmp/pgpass
      authentication:
        replication:
          username: myuser
          password: mypassword
        superuser:
          username: myuser
          password: mypassword
    bootstrap:
      dcs:
        ttl: 30
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 1048576
        postgresql:
          use_pg_rewind: true
          parameters:
            archive_mode: 'on'
            archive_command: 'exit 0'
            wal_level: hot_standby

2. Patroni 클러스터 배포

kubectl apply -f patroni.yaml

실제 환경에서는 Patroni의 설정을 변경하여 클러스터를 보다 안정적으로 운영할 수 있습니다. 클러스터의 상태를 확인하고 페일오버 테스트를 수행하여 Patroni가 제대로 동작하는지 확인하는 것이 좋습니다.

 

PostgreSQL을 클러스터링할 때는 데이터베이스 버전 및 설정에 주의해야 합니다. 또한, 클러스터를 운영하기 위한 백업 및 복구 전략을 구현하는 것도 중요합니다.

728x90

댓글