PostgreSQL에서 풀 크기와 데이터베이스 연결 간의 적절한 지점을 결정하는 방법


14

사용량이 많은 시간 동안 데이터베이스 서버에 대한 트래픽을 처리하는 데 문제가 있습니다. 우리는 하드웨어를 개선하기 위해 노력하고 있지만 ( 이 측면에 대한이 질문 참조 ) 풀링 구성 및 서버 조정 작업도 원합니다.

우리가 작업하고있는 애플리케이션은 스마트 폰을위한 턴 기반 멀티 플레이어 게임입니다. 백엔드는 레일스유니콘PostgreSQL 9.1 을 데이터베이스로 구성합니다. 현재 6 억 명의 등록 된 사용자가 있으며 게임 상태가 데이터베이스에 저장되므로 몇 초마다 수천 번의 쓰기가 수행됩니다. 우리는 PgBadger를 사용하여 PostgreSQL 의 로그 파일을 분석했으며 중요한 시간 동안 많은 것을 얻습니다.

FATAL: remaining connection slots are reserved for non-replication superuser connections

이 문제를 해결하는 순진한 해결책 은 postgresql.conf 에서 max_connections (현재 100) 를 늘리는 것 입니다. 나는 이것이 옳지 않을 수도 있음을 나타내는 http://wiki.postgresql.org/wiki/Number_Of_Database_Connections 를 읽었습니다 . 앞에서 언급 한 기사에서 max_connections와 pool size 사이의 스위트 스팟을 찾는 것을 언급했습니다 .

이 스위트 스팟을 찾기 위해 무엇을 할 수 있습니까? max_connections풀 크기 의 다른 값에 대한 I / O 성능을 측정 할 수있는 유용한 도구가 있습니까?

현재 설정은 4 개의 게임 서버이며 각 서버에는 16 명의 유니콘 작업자가 있고 수영장 크기는 5입니다.

우리가 사용하는 기본이 아닌 postgres 설정은 다음과 같습니다.

version                      | PostgreSQL 9.1.5 on x86_64-unknown-linux-gnu,compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
checkpoint_completion_target | 0.9
checkpoint_segments          | 60
checkpoint_timeout           | 6min
client_encoding              | UTF8
effective_cache_size         | 2GB
lc_collate                   | en_US.UTF-8
lc_ctype                     | en_US.UTF-8
log_destination              | csvlog
log_directory                | pg_log
log_filename                 | postgresql-%Y-%m-%d_%H%M%S.log
log_line_prefix              | %t
log_min_duration_statement   | 200ms
log_rotation_age             | 1d
log_rotation_size            | 10MB
logging_collector            | on
max_connections              | 100
max_stack_depth              | 2MB
server_encoding              | UTF8
shared_buffers               | 1GB
ssl                          | on
TimeZone                     | localtime
wal_buffers                  | 16MB
work_mem                     | 8MB

지난 몇 주 동안 메일 링리스트에서이 질문을 한 사람이 있습니까? 그렇다면 해당 토론에 대한 백 링크를 추가하겠습니다. 또한 : DB 서버 하드웨어 및 구성은 무엇입니까? wiki.postgresql.org/wiki/Slow_Query_Questions . 기본 설정이 아닌 설정을 포함하십시오 ( wiki.postgresql.org/wiki/Server_Configuration) . wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server 를 읽었 습니까 ? 가능하면 더 큰 거래로 일괄 작업합니까? 캐싱 레이어를 사용합니까? 그렇다면 어떻게합니까? 또는를 사용 synchronous_commit = off하고 commit_delay있습니까?
Craig Ringer

따라서 PostgreSQL 서버에 총 20 개의 연결이 있습니까? 게임 서버 당 5 개? 각 게임 서버의 5 개 콘이 16 명의 유니콘 작업자에게 공유됩니까?
Craig Ringer

오, 느린 쿼리를 기록하고 있습니까? 그렇다면 핫스팟은 무엇입니까? 간단한 INSERT? 스키마는 어떻습니까-파티션되어 있습니까? 무엇 explain analyze몇 가지 예제 쿼리는? 검문소는 얼마나 자주, 얼마나 걸립니까? 검사 점 로깅 옵션을 참조하십시오. 그리고 진지하게, PostgreSQL 버전은 무엇입니까? (업데이트 : 여기에 하드웨어를 나열한 것 같습니다 : dba.stackexchange.com/questions/28061/… )
Craig Ringer 10

어쨌든 풀 크기 조정의 경우 실제로 유일한 해결책은로드 및 DB 서버 처리량에 대한 강력한 측정을 설정 한 다음 스위트 스팟을 찾을 때까지 조정을 시작하는 것입니다.
Craig Ringer

@CraigRinger 아니오 나는 그 사람이 아닙니다. 그러나 뒤로 연결해 주셔서 감사합니다! PostgreSQL 서버 튜닝 을 읽었 으며 언급 된 팁 중 일부를 따랐습니다. 기본 설정이 아닌 설정을 포함 시켰습니다. 우리는 지금 메이크업 큰 거래 및 테스트를 조사하고 있습니다synchronous_commit = off
lorgartzor

답변:


14

여기서 간단한 대답은 "모니터링 및 성능 지표에 따라 시행되는 오류 및 시행 착오"입니다.

처음 막연한 부분을 찾는 데 도움이되는 몇 가지 일반적인 규칙이 있지만 매우 일반적입니다. "CPU 수와 독립 디스크 수"에 대한 광범위한 지침이 종종 인용되지만, 이는 매우 거친 시작점 일뿐입니다.

실제로해야 할 일은 애플리케이션에 대한 강력한 성능 지표를 얻는 것입니다. 통계 기록을 시작하십시오.

이를위한 통합 툴링 방식은 그리 많지 않습니다. nagios check_postgres스크립트, Cacti 시스템 성능 카운터 로깅, PostgreSQL 통계 수집기 등과 같은 것들이 있지만 모두 합치지는 않습니다. 슬프게도, 당신은 그 비트를 스스로해야합니다. PostgreSQL 측은 PostgreSQL 매뉴얼의 모니터링 을 참조하십시오 . EnterpriseDB의 Postgres Enterprise Monitor 와 같은 일부 타사 옵션이 있습니다 .

여기에 언급 된 애플리케이션 레벨 지표의 경우 공유 데이터 구조 또는 Redis와 같은 외부 비 내구성 DB에이를 기록하고 기록 할 때 또는 PostgreSQL DB에 쓰기 전에 집계해야합니다. Pg에 직접 로그하려고하면 측정 값을 기록하여 생성 된 오버 헤드로 측정 값이 왜곡되고 문제가 악화됩니다.

가장 간단한 옵션은 응용 프로그램 통계를 기록하는 데 사용하는 각 응용 프로그램 서버의 단일 항목 일 것입니다. 지속적으로 최소, 최대, n, 총계 및 평균을 업데이트하고 싶을 것입니다. 이렇게하면 각 스탯 포인트를 저장할 필요가없고 집계 만하면됩니다. 이 싱글 톤은 x 분마다 집계 통계를 Pg에 기록 할 수 있으며 성능에 미치는 영향을 최소화 할 정도로 낮은 속도입니다.

로 시작 :

  • 요청 대기 시간은 얼마입니까? 다시 말해, 앱이 클라이언트에 응답 할 때까지 클라이언트로부터 요청을받는 데 걸리는 시간입니다. 개별 기록이 아닌 일정 기간 동안 집계하여 기록하십시오. 요청 유형별로 그룹화하십시오. 페이지별로 말하십시오.

  • 앱이 실행하는 각 쿼리 또는 쿼리 유형에 대한 데이터베이스 액세스 지연은 무엇입니까? DB에 정보를 요청하고 정보를 저장하고 다음 작업으로 넘어갈 때까지 시간이 얼마나 걸립니까? 다시 한 번 애플리케이션에서 이러한 통계를 집계하고 집계 정보 만 DB에 씁니다.

  • 처리량은 어떻습니까? 주어진 x 분 안에 앱이 실행하는 각 주요 클래스의 쿼리 수는 DB에 의해 처리됩니까?

  • 같은 시간 x 분 동안 클라이언트 요청이 몇 번 있었습니까?

  • 몇 초마다 샘플링하고 DB의 동일한 x 분 창을 집계하면 얼마나 많은 DB 연결이 있었습니까? 유휴 상태 인 사람은 몇 명입니까? 활동적인 사람은 몇 명입니까? 인서트에서? 업데이트? 선택? 삭제? 그 기간 동안 몇 건의 거래가 있었습니까? 통계 수집기 설명서를 참조하십시오

  • 동일한 시간 간격 동안 다시 샘플링 및 집계 할 때 호스트 시스템의 성능 지표는 어떻습니까? 초당 몇 개의 읽기 및 쓰기 디스크 IO가 있습니까? 초당 메가 바이트의 디스크 읽기 및 쓰기? CPU 활용? 평균로드? RAM 사용?

이제 데이터를 상관시키고 그래프로 표시하여 앱의 성능에 대해 배울 수 있습니다. 패턴을보고 병목 현상을 찾기 시작합니다.

당신은 당신의 시스템이 병 목에 배울 수 INSERTUPDATE초당 메가 바이트 매우 낮은 디스크 I / O에도 불구하고, 높은 트랜잭션 속도에요. 이는 배터리 지원 후기 입 캐싱 RAID 컨트롤러 또는 일부 고품질 전원 보호 SSD로 디스크 플러시 성능을 개선해야한다는 힌트입니다. synchronous_commit = off서버 크래시 및 / 또는 a commit_delay에서 일부 트랜잭션이 손실 되어 동기화로드를 일부 해제 할 수있는 경우 에도 사용할 수 있습니다 .

동시 연결 수에 대해 초당 트랜잭션을 그래프로 표시하고 응용 프로그램이 보는 다양한 요청 비율을 수정하면 처리량 스폿이 어디에 있는지 더 잘 알 수 있습니다.

빠른 플러시 스토리지 (BBU RAID 또는 빠른 내구성 SSD)가없는 경우 상당히 적은 수의 활발한 쓰기 연결, 최대 2 배의 디스크 수, 아마도 RAID 배열에 따라 더 적은 수의 디스크를 원하지 않을 것입니다 디스크 성능 등이 경우에는 시행 착오를 할 가치가 없습니다. 다만 빠른 디스크 플러시 하나에 스토리지 서브 시스템을 업그레이드 .

pg_test_fsync이것이 문제가 될 수 있는지 판단하는 데 도움이되는 도구를 참조하십시오 . 대부분의 PostgreSQL 패키지는이 도구를 contrib의 일부로 설치하므로 컴파일 할 필요가 없습니다. 초당 2 천회 미만의 작업이 발생 pg_test_fsync하면 스토리지 시스템 을 긴급하게 업그레이드해야합니다. SSD가 장착 된 노트북은 5000-7000을받습니다. 내 워크 스테이션은 7200rpm SATA 디스크의 4 디스크 RAID 10 어레이를 사용하며, 쓰기 스루 (비 쓰기 캐싱)는 초당 약 80 ops, 초당 f_datasync20 ops를 얻 습니다 fsync(). 그건 느린 수백 번 . 비교 : 노트북 SSD와와 워크 스테이션 쓰기를 통해 (비 쓰기 캐싱) RAID (10). 이 랩톱의 SSD는 저렴하며 전원 손실시 쓰기 캐시를 플러시한다고 반드시 믿지는 않습니다. 나는 좋은 백업을 유지하고 내가 관심있는 데이터에 사용하지 않을 것입니다. 우수한 품질의 SSD는 성능이 우수하고 쓰기 내구성이 뛰어나더라도 성능이 우수합니다.

귀하의 신청의 경우, 다음 사항을 검토 할 것을 강력히 권장합니다.

  • 빠른 플러시 기능을 갖춘 우수한 스토리지 서브 시스템. 나는 이것을 충분히 강조 할 수 없다. 양질의 전원 장애 방지 SSD 및 / 또는 전원으로 보호되는 후기 입 캐시가있는 RAID 컨트롤러.
  • UNLOGGED손실이 생길 수있는 데이터에 테이블을 사용하십시오 . 주기적으로 로그 된 테이블로 집계하십시오. 예를 들어, 게임 진행 중을 로그되지 않은 테이블에 유지하고 점수를 일반적인 내구성 테이블에 씁니다.
  • 사용 commit_delay(빠른 세척 스토리지 덜 유용 - 힌트)
  • synchronous_commit잃어 버릴 수있는 트랜잭션 끄기 (빠른 플러시 스토리지에서는 유용하지 않음-힌트 힌트)
  • 파티셔닝 테이블, 특히 데이터가 "만료되어"정리 된 테이블. 파티션 된 테이블에서 삭제하는 대신 파티션을 삭제하십시오.
  • 부분 인덱스
  • 생성하는 인덱스 수를 줄입니다. 모든 인덱스에는 쓰기 비용이 있습니다.
  • 더 큰 거래에 대한 배치 작업
  • 읽기 전용 핫 스탠바이 복제본을 사용하여 주 DB에서 읽기로드 해제
  • 덜 자주 변경되거나 부실 할 수있는 데이터에 memcached 또는 redis와 같은 캐싱 계층을 사용합니다. PostgreSQL 테이블에서 트리거를 사용하여 캐시 무효화를 사용 LISTEN하고 NOTIFY수행 할 수 있습니다 .

확실하지 않은 경우 : http://www.postgresql.org/support/professional_support/

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.