MySQL - 최적화된 그래픽 코드 상세 소개

黄舟
풀어 주다: 2017-03-09 13:18:45
원래의
1357명이 탐색했습니다.

성숙한 데이터베이스 아키텍처는 처음부터 고가용성, 고확장성 등의 특성을 갖도록 설계되지 않습니다. 사용자 수가 증가함에 따라 인프라가 점차 개선됩니다. 이번 블로그 포스팅은 주로 MySQL 데이터베이스의 개발 주기에서 직면하는 문제점과 MySQL에 최적화된 그래픽 코드의 세부 도입 계획에 대해 다루고 있으며, 당분간 프론트엔드 애플리케이션을 제쳐두고 대략적으로 다음과 같은 5단계로 나누어집니다. 🎜>

1. 데이터베이스 테이블 디자인

프로젝트 승인 후 개발 부서에서 프로젝트를 개발합니다. 제품 부서의 필요에 따라 개발 엔지니어의 작업 중 하나는 구조 설계 테이블을 컴파일하는 것입니다. 데이터베이스의 경우 이는 매우 중요합니다. 제대로 설계되지 않으면 액세스 속도와 사용자 경험에 직접적인 영향을 미칩니다. 느린 쿼리, 비효율적인 쿼리 문, 부적절한 인덱싱, 데이터베이스 정체(교착 상태) 등 많은 영향 요인이 있습니다. 물론 스트레스 테스트를 수행하고 버그를 찾아내는 테스트 엔지니어 팀이 있습니다. 테스트 엔지니어가 없는 팀의 경우 대부분의 개발 엔지니어는 초기 단계에서 데이터베이스 설계가 합리적인지 여부에 대해 크게 생각하지 않지만 프로젝트가 일정량 방문하면 최대한 빨리 기능 구현 및 제공을 완료합니다. 숨겨진 문제가 노출되면 다시 수정하기가 쉽지 않습니다.

2. 데이터베이스 배포

운영 및 유지보수 엔지니어가 등장했으며, 초기 방문횟수는 따라서 단일 배포로 약 1,500의 QPS(초당 쿼리 속도)를 처리할 수 있습니다. 고가용성을 고려하면 MySQL 마스터-슬레이브 복제 + Keepalived를 더블클릭 핫 백업에 사용할 수 있습니다. 일반적인 클러스터 소프트웨어에는 Keepalived 및 Heartbeat가 포함됩니다.

3. 데이터베이스 성능 최적화

MySQL을 일반 X86 서버에 배포하는 경우 어떤 최적화를 하더라도 MySQL은 이론적으로 약 2,000 QPS를 처리할 수 있습니다. 최적화 후에는 약 2,500 QPS로 증가할 수 있습니다. 그렇지 않으면 방문 수가 약 1,500개의 동시 연결에 도달하면 데이터베이스 처리 성능이 저하됩니다. 여전히 풍부하므로 소프트웨어 문제를 고려해야 할 때입니다. 그렇다면 데이터베이스의 성능을 극대화하는 방법은 무엇입니까? 한편으로는 단일 서버에서 여러 MySQL 인스턴스를 실행하여 서버 성능을 극대화할 수 있습니다. 반면에 운영 체제와 데이터베이스의 기본 구성은 상대적으로 보수적이므로 특정 제한 사항이 적용됩니다. 이러한 구성은 가능한 한 많은 연결을 처리하도록 적절하게 조정될 수 있습니다.

구체적인 최적화에는 다음 세 가지 수준이 있습니다.

3.1 데이터베이스 구성 최적화

MySQL에는 일반적으로 사용되는 두 가지 스토리지 엔진이 있습니다. 하나는 트랜잭션 처리를 지원하지 않고 빠른 읽기 성능과 테이블 수준 잠금 기능을 갖춘 MyISAM입니다. 다른 하나는 트랜잭션 처리(ACID)를 지원하는 InnoDB입니다. 설계 목표는 대용량 데이터 처리를 위한 성능 및 행 수준 잠금을 극대화하는 것입니다.

테이블 잠금: 낮은 오버헤드, 큰 잠금 세분성, 높은 교착 상태 가능성 및 상대적으로 낮은 동시성.

행 잠금: 높은 오버헤드, 작은 잠금 세분성, 낮은 교착 상태 가능성, 상대적으로 높은 동시성.

테이블 잠금과 행 잠금은 왜 발생하나요? 주로 데이터의 무결성을 보장하기 위한 것입니다. 예를 들어, 한 사용자가 테이블을 운영하고 있고 다른 사용자도 테이블을 운영하려는 경우 다른 사용자가 테이블 잠금 및 행을 운영하기 전에 첫 번째 사용자가 작업을 완료할 때까지 기다려야 합니다. 그것이 바로 자물쇠의 역할입니다. 그렇지 않고 여러 사용자가 동시에 테이블을 운영하게 되면 데이터 충돌이나 예외가 반드시 발생하게 됩니다.

위 내용을 토대로 보면 InnoDB 스토리지 엔진을 사용하는 것이 최선의 선택이며 MySQL 5.5 이상 버전에서는 기본 스토리지 엔진이기도 하다. 각 스토리지 엔진과 관련된 많은 매개변수가 아래에 나열되어 있습니다.

공개 매개변수 기본값:

max_connections = 151
#同时处理最大连接数,推荐设置最大连接数是上限连接数的80%左右   
sort_buffer_size = 2M
#查询排序时缓冲区大小,只对order by和group by起作用,可增大此值为16M
query_cache_limit = 1M  
#查询缓存限制,只有1M以下查询结果才会被缓存,以免结果数据较大把缓存池覆盖
query_cache_size = 16M  
#查看缓冲区大小,用于缓存SELECT查询结果,下一次有同样SELECT查询将直接从缓存池返回结果,可适当成倍增加此值
open_files_limit = 1024 
#打开文件数限制,如果show global status like 'open_files'查看的值等于或者大于open_files_limit值时,程序会无法连接数据库或卡死
로그인 후 복사

MyISAM 매개변수 기본값:

key_buffer_size = 16M
#索引缓存区大小,一般设置物理内存的30-40%
read_buffer_size = 128K  
#读操作缓冲区大小,推荐设置16M或32M
로그인 후 복사

InnoDB 매개변수 기본값:

innodb_buffer_pool_size = 128M
#索引和数据缓冲区大小,一般设置物理内存的60%-70%
innodb_buffer_pool_instances = 1    
#缓冲池实例个数,推荐设置4个或8个
innodb_flush_log_at_trx_commit = 1  
#关键参数,0代表大约每秒写入到日志并同步到磁盘,数据库故障会丢失1秒左右事务数据。
1为每执行一条SQL后写入到日志并同步到磁盘,I/O开销大,执行完SQL要等待日志读写,效率低。2代表只把日志写入到系统缓存区,再每秒同步到磁盘,效率很高,如果服务器故障,
才会丢失事务数据。对数据安全性要求不是很高的推荐设置2,性能高,修改后效果明显。
innodb_file_per_table = OFF  
#默认是共享表空间,共享表空间idbdata文件不断增大,影响一定的I/O性能。
推荐开启独立表空间模式,每个表的索引和数据都存在自己独立的表空间中,可以实现单表在不同数据库中移动。
innodb_log_buffer_size = 8M  
#日志缓冲区大小,由于日志最长每秒钟刷新一次,所以一般不用超过16M
로그인 후 복사

3.2 系统内核优化

大多数MySQL都部署在linux系统上,所以操作系统的一些参数也会影响到MySQL性能,以下对linux内核进行适当优化。

net.ipv4.tcp_fin_timeout = 30
#TIME_WAIT超时时间,默认是60s
net.ipv4.tcp_tw_reuse = 1    
#1表示开启复用,允许TIME_WAIT socket重新用于新的TCP连接,0表示关闭
net.ipv4.tcp_tw_recycle = 1  
#1表示开启TIME_WAIT socket快速回收,0表示关闭
net.ipv4.tcp_max_tw_buckets = 4096   
#系统保持TIME_WAIT socket最大数量,如果超出这个数,系统将随机清除一些TIME_WAIT并打印警告信息
net.ipv4.tcp_max_syn_backlog = 4096
#进入SYN队列最大长度,加大队列长度可容纳更多的等待连接
로그인 후 복사

在linux系统中,如果进程打开的文件句柄数量超过系统默认值1024,就会提示“too many files open”信息,所以要调整打开文件句柄限制。

# vi /etc/security/limits.conf  #加入以下配置,*代表所有用户,也可以指定用户,重启系统生效
* soft nofile 65535
* hoft nofile 65535
# ulimit -SHn 65535   #立刻生效
로그인 후 복사

3.3 硬件配置

加大物理内存,为提高文件系统性能,linux内核会从内存中分配缓存区(系统缓存和文件缓存)来存放热数据,也就是说物理内存越大,分配缓存区越大,缓存数据越多。

SSD硬盘代替SAS硬盘,将RAID级别调整为RAID1+0,相对于RAID1和RAID5有更好的读写性能(IOPS),毕竟数据库的压力主要来自磁盘I/O方面。

4、数据库架构扩展

随着业务量越来越大,单台数据库服务器性能已无法满足业务需求,该考虑加机器了,该做集群了~~~。主要思想是分解单台数据库负载,突破磁盘I/O性能,热数据存放缓存中,降低磁盘I/O访问频率。

4.1 主从复制与读写分离

因为生产环境中,数据库大多都是读操作,所以部署一主多从架构,主数据库负责写操作,并做双击热备,多台从数据库做负载均衡,负责读操作,主流的负载均衡器有LVS、HAProxy、Nginx。怎么来实现读写分离呢?大多数企业是在代码层面实现读写分离,效率比较高。另一个种方式通过代理程序实现读写分离,企业中应用较少,常见代理程序有MySQL Proxy、Amoeba。在这样数据库集群架构中,大大增加数据库高并发能力,解决单台性能瓶颈问题。如果从数据库一台从库能处理2000 QPS,那么5台就能处理1w QPS,数据库横向扩展性也很容易。

有时,面对大量写操作的应用时,单台写性能达不到业务需求。如果做双主,就会遇到数据库数据不一致现象,产生这个原因是在应用程序不同的用户会有可能操作两台数据库,同时的更新操作造成两台数据库数据库数据发生冲突或者不一致。在单库时MySQL利用存储引擎机制表锁和行锁来保证数据完整性,怎样在多台主库时解决这个问题呢?有一套基于perl语言开发的主从复制管理工具,叫MySQL-MMM(Master-Master replication managerfor Mysql,Mysql主主复制管理器),这个工具最大的优点是在同一时间只提供一台数据库写操作,有效保证数据一致性。


4.2 增加缓存

给数据库增加缓存系统,把热数据缓存到内存中,如果内存缓存中有要请求的数据就不再去数据库中返回结果,提高读性能。缓存实现有本地缓存和分布式缓存,本地缓存是将数据缓存到本地服务器内存中或者文件中,速度快。分布式可以缓存海量数据,扩展容易,主流的分布式缓存系统有memcached、redis,memcached性能稳定,数据缓存在内存中,速度很快,QPS可达8w左右。如果想数据持久化那就用redis,性能不低于memcached。

工作过程:

MySQL - 최적화된 그래픽 코드 상세 소개

4.3 分库

分库是根据业务不同把相关的表切分到不同的数据库中,比如web、bbs、blog等库。如果业务量很大,还可将切分后的库做主从架构,进一步避免单个库压力过大。

4.4 分表

数据量的日剧增加,数据库中某个表有几百万条数据,导致查询和插入耗时太长,怎么能解决单表压力呢?你就该考虑是否把这个表拆分成多个小表,来减轻单个表的压力,提高处理效率,此方式称为分表。

分表技术比较麻烦,要修改程序代码里的SQL语句,还要手动去创建其他表,也可以用merge存储引擎实现分表,相对简单许多。分表后,程序是对一个总表进行操作,这个总表不存放数据,只有一些分表的关系,以及更新数据的方式,总表会根据不同的查询,将压力分到不同的小表上,因此提高并发能力和磁盘I/O性能。

分表分为垂直拆分和水平拆分:

垂直拆分:把原来的一个很多字段的表拆分多个表,解决表的宽度问题。你可以把不常用的字段单独放到一个表中,也可以把大字段独立放一个表中,或者把关联密切的字段放一个表中。

水平拆分:把原来一个表拆分成多个表,每个表的结构都一样,解决单表数据量大的问题。

4.5 分区

分区就是把一张表的数据分成多个区块,这些区块可以在一个磁盘上,也可以在不同的磁盘上,分区后,表面上还是一张表,但数据散列在多个位置,这样一来,多块硬盘同时处理不同的请求,从而提高磁盘I/O读写性能,实现比较简单。

注:增加缓存、分库、分表和分区主要由程序猿来实现。

5、数据库维护

数据库维护是运维工程师或者DBA主要工作,包括性能监控、性能分析、性能调优、数据库备份和恢复等。

5.1 性能状态关键指标

QPS,Queries Per Second:每秒查询数,一台数据库每秒能够处理的查询次数

TPS,Transactions Per Second:每秒处理事务数

通过show status查看运行状态,会有300多条状态信息记录,其中有几个值帮可以我们计算出QPS和TPS,如下:

Uptime:服务器已经运行的实际,单位秒

Questions:已经发送给数据库查询数

Com_select:查询次数,实际操作数据库的

Com_insert:插入次数

Com_delete:删除次数

Com_update:更新次数

Com_commit:事务次数

Com_rollback:回滚次数

那么,计算方法来了,基于Questions计算出QPS:

 mysql> show global status like 'Questions';
 mysql> show global status like 'Uptime';
로그인 후 복사

QPS = Questions / Uptime

基于Com_commit和Com_rollback计算出TPS:

 mysql> show global status like 'Com_commit';
 mysql> show global status like 'Com_rollback';
 mysql> show global status like 'Uptime';
로그인 후 복사

TPS = (Com_commit + Com_rollback) / Uptime

另一计算方式:基于Com_select、Com_insert、Com_delete、Com_update计算出QPS

 mysql> show global status where Variable_name in('com_select','com_insert','com_delete','com_update');
로그인 후 복사

等待1秒再执行,获取间隔差值,第二次每个变量值减去第一次对应的变量值,就是QPS

TPS计算方法:

 mysql> show global status where Variable_name in('com_insert','com_delete','com_update');
로그인 후 복사

计算TPS,就不算查询操作了,计算出插入、删除、更新四个值即可。

经网友对这两个计算方式的测试得出,当数据库中myisam表比较多时,使用Questions计算比较准确。当数据库中innodb表比较多时,则以Com_*计算比较准确。

5.2 开启慢查询日志

MySQL开启慢查询日志,分析出哪条SQL语句比较慢,使用set设置变量,重启服务失效,可以在my.cnf添加参数永久生效。

mysql> set global slow-query-log=on  #开启慢查询功能
mysql> set global slow_query_log_file='/var/log/mysql/mysql-slow.log';  #指定慢查询日志文件位置
mysql> set global log_queries_not_using_indexes=on;   #记录没有使用索引的查询
mysql> set global long_query_time=1;   #只记录处理时间1s以上的慢查询
로그인 후 복사

分析慢查询日志,可以使用MySQL自带的mysqldumpslow工具,分析的日志较为简单。

  # mysqldumpslow -t 3 /var/log/mysql/mysql-slow.log    #查看最慢的前三个查询

  也可以使用percona公司的pt-query-digest工具,日志分析功能全面,可分析slow log、binlog、general log。

  分析慢查询日志:pt-query-digest /var/log/mysql/mysql-slow.log

  分析binlog日志:mysqlbinlog mysql-bin.000001 >mysql-bin.000001.sql 

  pt-query-digest --type=binlog mysql-bin.000001.sql 

  分析普通日志:pt-query-digest --type=genlog localhost.log

  5.3 数据库备份

  备份数据库是最基本的工作,也是最重要的,否则后果很严重,你懂得!但由于数据库比较大,上百G,往往备份都很耗费时间,所以就该选择一个效率高的备份策略,对于数据量大的数据库,一般都采用增量备份。常用的备份工具有mysqldump、mysqlhotcopy、xtrabackup等,mysqldump比较适用于小的数据库,因为是逻辑备份,所以备份和恢复耗时都比较长。mysqlhotcopy和xtrabackup是物理备份,备份和恢复速度快,不影响数据库服务情况下进行热拷贝,建议使用xtrabackup,支持增量备份。有兴趣可参考以往博文:http://www.php.cn/

  5.4 数据库修复

  有时候MySQL服务器突然断电、异常关闭,会导致表损坏,无法读取表数据。这时就可以用到MySQL自带的两个工具进行修复,myisamchk和mysqlcheck。

  myisamchk:只能修复myisam表,需要停止数据库

  常用参数:

  -f --force    强制修复,覆盖老的临时文件,一般不使用

  -r --recover  恢复模式

  -q --quik     快速恢复

  -a --analyze  分析表

  -o --safe-recover 老的恢复模式,如果-r无法修复,可以使用此参数试试

-F --fast 정상적으로 닫히지 않은 테이블만 확인

Weibo 데이터베이스 빠르게 복구:

# cd / var/lib/mysql/weibo

# myisamchk -r -q *.MYI

mysqlcheck: myisam 및 모든 innodb 테이블은 데이터베이스를 중지하지 않고도 사용할 수 있습니다. 단일 테이블을 복구하려면 데이터베이스 뒤에 테이블 이름을 공백으로 구분하여 추가하면 됩니다.

공통 매개변수:

-a --all-databases 모든 라이브러리 확인

-r --repair 테이블 복구

-c -- 테이블 확인, 기본 옵션

-a --분석 테이블 분석

-o --optimize 최적화 table

-q --quik 가능한 한 빨리 테이블을 확인하거나 복구합니다.

-F --fast 아직 테이블을 확인하지 않은 테이블만 확인합니다. 정상 종료

Weibo 데이터베이스 신속 복구:

mysqlcheck -r -q -uroot -p123 weibo

5.5 추가적으로 CPU 및 I/O 성능 확인

#CPU 성능 확인

MySQL - 최적화된 그래픽 코드 상세 소개

#매개변수 -P는 CPU 수를 표시하는 것이고, ALL은 모두를 의미하거나, CPU 수만 표시할 수 있습니다. MySQL - 최적화된 그래픽 코드 상세 소개

#I/O 성능 보기

MySQL - 최적화된 그래픽 코드 상세 소개

#Parameter -m은 M 단위로 표시되며 기본값은 K입니다

#%util: 100%에 도달하면 I/O가 매우 바쁘다는 의미입니다.

#await: 요청이 대기열에서 기다리는 시간은 읽기 시간에 직접적인 영향을 미칩니다.

I/O 제한: IOPS(r/s+w/s), 일반적으로 약 1200입니다. (IOPS, 초당 읽기 및 쓰기(I/O) 작업 횟수)

I/O 대역폭: 순차 읽기 및 쓰기 모드에서 SAS 하드 디스크의 이론값은 약 300M/s, SSD 하드디스크의 이론값은 약 600M/s 정도입니다.



위 내용은 MySQL - 최적화된 그래픽 코드 상세 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!