집 >데이터 베이스 >MySQL 튜토리얼 >MySQL은 어떻게 응답 속도를 향상시킬 수 있습니까?
MySQL에는 고유한 한계가 있습니다. 많은 사이트가 MySQL+Memcached의 클래식 아키텍처를 채택했으며 일부 사이트는 MySQL을 포기하고 NoSQL 제품을 채택하기도 했습니다. 몇 가지 간단한 쿼리(특히 PK 쿼리)를 수행할 때 많은 NoSQL 제품이 MySQL보다 훨씬 빠르다는 것은 부인할 수 없습니다.
MySQL 자체의 한계로 인해 많은 사이트에서 MySQL+Memcached의 클래식 아키텍처를 채택했으며 일부 사이트에서는 MySQL을 포기하고 Redis/MongoDB와 같은 NoSQL 제품을 채택하기도 했습니다. 등. 몇 가지 간단한 쿼리(특히 PK 쿼리)를 수행할 때 많은 NoSQL 제품이 MySQL보다 훨씬 빠르며 프런트 엔드 웹사이트에서 수행되는 쿼리 중 80% 이상이 단순 쿼리 서비스라는 것은 부인할 수 없습니다.
MySQL은 HandlerSocket 플러그인을 통해 API 액세스 인터페이스를 제공합니다. 벤치마크 테스트에서 일반 R510 서버 단일 인스턴스 Percona/XtraDB는 72W+QPS(순수 읽기)에 도달했습니다. 이론적으로는 더 높은 성능을 얻을 수 있습니다. 동일한 조건에서 Memcached는 40W+QPS(순수 읽기)만 가지며, Memcached에는 동시성 기능을 제한하는 메모리에 대한 대규모 잠금이 있기 때문에 R510의 단일 Memcached 인스턴스는 성능을 향상시킬 수 없습니다.
Innodb 엔진은 기본 키, 고유 키 또는 인덱스로 검색합니다(즉, 조건이 다음과 같아야 하는 SQL). IN, INSERT/UPDATE/DELETE를 지원합니다.
기본 키, 고유 키, 인덱스 없이 검색하면 작동하지 않습니다!
테이블은 Innodb 엔진이어야 합니다
HandlerSocket과 NoSQL의 주요 사용 시나리오는 다릅니다. HandlerSocket은 주로 MySQL 개선, 테이블 추가, 삭제, 수정, 테이블 구조 수정 등의 작업을 최적화하고 집중적인 CPU 작업을 지원하는 데 사용되며, NoSQL은 캐시 기능으로 집중적인 I/O 작업을 지원합니다.
따라서 필요한 경우 두 가지를 결합하여 함께 작업할 수 있습니다.
HandlerSocket은 mysqld 프로세스에 통합된 MySQL용 플러그인입니다. NoSQL이 구현할 수 없는 기타 작업은 여전히 MySQL의 자체 관계형 데이터베이스를 사용하여 구현됩니다. 운영 및 유지 관리 수준에서 널리 사용되는 MySQL 마스터-슬레이브 복제 경험은 다른 NoSQL 제품에 비해 데이터 보안이 더 보장됩니다.
그것은 다음과 같습니다. HandlerSocket이 MySQL의 SQL을 우회하는 것을 볼 수 있습니다. 파싱 계층(SQL Layer)은 MySQL 스토리지 계층에 직접 접근합니다. 또한 HandlerSocket은 epoll 및 작업자 스레드/스레드 풀링 네트워크 아키텍처를 사용하여 더 높은 성능을 달성합니다.
MySQL의 아키텍처는 "데이터베이스 관리"와 "데이터 관리"의 분리, 즉 MySQL 서버+스토리지 엔진 모델입니다. MySQL 서버는 클라이언트와 직접 상호 작용하는 계층으로, 연결 스레드 관리, 실행 계획 생성을 위한 SQL 구문 분석, 뷰, 트리거, 저장 프로시저 및 특정 데이터 작업 관리와 관련 없는 기타 작업을 관리 및 구현하는 역할을 담당합니다. 엔진은 특정 데이터에 대해 작동하는 Handler API를 호출하여 저장을 허용합니다. Storage Engine은 Handler API 기능을 상속하여 구현하며, 데이터와 직접 상호작용하는 데이터 접근 구현(필수), 트랜잭션 구현(선택), 인덱스 구현(선택), 데이터 캐시 구현(선택)을 담당합니다.
HandlerSocket은 MySQL의 내부 구성 요소로 MySQL Daemon Plugin 형태로 NoSQL과 유사한 네트워크 서비스를 제공하며, 구성된 포트만 수신하고 NoSQL/API를 사용하여 데이터를 수신합니다. 통신 프로토콜을 사용하고 스토리지 엔진(예: InnoDB)을 호출하여 MySQL 내부의 Handler API를 통해 데이터를 처리합니다. 이론적으로 HanderSocket은 다양한 MySQL 스토리지 엔진을 처리할 수 있지만 MyISAM을 사용하면 삽입된 데이터를 찾을 수 없습니다. 이는 실제로 행을 구성할 때 첫 번째 바이트가 0xff로 초기화되지 않기 때문입니다. 여전히 지원될 수 있지만 메모리를 더 잘 활용하기 위해 HandlerSocket이 InnoDB 스토리지 엔진과 함께 사용됩니다.
위 그림에서 볼 수 있듯이 HandlerSocket은 mysql 클라이언트와 mysql 사이의 중간 계층 역할을 하며 mysql의 기본 데이터 및 테이블 처리 작업의 일부를 대체하며 멀티 스레드 접근 방식을 사용하여 DDL과 DML을 구별합니다. 운영. 그 목적은 복잡한 처리를 효율적으로 처리할 수 있도록 하는 것입니다.
HandlerSocket은 MySQL Daemon Plugin 형태로 존재하기 때문에 애플리케이션에서 MySQL을 NoSQL로 사용할 수 있습니다. 가장 큰 기능은 SQL 초기화 오버헤드 없이 InnoDB와 같은 스토리지 엔진과 상호 작용할 수 있도록 하는 것입니다. MySQL의 TABLE에 접근할 때 당연히 테이블을 열고 닫아야 하는데, 이전에 접근했던 테이블 캐시를 다시 사용하기 위해 저장하기 때문에 매번 테이블을 열고 닫지는 않는데, 테이블을 열고 닫는 것이 가장 많다. 리소스를 많이 소모하며 뮤텍스 경합을 쉽게 일으킬 수 있습니다. 이는 성능 향상에 매우 효과적입니다. 트래픽이 작아지면 HandlerSocket은 테이블을 닫으므로 일반적으로 DDL을 차단하지 않습니다.
HandlerSocket과 MySQL+Memcached의 차이점은 무엇인가요? 그림 1-2와 그림 1-3을 비교하면 그림 1-3은 일반적인 MySQL+Memecached 애플리케이션 아키텍처를 보여줍니다. Memcached의 가져오기 작업은 메모리나 디스크에서 MySQL의 기본 키 쿼리보다 훨씬 빠르기 때문에 Memcached는 데이터베이스 레코드를 캐시하는 데 사용됩니다. HandlerSocket의 쿼리 속도와 응답 시간이 Memcached와 비슷하다면 Memcached 캐시 레코드의 아키텍처 계층을 교체하는 것을 고려할 수 있습니다.
1) 다중 쿼리 모드 지원
HandlerSocket은 현재 인덱스 쿼리(기본 키 인덱스 및 비기본 키 일반 인덱스 모두), 인덱스 범위 스캔, LIMIT 절 즉, 추가, 삭제, 수정, 조회 등의 기능은 모두 지원하지만, 인덱스를 사용할 수 없는 연산은 아직 지원하지 않습니다. 또한, 네트워크를 통해 동시에 여러 Query 요청을 전송할 수 있도록 Execute_multi()를 지원하므로 네트워크 전송 시간이 절약됩니다.
2) 많은 수의 동시 연결을 처리합니다.
HandlerSocket은 epoll() 및 작업자 스레드/스레드 풀링 아키텍처를 사용하고 MySQL 내부 스레드 수가 제한되어 있으므로 HandlerSocket 연결은 가볍습니다(my.cnf로 구성 가능) (handlersocket_threads/handlersocket_threads_wr 매개변수에 의해 제어됨) 따라서 HandlerSocket에 수천만 개의 네트워크 연결이 설정되더라도 메모리를 많이 소모하지 않으며 안정성에도 어떤 영향도 미치지 않습니다. 대규모 상호 배제 경쟁 및 기타 문제(예: bug#26590, bug#33948, bug#49169).
3) 탁월한 성능
HandlerSocket의 성능은 HandlerSocket 성능 테스트 보고서에 설명되어 있습니다. 다른 NoSQL 제품과 비교해도 성능이 전혀 뒤떨어지지 않습니다. SQL 관련 기능을 호출하지 않을 뿐만 아니라 최적화도 수행합니다. 네트워크/동시성 관련 문제:
더 작은 네트워크 패킷: 기존 MySQL 프로토콜에 비해 HandlerSocket 프로토콜은 더 짧으므로 전체 네트워크 트래픽이 더 작습니다.
제한된 수의 MySQL 내부 스레드를 실행합니다. 위 내용을 참조하세요.
그룹 클라이언트 요청: HandlerSocket에 많은 수의 동시 요청이 도착하면 각 작업자 스레드는 가능한 한 많은 요청을 집계한 다음 집계된 요청을 실행하고 동시에 결과를 반환합니다. 이러한 방식으로 응답 시간을 약간 희생하여 성능이 크게 향상됩니다. 예를 들어 fsync() 호출 수를 줄이고 복사 대기 시간을 줄일 수 있습니다.
4) 중복 캐싱 없음
Memcached를 사용하여 MySQL/InnoDB 레코드를 캐시할 때 이러한 레코드는 Memcached와 InnoDB 버퍼 풀 모두에 캐시되므로 효율성이 매우 낮습니다(실제로는 데이터 복사본이 두 개 있고 Memcached 자체적으로 HA 지원이 필요할 수도 있음), HandlerSocket 플러그인을 사용하여 InnoDB 스토리지 엔진에 직접 접근하여 레코드를 InnoDB 버퍼 풀에 캐시하므로 다른 SQL 문에서 캐시된 데이터를 재사용할 수 있습니다.
5) 데이터 불일치 없음
Memcached를 사용할 때와 달리 데이터는 한 곳(InnoDB 스토리지 엔진 캐시)에만 저장되므로 Memcached와 MySQL 간에 데이터 일관성이 유지되어야 합니다.
6) 충돌 안전
백엔드 스토리지는 트랜잭션의 ACID 특성을 지원하고 트랜잭션의 보안을 보장하는 InnoDB 엔진입니다. innodb_flush_log_at_trx_commit=2로 설정되어 있어도 데이터베이스 서버가 충돌하는 경우
7) SQL/NOSQL 공존
많은 경우에 우리는 여전히 SQL(예: 복잡한 보고서 쿼리)을 사용하고 싶어하며 대부분의 NoSQL 제품은 SQL 인터페이스를 지원하지 않습니다. HandlerSocket은 단지 MySQL 플러그인일 뿐입니다. MySQL 클라이언트는 SQL 문을 보내지만, 높은 처리량과 빠른 응답이 필요한 경우에는 HandlerSocket을 사용합니다.
8) MySQL 기능 상속
HandlerSocket은 MySQL에서 실행되므로 SQL, 온라인 백업, 복제, HA, 모니터링 등 모든 MySQL 기능이 계속 지원됩니다.
9) MySQL을 수정/재구축할 필요가 없습니다
HandlerSocket은 플러그인이자 오픈 소스이기 때문에 MySQL을 수정하지 않고도 모든 MySQL 소스 코드는 물론 타사 버전(예: Percona)에서도 빌드를 지원합니다. .
10) 스토리지 엔진 독립적
MySQL-EnterpriseInnoDB 및 Percona XtraDB 플러그인만 테스트했지만 HandlerSocket은 이론적으로 모든 스토리지 엔진과 상호 작용할 수 있습니다. MyISAM은 간단한 수정을 통해서도 지원될 수 있지만 이는 데이터 캐싱 및 메모리 활용 측면에서 별 의미가 없습니다.
1) 프로토콜 비호환
HandlerSocket API는 Memcached API와 호환되지 않습니다. 사용하기 쉽지만 HandlerSocket과 상호 작용하는 방법을 배우려면 약간의 학습이 필요합니다. 그러나 Memecached 함수를 오버로드하여 이를 HandlerSocket API로 변환할 수 있습니다.
2) 보안 기능 없음
다른 NoSQL 데이터베이스와 유사하게 HandlerSocket의 작업자 스레드는 시스템 사용자 권한으로 실행되므로 응용 프로그램은 HandlerSocket 프로토콜을 통해 모든 테이블 개체에 액세스할 수 있습니다. 간단히 프로토콜을 수정하고, my.cnf에 구성 항목을 비밀번호로 추가하고, 연결 시 이 구성의 비밀번호 확인을 통과해야 합니다. 물론 네트워크 방화벽을 통해 데이터 패킷을 필터링할 수도 있습니다.
3) 디스크 IO 집약적인 시나리오에는 이점이 없습니다
IO 집약적인 애플리케이션 시나리오의 경우 데이터베이스는 초당 수천 개의 쿼리를 실행할 수 없으며 일반적으로 CPU 사용률이 1~10%에 불과합니다. 이 경우 SQL 구문 분석은 되지 않습니다. 성능 병목 현상이 발생하므로 HandlerSocket을 사용해도 이점이 없습니다. HandlerSocket은 데이터가 메모리에 완전히 로드되는 서버에서만 사용해야 합니다. 그러나 초당 4w+ IOPS를 제공할 수 있고 IO 장치 자체가 많은 양의 CPU를 소비하는 PCI-E SSD(예: Fusion-IO) 장치의 경우 HandlerSocket을 사용하면 여전히 이점이 있습니다.
참고: 책에 있는 설치 방법은 오래되었으며 버전이 상대적으로 낮습니다. 설치를 위해 공식 문서를 사용하는 것이 좋습니다: https:// github.com/DeNA/HandlerSocket- Plugin-for-MySQL
설치 문서: https://github.com/DeNA/HandlerSocket-Plugin-for-MySQL/blob/master/docs-en/installation.en.txt
소스 코드 다운로드: github를 통해 직접 다운로드할 수도 있습니다. git clone 또는 다운로드도 가능합니다.
설치 단계:
1. Build Handlersocket
./autogen.sh ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
참고:
2. 컴파일
make && make install
3. 컴파일 후에는 HandleSocket을 사용할 수 없습니다. , MySQL 구성 파일(my.cnf)에 추가해야 합니다. 다음 구성:
[mysqld] # 绑定读请求端口 loose_handlersocket_port = 9998 # 绑定写请求端口 loose_handlersocket_port_wr = 9999 # 读请求线程数 loose_handlersocket_threads = 16 # 写请求线程数 loose_handlersocket_threads_wr = 16 # 设置最大接收连接数 open_files_limit = 65535
여기에 추가된 것은 주로 HandleSocket 구성을 위한 것입니다. 데이터 읽기용 9998과 데이터 쓰기용 9999의 두 가지 포트가 있습니다. 단, 9998개까지 읽는 것이 더 효율적입니다. 여기서 읽기 및 쓰기를 처리하는 스레드 수는 16개로 설정됩니다. 또한, 더 많은 동시 연결을 처리하기 위해 열린 파일 설명자 수를 65535
로 설정합니다. , InnoDB의 innodb_buffer_pool_size 또는 MyISAM의 key_buffy_size 구성 옵션은 캐시 인덱스와 관련이 있으므로 최대한 크게 설정하여 사용할 수 있도록 합니다. HandleSocket의 잠재력.
4. HandleSocket 활성화
실행하려면 MySQL에 로그인하세요
mysql> install plugin handlersocket soname 'handlersocket.so';
show processlist 또는 showplugins
마지막으로 PHP 확장 패키지 PHP HandlerSocket
을 설치해야 합니다. 설치 설명서: https:// github.com/tz -lom/HSPHP
PHP 사용법:
Select
<?php $c = new \HSPHP\ReadSocket(); $c->connect(); $id = $c->getIndexId('data_base_name', 'table_name', '', 'id,name,some,thing,more'); $c->select($id, '=', array(42)); // SELECT WITH PRIMARY KEY $response = $c->readResponse(); //SELECT with IN statement $c = new \HSPHP\ReadSocket(); $c->connect(); $id = $c->getIndexId('data_base_name', 'table_name', '', 'id,name,some,thing,more'); $c->select($id, '=', array(0), 0, 0, array(1,42,3)); $response = $c->readResponse();
Update
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->update($id,'=',array(100500),array(100500,42)); // Update row(k,v) with id 100500 to k = 100500, v = 42 $response = $c->readResponse(); // Has 1 if OK $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->update($id,'=',array(100500),array(100500,42), 2, 0, array(100501, 100502)); // Update rows where k IN (100501, 100502) $response = $c->readResponse(); // Has 1 if OK
Delete
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->delete($id,'=',array(100500)); $response = $c->readResponse(); //return 1 if OK
Insert
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->insert($id,array(100500,'test\nvalue')); $response = $c->readResponse(); //return array() if OK
관련 추천: "
mysql tutorial위 내용은 MySQL은 어떻게 응답 속도를 향상시킬 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!