PgBouncer 처리량을 4배로 확장한 방법
요약
본 글은 PostgreSQL의 연결 관리 및 확장성 문제를 PgBouncer를 활용하여 해결하는 방법을 다룹니다. PgBouncer는 높은 트래픽 환경에서 안정적인 연결 풀링을 제공하며, Kubernetes와 같은 분산 환경에서도 유용하게 사용될 수 있습니다. 특히 복잡한 질의 취소 처리 메커니즘과 네트워크 아키텍처 설계에 대한 심도 있는 논의가 포함되어 있습니다.
핵심 포인트
- PgBouncer는 PostgreSQL 연결 관리를 최적화하여 높은 트래픽을 안정적으로 처리합니다.
- Kubernetes 환경에서 PgBouncer를 운영하면 분산 및 장애 대응에 매우 효과적입니다.
- 질의 취소 처리는 PgBouncer가 클라이언트와 서버 간의 상태를 추적하는 복잡한 메커니즘을 통해 구현됩니다.
- 연결 풀링은 마이크로서비스 아키텍처에서 데이터베이스 접근을 통제하고 자원을 효율화하는 데 필수적입니다.
가장 검증됐고 PostgreSQL에 자연스럽게 맞는 PgBouncer부터 제대로 조정해 사용했으며, 준비된 문 지원처럼 오랫동안 남아 있던 문제도 해결돼 아주 잘 작동하고 있음
PostgreSQL 연결을 1만 개 이상으로 확장한 고객도 많고, 앞으로 Odyssey나 pgdog 같은 대안도 검토할 예정임. 다만 개인적으로 PostgreSQL에 1만 개 넘는 연결을 두는 방식은 선호하지 않으며, 수백 개만으로도 충분히 확장할 수 있다고 봄
관련된 흥미로운 사실로, ClickHouse도 원래 Yandex가 개발했음
Yandex는 러시아 회사이므로 사용하지 않는 편이 낫다고 봄
Kubernetes에서 PgBouncer를 운영하면 한 머신에 여러 프로세스를 띄우기도 쉽고, 여러 머신에 분산하기도 간단함
Azure가 VM 유지보수 과정에서 전체 서버군에 순차 장애를 일으키곤 해서 다중 머신 구성이 특히 유용함
PgBouncer에서 PostgreSQL까지 네트워크 홉이 하나 더 생길 때 처리량에 어떤 영향을 주는지 궁금함. 차이는 작을 것으로 예상하지만 확인해 볼 만함
여기서 말하는 피어링의 개념은 이해하지만 PostgreSQL에서 써본 적은 없음
A) PostgreSQL에 이를 쉽게 구성하는 모드나 설정이 있는가? 오류가 나지 않을 때까지 취소 요청을 피어들에게 순차 전달하거나, 잘못 받은 프로세스가 올바른 프로세스를 식별할 수 있는 메타데이터가 취소 요청에 담기는 구조를 상상하고 있음
B) 모든 PostgreSQL 프로세스가 so_reuseport로 클라이언트 요청을 받는다면 피어 간 통신에는 별도의 프로세스 간 통신(IPC) 수단이 필요해 보이는데, 실제로 어떤 메커니즘을 쓰는가?
원문은 AI가 쓴 티가 남. 취소 처리는 PostgreSQL 서버 프로세스가 아니라 PgBouncer 기능이며, 피어링도 PgBouncer 프로세스 사이에서 이뤄짐
PgBouncer 프로세스 ID를 취소 키에 포함하면 비교적 간단히 구현할 수 있을 듯함
PgBouncer가 왜 취소 요청까지 신경 써야 하는지 궁금함. PostgreSQL에 그대로 전달하고, 취소된 질의에 PostgreSQL이 정상 응답 대신 오류를 반환하면 해당 연결을 맡은 PgBouncer가 처리하면 되지 않는가?
질의 취소는 기존 질의 연결과 별도로 전달되므로 PgBouncer가 요청을 정확한 서버와 연결에 보내야 함
PgBouncer는 클라이언트에 가짜지만 추적 가능한 취소 PID와 비밀값을 주고, 취소 요청이 돌아오면 실제 서버·프로세스의 PID와 비밀값을 찾아 전달함. 또한 클라이언트는 질의가 실행 중이라고 믿지만 PgBouncer는 이미 끝나 연결이 재사용됐음을 아는 상황도 있으므로, 해당 연결과 PID가 여전히 그 질의를 실행 중인지 확인해야 함
마이크로서비스에서 연결 풀을 통해 PostgreSQL 서버 접근을 통제하는 용도인가? 모놀리식 백엔드라면 필요하지 않아 보임
대부분의 괜찮은 백엔드 프레임워크에는 연결 풀이 내장돼 있으며, 마이크로서비스가 필요하지도 권장되지도 않는 사용 사례의 98%는 이것으로 해결됨
호스트마다 백엔드 애플리케이션이 하나의 큰 바이너리로 실행된다면 맞음. 하지만 백엔드가 상태를 공유하지 않는 다수의 포크 프로세스로 구성된다면 분명 필요함
PgBouncer는 훌륭한 소프트웨어임. 많이 활용하고 있으며 데이터베이스 운영을 상당히 간단하게 만들어 줌
so_reuseport를 처음 알게 됐는데 흥미로움. 구성의 핵심은 이것과 피어링으로 보이는데, 피어링이 PgBouncer에 내장돼 있고 설정도 간단한가?
Kubernetes에서도 피어링을 사용할 수 있는가? 이 환경에서는 포트를 재사용할 필요가 없을 텐데, 각 Pod가 별도의 연결 풀을 가지고 독립적으로 동작하게 되는지도 궁금함
지금 46세인데, 23세 때 PostgreSQL의 무거운 연결 모델을 보고 충격받았던 기억이 남. 그 뒤로도 개선되지 않은 것인가?
상당히 개선됐으며 이제 수천 개 연결도 제법 잘 처리함: https://techcommunity.microsoft.com/blog/adforpostgresql/imp...
다만 연결 풀을 쓰지 않으면 PostgreSQL이 프로세스를 포크해야 하므로 새 연결 생성에 수십 밀리초 이상의 비용이 항상 듦. 연결 풀 없이 작성된 애플리케이션도 이상적이지 않지만 흔히 존재함
애플리케이션 프레임워크도 변했으며, 서버리스 아키텍처는 PostgreSQL이 문제를 겪기 시작하는 수만 개의 연결을 만들 수 있음. 개인적으로 수백 개 넘는 연결은 선호하지 않지만 요즘에는 충분히 현실적인 상황임
당시에는 여러 회사가 Java가 제시한 스레딩 모델에 처음으로 쓸 만한 해답을 내놓던 시기였음. 이는 Windows의 모델에 기능을 더한 형태였고 Solaris조차 Java 처리에 버거워했으며, HP-UX는 더 심했고 SGI가 HP보다 나았는지는 기억나지 않음
Java 호환성을 확보하는 과정에서 많은 회사가 동시성 처리 방식을 크게 바꿔야 했음. PostgreSQL과 SQLite도 비슷한 시기에 설계됐지만, 이런 스레딩 논의가 생기기 전부터 고부하 시스템을 배포해 온 업계 베테랑들이 오래된 하드웨어 사용자까지 지원하며 만든 시스템이었음
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기