데이터베이스 연결 풀의 크기를 설정하는 방법을 정말로 알고 계십니까?
얼마 전 오래된 프로젝트에서 Dubbo 서비스가 시작될 때 속도가 매우 느린 문제를 경험했습니다. 나중에 전체 프로세스가 데이터베이스를 초기화하고 있었기 때문에 로그를 살펴보았습니다. 연결. 데이터베이스 연결 매개변수를 보면 연결 풀 크기는 1024입니다.
뒤늦게 업계에 입문한 많은 학생들이 JDBC 인연으로 손글씨를 쓰는 시절을 경험해 본 적이 없습니다. 당시에는 데이터베이스 연결 풀이라는 개념이 없었고 모든 것이 네이티브 코드로 이루어졌는데, 이후 iBATIS를 사용하면서 자바 개발의 복잡성이 점차 줄어들면서 C3P0 데이터베이스 연결 풀과 같은 기본적인 것들이 파생되었다. 로마는 하루아침에 만들어지지 않았지만 인터넷은 너무 빨리 발전하고 있습니다. 기술의 압력으로 인해 다양한 미들웨어가 개발될 수밖에 없으며 모든 종류의 고급 비계를 구축하기 위해 야근을 하고 있으며 또한 많은 훌륭한 사람들을 달성했습니다. .
데이터베이스 연결은 TCP를 사용하여 연결을 설정하는 데 3번의 핸드셰이크가 필요하고 연결을 해제하려면 4번의 웨이브가 필요합니다. 현재 인터넷 사용 빈도로 데이터베이스에 액세스할 때마다 연결이 다시 설정되면 내 생각엔 당신 회사가 그럴 것 같아요. 800번의 파산도 충분하지 않습니다.
1. 데이터베이스 연결 과정은 어떻게 되나요?
Java의 창시자 Sun은 API 세트로 세상을 통일하고 싶어하지만 다양한 데이터베이스 서버 제조업체의 힘이 너무 강합니다. 통일하다. 마지막 수단은 통합된 인터페이스를 만들고 일련의 통합된 액세스 단계를 제안하는 것이었습니다. 각 제조업체는 인터페이스를 구현하고 단계에 따라 자체 데이터베이스를 로드했습니다. 따라서 현재 해결 방법은 네 가지 방법을 사용하는 것입니다.
Class.forName()으로 알려진 드라이버를 등록하고, 성공하면 데이터베이스와 연결을 설정합니다. ;
데이터베이스의 CRUD를 작동하는 데 사용되는 명령문 개체를 가져옵니다.
데이터베이스에서 반환된 ResultSet을 가져옵니다.
데이터베이스 자체가 클라이언트 프로그램이고 시작된 후에만 연결될 수 있다는 점은 누구나 알아야 합니다. MYSQL을 예로 들어 서비스가 설치되고 시작된 머신에서 명령줄에 mysql -uroot -p를 입력하여 현재 데이터베이스에 연결합니다.
MYSQL 연결 방법에는 Unix 시스템과 Windows 시스템을 구분하는 일반적인 연결 방법이 있습니다. 여기서는 두 가지 방법만 사용합니다. 하나는 Unix 도메인 소켓이고 다른 하나는 일반적으로 tcp/ip 프로토콜을 기반으로 합니다. 즉, 원격으로 데이터베이스에 액세스하는 경우에는 tcp/ip를 기반으로 해야 하지만 로컬로 로그인하는 경우에는 소켓 또는 tcp/ip를 사용하게 됩니다.
소켓: mysql -uroot -p
tcp/ip: mysql -h127.0.0.1 -uroot -p
데이터베이스 서버와 애플리케이션 서버가 연결된 경우 다른 호스트를 사용하는 경우 연결을 설정하기 위해 tcp/ip를 사용해야 합니다. 각 연결은 유지 관리를 위해 운영 체제의 스레드를 차지합니다. 연결 설정도 짧은 연결과 긴 연결의 두 가지 범주로 나뉩니다.
짧은 연결
소위 짧은 연결은 애플리케이션과 데이터베이스 간의 통신이 완료된 후 연결이 닫히는 것을 의미합니다. 이러한 종류의 연결의 각 작업은 다음과 같습니다.
요청 발행--->연결 설정--->데이터 조작--->연결 해제
이 문제 is:
잦은 연결 설정/해제로 인해 데이터베이스에 대한 시스템 부담이 증가합니다.
애플리케이션에 의한 각 데이터베이스 작업 프로세스가 매우 느려집니다.
응용 시스템은 연결을 설정할 때마다 포트를 점유하고 이를 자주 설정/해제합니다. 해제된 각 연결은 해제 요청을 보낸 후 즉시 실행되지 않으며 확인될 때까지 FIN 단계를 기다려야 합니다. 따라서 초당 수천 개의 데이터베이스 요청이 있는 경우 애플리케이션 서버 포트가 소모될 가능성이 높습니다.
긴 연결
긴 연결은 연결이 설정된 후 열리고 애플리케이션이 닫힐 때까지 해제되지 않습니다. 긴 연결을 사용하면 매번 연결을 생성함으로써 발생하는 오버헤드를 줄일 수 있다는 이점이 있습니다.
애플리케이션 서버의 경우 긴 연결을 유지함으로써 얻을 수 있는 이점은 자명하지만 데이터베이스 서버의 경우 긴 연결을 너무 많이 유지하면 재앙이 됩니다.
MYSQL의 TCP 연결은 긴 연결을 지원하므로 데이터베이스 작업을 마칠 때마다 바로 연결을 닫을 필요 없이 다음 사용 때까지 기다려 연결을 재사용하면 된다. 모든 소켓 롱 연결은 TCP 자체 핑을 통해 하트비트(TCP keepalive)를 유지함으로써 연결 상태를 유지합니다. 우리에게 익숙한 웹소켓은 TCP의 하트비트를 사용하여 중단 없이 연결을 유지합니다.
연결 풀
긴 연결의 이점은 너무나 커서 당연히 모든 사람이 긴 연결을 사용합니다. 천천히, 나는 장기 연결 유지 관리를 위한 도구 세트인 데이터베이스 연결 풀을 개발했습니다.
연결 풀 설계는 그다지 복잡하지 않습니다.
연결을 초기화합니다.
비즈니스가 연결을 해제합니다.
비즈니스에서 요청을 보냅니다.
연결을 다시 설정합니다.
위의 기본 기능 외에도 동시성 문제, 다중 데이터베이스 서버 및 다중 사용자, 트랜잭션 처리, 연결 풀 구성 및 유지 관리도 처리해야 합니다. 아마도 이런 기능이 아닐까 싶습니다. 연결 풀을 사용하면 연결 설정 및 해제가 비즈니스와 관련이 없으며 유지 관리를 위해 핸드오버 풀에 맡겨집니다.
2. MYSQL은 몇 개의 연결을 지원할 수 있나요?
MYSQL의 최대 연결 수는 버전 5.7에서 기본적으로 151개이며 최대 연결 수는 16384(2^14)에 도달할 수 있습니다. 최대 연결 수를 설정하는 방법은 서버 성능에 따라 다릅니다. MYSQL 연결 수 정보를 보는 명령은 다음과 같습니다.
mysql> show Variables like '%max_connections%';
+----- ------------+-------+
| 변수 이름 |
+- -------- ------+-------+
| max_connections |
+----- -------- ----+-------+
1행 세트(0.00초)
최대 MYSQL 연결 수 우리의 프로덕션 환경은 5050으로 설정되어 있습니다. 너무 작으면 설정할 수 없습니다. 너무 작으면 연결 실패가 발생합니다. "쿼리 실패 오류 1040: 연결이 너무 많습니다" 오류. 너무 크고 데이터베이스에 연결된 머신이 많으면 MYSQL의 현재 성능에 영향을 미칩니다.
MYSQL 공식 웹사이트에서는 최대 연결 수 설정에 대한 권장 비율을 제공합니다:
Max_used_connections / max_connections * 100% ≒ 85%
즉, 사용된 연결 수는 전체 상한의 약 85%를 차지합니다. 최대 연결 수에 대한 현재 사용된 연결 수의 비율이 10% 미만이면 설정이 너무 크다는 것을 알 수 있습니다.
현재 데이터베이스에 설정된 연결 수를 쿼리합니다.
mysql> show status like 'Threads_connected';
+--------- --- ------+-------+
| 변수_이름 |
+---------- --- ----+-------+
| 스레드_연결됨 89 |
+------------ --- ----+-------+
1행(0.00초)
Mysql 구성을 쿼리하고 전역 변수에 설정할 수 있습니다. 구성 주로 다음을 쿼리할 수 있습니다.
구성
의미
연결
관계없이 Mysql에 연결을 시도하는 연결 수 연결 성공 여부에 따라 이 값은 +1이 됩니다.
Threads_connected
설정된 연결 수는 일반적으로 최대 연결 수의 최대 연결 수보다 적습니다. 단일 노드 아래 풀
max_connections
Mysql에 의해 제한되는 최대 연결 수
wait_timeout
즉, 최대 수명 MYSQL 긴 연결(비대화형)의 경우 기본값은 8시간입니다.
interactive_timeout
긴 연결(대화형)의 최대 수명은 기본값은 8시간입니다.
3. 연결 풀에는 몇 개의 연결이 적합합니까?
연결 풀을 설정하십시오. 크기가 클수록 현재 시스템의 성능이 더 좋습니다. 서비스 위치, 네트워크 상태, 데이터베이스 머신 성능, 데이터베이스 특성 등 동시에 시스템 리소스, 메모리, 포트, 동기화 세마포어 등을 낭비해서는 안 됩니다.
예를 들어 애플리케이션 서버 Tomcat이 설정하는 최대 스레드 풀의 기본값은 200입니다. 각 스레드가 데이터베이스 연결을 사용한다고 가정하면 최대 스레드 풀 크기는 200보다 작거나 같아야 합니다. .
또 고려해야 할 점은 장시간 연결을 신청할 때마다 물리적 네트워크에 장시간 연결 유지를 위한 프로세스가 구축되며, 해당 프로세스의 실행은 CPU 코어 수와 관련이 있다는 점입니다. 물리적 기계의. 이론적으로 8코어 서버의 경우 연결 풀을 8로 설정하는 것이 가장 좋습니다. 각 코어는 동시에 하나의 스레드를 처리합니다. 8을 초과하는 동시성에는 스레드 컨텍스트 전환의 오버헤드가 발생합니다.
오라클 성능팀에서 공개한 짧은 영상입니다. 연결 풀 테스트는 테스트 영상 1과 테스트 영상 2로 나누어져 있습니다. 영상에서는 스레드 풀 크기를 2048로 조정했을 때 데이터베이스 성능이 갑자기 떨어졌다가 144로 조정한 후 회복되는 모습을 보여줬습니다. PostgreSQL은 예상 스레드 풀 크기를 설정하는 공식을 제공합니다:
connections = ((core_count * 2) + Effective_spindle_count)
공식 출처: /brettwooldridge/HikariCP/wiki/About -풀 크기 조정.
이 중 core_count는 CPU 코어이고, Effective_spindle_count는 유효 스핀들 수를 의미합니다. 서버가 16개의 디스크로 구성된 RAID를 사용하는 경우 valid_spindle_count=16입니다. 이는 기본적으로 서버가 관리할 수 있는 병렬 I/O 요청 수를 측정한 것입니다. 회전하는 하드 디스크는 일반적으로 한 번에 하나의 I/O 요청만 처리할 수 있으며, 하드 디스크가 16개인 경우 시스템은 16개의 I/O 요청을 동시에 처리할 수 있습니다.
히카리는 현재 최고의 데이터베이스 연결 풀 중 하나로서 제안된 공식이 여전히 테스트를 견딜 수 있다고 생각합니다. 프로덕션 환경에서 시도해 볼 수도 있습니다(문제가 있으면 나에게 오지 마세요).
데이터베이스 연결 풀의 크기를 설정하는 방법을 정말로 알고 계십니까?
태그: 초과 근무 발판을 가져옵니다 기능이 너무 많습니다 짧은 연결 복잡한 연결 설정