《App后台开发运维与架构实践》第6章 MySQL数据库

6.1 基本架构

  • 服务层

大多数基于网络的客户端/服务端工具都有这一层,这一层主要是处理链接和安全验证。mysql

  • 核心层

这层处理MySQL的核心业务。查询分析、优化、缓存和内存的函数;内建的视图,存储过程,触发器。sql

  • 存储引擎层

存储引擎负责数据的存储和提取。核心层经过存储引擎的API与存储引擎通讯,这样子就遮蔽了不一样存储引擎的差别,使得这些差别对上层查询是透明的。存储引擎之间不会相互通讯,只是简单地响应上层的查询。数据库

6.2 选择版本

MySQL的发展经历了下面的几个里程碑。缓存

  • 1979年,创始人Monty Windenius写了最初的版本。
  • 1996年,发布1.0版本。
  • 1995-2000年,MySQL AB公司成立,引入BDB。
  • 2000年,集成MyISAM和Replication。
  • 2008年,MySQL AB被Sun收购,2009年推出5.1版本。
  • 2009年,Oracle收购Sun,2010年12月推出5.5版本。

MySQL被Oracle收购后,MySQL创始人Monty Windenius主导开发了MariaDB,采用GPL受权许可,彻底兼容MySQL,使用XtraDB存储引擎来代替MySQL的InnoDB存储引擎。安全

因为上面所述的历史缘由,形成了如今有4个MySQL的版本。服务器

  • MySQL社区版:用户群体最大。
  • MySQL企业版:收费。
  • Percona Server版:新特性多。
  • MariaDB版:国内用户很少。

建议开发者选择MySQL社区版,足够应付业务上的需求。网络

6.3 配置文件详解

在Linux中MySQL的配置文件是/etc/my.cnf。多线程

6.4 软件优化

6.4.1 正确使用MyISAM和InnoDB存储引擎

在MySQL 5.1版本中,默认的存储引擎是MyISAM;到了MySQL 5.五、5.6版本,默认的存储引擎是InnoDB。架构

MyISAM基于ISAM(索引顺序访问方法),支持全文索引,但并不是事务安全,不支持外键,使用表级锁。每一个MyISAM表存有3个文件:FRM文件存放表结构,MYD文件存放数据,MYI存放索引。负载均衡

InnoDB是事务性存储引擎,其支持行锁,InnoDB表的行锁也不是绝对的,若是它在执行一个更新的语句时无法肯定更新的范围,也会锁表。InnoDB支持回滚、崩溃恢复、ACID事务控制,InnoDB存储它的表和索引在一张表空间,表空间能够包含多个文件。

MyISAM和InnoDB的主要区别以下。

  • MyISAM支持表锁,InnoDB支持行锁。
  • MyISAM是非事务安全型,InnoDB是事务安全型。
  • MyISAM不支持外键,InnoDB支持外键。

6.4.2 正确使用索引

使用索引的一些原则。

  • 给合适的列创建索引

在where子句中常常须要给检索的列创建索引,或者给链接子句中指定的列创建索引,而不是给select选择列表中的列创建索引。

  • 索引列的值尽量不一样

对于有惟一性的值,索引的效果最好;若是有大量的重复值,索引的效率不好。

  • 使用短索引

对字符类型的列创建索引,只要有可能,都应该指定前缀长度。

  • 利用最左前缀

建立一个n列索引,本质上是MySQL建立了n个索引。多个索引能够起n个索引的做用,能够用索引中最左列的值来匹配,这样的列值叫作最左前缀。

  • 使用like查询时索引会失效

尽可能少使用like查询,对于百万、千万级的数据,能够采用专业的搜索软件来实现。

  • 不能滥用索引

索引不是越多越好,使用索引须要恰到好处。过分使用索引会有下面的问题:索引会占用额外的磁盘空间,下降性能;当更新数据时索引必须更新,花费时间更长;有可能使MySQL选择到不是最优的索引,增长查询优化的时间。

6.4.3 避免使用select *

使用“select *”有下面的坏处:

  • 在select语句执行的过程当中,“select *”从数据库中返回的结果更多,下降了查询的速度。
  • 过多的返回结果会增大服务器返回给App端的数据的传输量。过大的传输量很容易形成请求的失效。

6.4.4 字段尽量地设置为NOT NULL

6.5 硬件优化

6.5.1 增长物理内存

MySQL读写数据最大的性能瓶颈就是磁盘IO,从减小磁盘IO方面提升性能是个重要的方向。经过加大物理内存能够采起提高文件系统性能,减小磁盘IO。另外,MySQL中也用了大量的内存来提升性能,配置参数以下。

  • thread_cache_size:服务端线程缓存。
  • sort_buffer_size:每一个链接须要使用buffer时,分配的内存大小。
  • query_cache_size:查询缓存的大小。
  • query_cache_limit:单次查询缓冲区的大小。

6.5.2 增长应用缓存

把应用的热数据存储在缓存中,若是缓存中有数据就不须要到数据库读取数据,从而达到提升性能的目的。

应用的缓存有如下两种。

  • 本地缓存:把数据放在服务器的内存或文件中。
  • 分布式缓存:Redis(数据能够持久化)或Memcache。

6.5.3 用固态硬盘代替机械硬盘

6.5.4 SSD硬盘+SATA硬盘混合存储方案

6.6 架构优化

6.6.1 分表

当项目上线后,随着用户的增加,有些数据表的规模会以几何级增加,当数据达到必定规模后查询读取性能就降低不少,这时要考虑分表了。

  • 水平拆分:把一张表的数据分别保存在不一样的表。
  • 垂直拆分:把一张表的字段分别保存在不一样的表。

分表的存储引擎是MyISAM,能够利用MERGE存储引擎将拆分的表合并成一张表。若是是InnoDB,也能经过alter table命令把InnoDB变为MyISAM。

6.6.2 读写分离

随着App的不断迭代和推广,数据不断增多,数据库的压力也愈来愈大,对MySQL的基础优化可能达不到最终的效果。所以采起数据库的读写分离策略进行优化。

读写分离是把对数据库的读和写操做分开对应于主/从数据库服务器,主数据库提供写操做,从数据库提供读操做(能够有多个数据库)。由于大多数业务是以读为主,所以多个从数据库能有效减轻数据库的压力。

当主数据库进行写操做时,数据要同步到从数据库,这样才能有效保证数据库完整性。这称为数据库的主从复制。

MySQL主从复制基于主服务器在二进制日志(binlog)中跟踪全部对数据库的更改实现。所以要进行复制,必须在主服务器上启用二进制日志。

主从复制的延迟问题,通常来讲从数据库的压力比主数据库大多了,很是容易致使延迟。

延迟的解决方案以下。

  • 定位延迟的瓶颈,若是是由于IO压力大,那么能够考虑采用升级硬件的方案,如把硬盘更换为SSD硬盘。
  • 若是是由于单线程从relaylog中执行MySQL语句致使延迟,能够采用MySQL 5.6以上版本的多线程方案,或者采用Tungsten为表明的第三方并行复制工具。
  • 若是以上两种方案都不起做用,就要考虑采用分库策略。

6.6.3 分库

当数据规模不断增打,分表和读写分离可能都知足不了系统的性能需求,这时须要考虑分库,即把不一样的数据表部署到不一样的数据库集群上。

支持数据库分库的关系型数据库分布式处理软件Mycat,它以代理服务器的形式位于应用服务器与后台数据库之间,因为其是无状态,所以很容易部署MyCat集群实现负载均衡。对外开放的接口是MySQL通讯协议,将应用服务器传过来的SQL语句按照路由的规则拆解转发到不一样的后台数据库,并把结果汇总并返回。

MyCat能够把一个逻辑上的数据库和数据表对应到物理上真实的数据库和数据表,用户只须要按照逻辑上的结构操做相关数据就行,遮蔽了物理上的差别。

6.7 SQL慢查询优化

SQL慢查询是指执行超过必定时间的SQL查询语句,把这些SQL查询语句记录到慢查询日志,方便开发人员找出有性能问题的SQL,针对这些SQL查询语句进行分析调优。

配置选项中慢查询相关的3个参数以下。

  • long_query_time:定义慢查询的时间,SQL查询语句执行时间大于该参数设置时间的SQL都会被记录下来,支持小于1秒的设置。
  • slow_query_log:设置是否打开慢查询日志的开关。
  • slow_query_log_file:设置慢查询日志文件的路径。

配置慢查询有两种方法。

  • 经过命令行设置,当即生效,可是在MySQL服务重启后失效。
set global long_query_time=1;
set global slow_query_log=on;
set global slow_query_log_file='/data/slow.log';
  • 在/etc/my.conf中新增下面的配置选项,重启MySQL服务后生效。
[MySQLd]
long_query_time=1
slow_query_log=on
slow_query_log_file=/data/slow.log

可使用MySQL自带的工具mysqldumpslow分析慢查询日志,例如,查看最慢的前3个SQL查询的命令格式以下。

mysqldumpslow -t 3 /data/slow.log

开启慢查询日志后,可在系统状态中查看慢查询数。

show global status like '%slow%';

要分析慢查询语句,须要使用到MySQL的explain命令。

相关文章
相关标签/搜索