>  기사  >  백엔드 개발  >  Nine Million Bicycles MySQL 연결 수가 한도를 초과하는 문제에 대한 솔루션

Nine Million Bicycles MySQL 연결 수가 한도를 초과하는 문제에 대한 솔루션

WBOY
WBOY원래의
2016-07-29 08:46:05938검색

max_user_connections는 MySQL 사용자 연결 수에 대한 최대 설정입니다. 전체 설명은 서버의 MySQL에 대한 최대 연결 매개변수 수가 충분하지 않음을 의미합니다. 해결 방법: MySQL 설치 디렉토리의 my.ini 또는 my.cnf 파일에서 max_user_connections 매개변수 값을 수정하고 MySQL 서버를 다시 시작하십시오.
그러나 일반적으로 MySQL의 기본 연결 수인 100개이면 충분합니다. 절차적인 측면에서 생각해 볼 필요가 있습니다. MySQL의 기본 최대 연결 수는 100(N)이지만 일반 사용자가 실제로 사용하는 연결 수는 N-1개뿐이다. 많은 웹사이트가 실행될 때 연결이 제한될 것입니다. 10번 중 9번은 웹사이트의 실제 방문 횟수가 표준을 초과하는 것이 아니라 우리가 디자인할 때 불합리한 방법을 사용하기 때문이라고 생각합니다. 웹사이트 프로그램의 디자인 아키텍처 또는 데이터 구조로 인해 발생합니다. 한도를 초과하는 비정상 접속의 가능한 원인은 다음과 같습니다. (Tianyuan의 실시간 요약은 완전하지 않거나 오류가 없을 수 있으며 참고용일 뿐입니다.)
인원 수, 온라인 시간 및 조회수는 기본 프로그램 데이터베이스와 동일한 데이터 공간에 속합니다.
복잡한 동적 페이지도 쉽게 나타나며, 특히 사용자가 탐색할 때마다 여러 데이터베이스 또는 테이블 작업이 관련되는 경우 더욱 그렇습니다.
또한 불합리한 프로그램 설계(예: 복잡한 작업, 대기 및 기타 작업이 데이터베이스 상호 작용 중간에 배치됨)가 있거나 프로그램에 릴리스 버그가 있습니다.
컴퓨터 하드웨어 구성이 너무 낮지만 너무 높은 버전과 너무 높은 구성의 MySQL이 설치되어 있습니다.
캐싱 기술을 사용하지 않습니다.
데이터베이스가 최적화되지 않았거나 테이블이 복잡하게 설계되었습니다.
다른 이유로 인해 데이터베이스의 데이터 상호 작용 시간이 연장되거나 상호 작용 횟수가 늘어납니다. 따라서 이러한 문제가 발생하면 먼저 프로그램에 연결 해제 실패를 일으키는 BUG가 있는지 고려한 다음 소프트웨어 및 하드웨어 최적화를 고려해야 합니다. 물론, MySQL 연결 수를 수정하는 것도 소프트웨어 최적화 방법 중 하나입니다. 모두가 학습하는 태도로 자신의 이유를 연구하여 이 문제를 해결할 수 있기를 바랍니다. 정말 이유를 찾을 수 없다면 먼저 연결 수를 수정하고 실제 원인 찾기를 연기해야 ​​합니다.
PHP의 데이터베이스 영구 연결 mysql_pconnect
PHP 프로그래머는 mysql_pconnect(영구 연결) 기능을 사용하여 MySQL 데이터베이스에 연결할 수 있다는 것을 모두 알고 있어야 합니다. 데이터베이스 영구 연결을 사용하면 효율성이 향상될 수 있지만 실제 애플리케이션에서는 데이터베이스 영구 연결은 종종 문제를 일으킵니다. 일부 문제는 일반적으로 방문 횟수가 많은 웹사이트에서 데이터베이스에 연결할 수 없는 것으로 나타납니다. 서버를 다시 시작한 후 "..."와 유사한 오류 메시지가 나타납니다. 다시 정상적으로 작동하지만 통과할 수 없습니다. 잠시 후 동일한 오류가 다시 발생했습니다. 모든 사람이 이러한 문제의 원인을 명확하게 설명할 수는 없습니다. PHP 문서에 관련 정보가 있지만 설명이 이해하기 쉽지 않습니다. 여기서는 뻔뻔하게도 간단한 논의와 명시된 견해를 작성하려고 합니다. 모두 정확할 수 있으며 모든 사람의 피드백을 환영합니다.
먼저 영구 데이터베이스 연결의 정의를 살펴보세요. 영구 데이터베이스 연결은 스크립트 실행이 종료될 때 닫히지 않는 연결을 의미합니다. 영구 연결 요청을 받은 경우. PHP는 이미 동일한 영구 연결(이전에 열렸던)이 있는지 확인합니다. 존재하는 경우 연결이 직접 사용되며 존재하지 않는 경우 새 연결이 설정됩니다. 소위 "동일" 연결은 동일한 사용자 이름과 비밀번호를 사용하여 동일한 호스트에 연결하는 것을 의미합니다.
PHP가 MySQL을 작동하기 위해 영구 연결을 사용하려면 전제 조건이 있습니다. PHP는 다중 스레드 또는 다중 프로세스 웹 서버용 플러그인 또는 모듈로 설치되어야 합니다. 가장 일반적인 형태는 다중 프로세스 Apache 서버에서 PHP를 모듈로 사용하는 것입니다. 다중 프로세스 서버의 일반적인 특징은 상위 프로세스와 하위 프로세스 그룹이 함께 실행되며, 그 중 하위 프로세스가 실제로 웹 페이지를 생성한다는 것입니다. 클라이언트가 상위 프로세스에 요청할 때마다 해당 요청은 다른 클라이언트 요청에 의해 점유되지 않은 하위 프로세스로 전달됩니다. 이는 동일한 클라이언트가 두 번째로 서버에 요청을 하면 다른 하위 프로세스에 의해 처리될 수 있음을 의미합니다. 영구 연결을 연 후 다른 하위 프로세스에서 SQL 서비스를 요청하는 모든 후속 페이지는 설정된 SQL 서버 연결을 재사용할 수 있습니다. 이를 통해 각 하위 프로세스는 페이지가 처리될 때마다 SQL 서버에 연결을 요청하는 대신 수명 주기 동안 하나의 연결 작업만 수행할 수 있습니다. 각 하위 프로세스는 서버에 대한 독립적인 영구 연결을 설정합니다. PHP 자체에는 데이터베이스 연결 풀 개념이 없지만 Apache에는 프로세스 풀 개념이 있습니다. Apache 하위 프로세스가 끝나면 다시 프로세스 풀에 배치됩니다. 이는 또한 mysql_pconnect로 열리는 mysql 연결 리소스를 허용합니다. 해제되지 않습니다. 해당 Apache 하위 프로세스에 연결되어 프로세스 풀에 저장됩니다. 그러면 다음 연결 요청에 다시 사용할 수 있습니다. 모든 것이 정상인 것 같지만 Apache에 동시 접속량이 많은 경우 mysql_pconnect를 사용하면 이전 Apache 하위 프로세스가 점유하고 있던 MySQL 연결이 닫히지 않고 MySQL이 곧 최대 연결 수에 도달하여 후속 작업을 수행하게 됩니다. 요청이 불가능합니다. 응답이 없습니다.
위 텍스트의 일부는 PHP 문서에서 발췌한 것입니다. 조금 서툴고 이해하기 어려울 수 있으므로 문제를 언어로 설명하기 위해 또 다른 예를 들어 보겠습니다.
Apache가 최대로 구성되어 있다고 가정합니다. 연결 수는 1000입니다. MySQL은 최대 연결 수 100으로 구성됩니다. Apache 서버가 200개의 동시 액세스를 받으면 그 중 100개는 데이터베이스 액세스와 관련되고 나머지 100개는 사용 가능한 데이터베이스가 없기 때문에 데이터베이스 액세스와 관련되지 않습니다. 따라서 데이터베이스 액세스에 관련된 100개의 동시성은 동시에 100개의 데이터베이스 영구 연결을 생성하여 최대 데이터베이스 연결 수에 도달합니다. 이러한 작업이 완료되지 않으면 다른 연결은 더 이상 데이터베이스를 얻을 수 없습니다. 이러한 작업이 완료되면 해당 연결이 프로세스 풀에 배치됩니다. 이때 Apache의 프로세스 풀에는 200개의 유휴 하위 프로세스가 있으며 그 중 100개는 데이터베이스 연결을 갖습니다. 왜냐하면 Apache는 유휴 하위 프로세스를 무작위로 선택하기 때문입니다. , 따라서 귀하가 받는 하위 프로세스는 데이터베이스 연결을 포함하지 않는 100개 프로세스 중 하나일 가능성이 높으며 데이터베이스 연결이 최대값에 도달하여 새 데이터베이스 연결을 성공적으로 설정할 수 없습니다. 페이지를 새로 고칠 때 운이 좋으면 데이터베이스 연결이 있는 하위 프로세스가 할당되어 페이지를 정상적으로 탐색할 수 있습니다. 방문 횟수가 많은 웹사이트의 경우 언제든지 동시성이 많이 발생할 수 있으므로 방문자는 지속적으로 데이터베이스에 연결할 수 없는 것을 발견할 수 있습니다.
아마도 Apache와 MySQL의 최대 연결 수를 같은 크기로 조정할 수는 없을까? 예, 최대 연결 수를 합리적으로 조정하면 이 문제를 어느 정도 피할 수 있지만 Apache와 MySQL의 로드 기능은 Apache의 로드 용량에 따라 설정되는 경우 MySQL의 경우 최대 연결 수가 됩니다. 너무 크면 MySQL 데이터베이스에 대한 많은 수의 영구 연결이 생성됩니다. 예를 들어 평시에 수백만 명의 군대를 지원하는 것과 같으며 비용이 부하에 따라 설정됩니다. Apache에 대한 MySQL의 용량은 최대 연결 수가 너무 작아서 과도한 느낌이 들고 Apache의 최대 효율성을 이끌어낼 수 없습니다.
따라서 PHP 매뉴얼의 소개에 따르면 동시 접속률이 낮은 웹사이트에서만 데이터베이스 영구 연결을 사용하는 것이 적합합니다. 그러나 동시 접속률이 낮은 웹사이트의 경우 데이터베이스 영구 연결을 사용하면 효율성이 향상되지 않습니다. 큰 의미는 이런 관점에서 볼 때 PHP의 데이터베이스 영구 연결은 기본적으로 쓸모없는 역할이라고 생각합니다. 데이터베이스 연결 풀 개념을 사용해야 한다면 Apache 자체에서 제공하는 sqlrelay 또는 mod_dbd를 사용해 볼 수 있습니다. 놀랄 것입니다.
mysql_free_result 및 mysql_close 정보
저는 이전에 mysql을 사용할 때 항상 짧은 링크를 사용했습니다. mysql_store_result를 호출하여 데이터를 한 번 가져온 후 직접 호출했습니다.

코드 복사 코드는 다음과 같습니다.


mysql_free_result(m_result);
mysql_close(m_Database)


하지만 두 가지 문제가 있습니다. 🎜>긴 연결을 사용하는 경우(즉, 연결 후 절대 닫히지 않습니다.) 마지막에 mysql_close가 호출되면 매번 mysql_free_result를 호출해야 하나요?
mysql_close가 호출된 후에도 m_result 데이터를 계속 사용할 수 있나요?
먼저 결론을 말씀드리겠습니다.
매번 호출해야 합니다. 테스트 후 mysql_store_result의 포인터가 매번 다르기 때문에 동일한 buf가 공유되지 않음을 나타냅니다.
아직도 사용할 수 있습니다. valgrind 스캐닝 후 mysql_close만 호출한 결과는

코드 복사 코드는 다음과 같습니다.

== 9397== 1 블록의 16,468(88 직접, 16,380 간접) 바이트는 손실 기록 5/5
==9397== 0x40219B3에서 확실히 손실됩니다: malloc (vg_replace_malloc.c:195)
==9397= = 0x8053EA2 기준: my_malloc(/data/home/dantezhu/appbase/application/platform/openqqcom/share/db_openright/test/test에서)
==9397== 0x806D314 기준: mysql_store_result(/data/home/dantezhu에서) /appbase/application /platform/openqqcom/share/db_openright/test/test)
==9397== by 0x804BB04: CMySQLCppClient::Result(st_mysql_res*&) (mysql_cpp_client.cpp:127)
==9397 == by 0x804AB58 : CDBOpenRight::GetUinsByApp(unsigned int, std::set, std::allocator >&) (db_openright.cpp:58)
== 9397== by 0x8049F10: main (test.cpp:27)

나중에 천천히 공부해보겠습니다. .
위 내용은 Nine Million Bicycles의 내용을 포함하여 Nine Million Bicycles의 MySQL 연결 수가 제한을 초과하는 문제에 대한 해결책을 소개한 내용입니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.