文章转自:http://mp.weixin.qq.com/s?__biz=MzA4Nzg5Nzc5OA==&mid=206762682&idx=1&sn=1233ed1496d7fd059d247329f3d3a183&scene=5#rd
杨尚刚,原新浪高级DBA,现在在美图负责数据库,微博zolker。2011年加入新浪,早期主要负责新浪微博核心数据库的架构设计,后期主要负责数据库平台的软硬件优化。
MySQL数据库性能优化方面的一些策略
MySQL性能优化的几点常规优化策略:
读写分离
sharding
参数优化
索引优化
系统优化
硬件优化
读写分离是一种比较常规的优化策略,这个也很容易理解和实现,方案的主要目的还是做到读写的隔离,减少相互干扰,互联网的大多数场景都是读多写少的业务,所以这种策略都是没问题的。
sharding拆分是一种通过一定的策略把数据重新分布的策略,主要解决单实例写入压力或容量过大的问题。但是sharding带来的问题也是很多的,比如运维管理成本增加和业务访问的复杂度增加。
sharding这种策略在微博早期压力大时候用的还是非常多的,天天各种拆分搞的很嗨,但是其实后来发现拆分很没意思,冷静下来发现其实很多拆分并不是那么紧迫或者没必要。
天天忙于拆分带来的问题就是导致没有时间做更深入优化和自动化方面的工作,所以拆分一定要做到适时适度。
sharding拆分主要分成两个维度,垂直拆分和水平拆分,水平拆分主要是在不改变schema的前提下重新分布数据,而垂直拆分主要是在业务层面解耦。基本上两者要结合使用。
所以控制拆分粒度是非常重要的 ,从现在的硬件水平上,单个sharding控制在2-3亿以内都是没问题的。
微博当时最大的单表在60亿+,单表容量过T,DBA有的时候还要“懒”一些的。
其实MySQL另外一个比较容易让人诟病的就是主从复制延时问题,这个主要还是早期MySQL复制单线程设计的问题。
而造成延时的原因其实主要是两点,主库写入过大导致从库SQL单线程性能跟不上,或者从库读压力过大影响了SQL单线程。当然现在MySQL 5.6也开始引入并行复制,但是粒度依然很大,还是基于库的复制,所以提升有限。
刚从这两点原因的主要诱发原因还是IO瓶颈的因素居多,所以解决延时问题首选的还是使用高性能IO存储,次之使用并行复制方案,再次之采用sharding拆分。
再讲一下 schema优化 ,主要考虑的是表结构的字段设计和索引设计合理性,以及分表策略是否合理。对后期管理优化都是非常重要的。
列类型够用就好,越小越好,简单就好,数据类型越简单越好,能用整型尽量不用字符串,比如存时间和字符串 ,避免Null,主键尽可能使用自增,不建议使用字符串,尤其是innodb单表索引数不要超过五个(5.6有待测试) 索引设计的差异性,避免冗余索引,字符集选择,尽量UTF8,emoji字符选择UTF8mb4。
然后是MySQL的一些参数优化策略,主要是InnoDB层面的参数优化,MySQL Server层参数优化性能提升有限
innodb_file_per_table
innodb_buffer_pool_size
innodb_flush_log_at_trx_commit= 0 1 2 (和数据安全有关)
innodb_log_file_size
innodb_page_size
sync_binlog(和数据安全有关)
尤其要注意
innodb_flush_log_at_trx_commit和sync_binlog的设置,如果对数据安全要求高,建议都设置为1
硬件优化主要是,NUMA、大内存和SSD相关的使用和优化
NUMA在当前这种多核架构下,理论优化是有价值的,不过实际测试结果提升有限,而且还增加了管理成本。所以像Twitter的MySQL分支也建议关闭NUMA。之所以NUMA不起作用主要还是因为这种跨Node的访问对MySQL整体latency影响有限。
而SSD更是在MySQL性能提升的利器。微博知名大V曾说过“近十年真正改变数据库技术的就是闪存技术”,而且像阿里的去IOE也是离不开的SSD的应用的。
当时在新浪的应用模式是2U服务器,10块SSD做Raid5 ,性能还是不错的。
echo noop/deadline >/sys/block/[device]/queue/scheduler(性能提升最明显)
echo 2 > /sys/block/[device]/queue/rq_affinity (CentOS 6.4以上)
echo 0 > /sys/block/[device]/queue/add_random (关闭文件系统barrier)
针对SSD的系统参数优化:
针对SSD的MySQL参数优化在5.5以上,提高innodb_write_io_threads和innodb_read_io_threads,innodb_io_capacity需要调大,日志文件和redo放到机械硬盘,undo放到SSD atomic write,不需要Double Write,Buffer InnoDB压缩,降低SSD寿命磨损,单机多实例+cgroup。
问题一:关于amazon的aurora的实现难度
从amazon披露的信息来看,难度还是比较大的。首先从上层数据库层面已经和原生MySQL差距很大了,应该也是自己重写或改写的,这个之前微博上也有过很多讨论,另外在文件系统和硬件存储上,amazon也都是深度定制的,相当于是把原来InnoDB的一些数据容错安全策略下防到文件系统和存储层面实现。
问题二:现在用PCI-E卡吗?
美图现在不用 ,原来新浪用了不少的,单从iops是要高的,实际跑业务差距不大,除非你的读写量超大。
问题三:除了刚才讲到的提高IO,降低主从延时有哪些建议?
那就是并行复制和拆分有效了,之前也有一些从库预读方案,预读Relay log,提升不大。
问题四:为什么建议把redo放在机械盘上呢?
文件读写特性有关,redo主要是顺序写为主,SSD更擅长随机写,实际我们也是都放SSD的,其实目前SSD寿命都还不错了,放在一起不区分也没什么问题。
问题五:什么场景不需要拆分?
就是看你数据量和访问量。从一般场景来说 单个sharding控制在2亿以内都是比较合理的,还是要根据自己的场景 判断瓶颈到底是不是只能sharding解决 ,能不用就不用吧。一般大表加字段用pt-online-schema也可以。不过像我们当时的那个60亿大表,估计要加字段就确实很麻烦了。
问题六:对原版MHA修改主要修改的哪些方面?galera有人用吗?
我们当时做的主要重写的他的切换逻辑部分。galera原生应该没人用,大部分用的还是percona基于galera封装的percona xtradb cluster。据我所知搜狐和去哪儿都在用,坑还是不少的,需要对代码底层有把控力的更好一些。
问题七:你们修改的MHA部分可以分享一下吗?你们用MariaDB吗,这个可以并行复制?你们用触发器吗?
我们修改的部分主要还是Python重写的核心切换逻辑,日志处理还是原生的。MariaDB可以并行复制,我们不要MariaDB,实际线上使用国内也不多。尽量不在线上使用触发器。
问题八:能讲讲SQL优化嘛?
SQL优化涉及到的东西就比较杂了,MySQL等值查询最好,尽可能好的利用索引,善用explain和pt-query-digest。
问题九:你们用MHA遇到了哪些问题,MHA自动切换如果丢了数据,如何恢复?PXC和MHA生产中如何选择,另外您提到您这边部分手动,部分自动,是什么原因?
MHA只是尽可能保证不丢,如果切换完数据补全完还有问题,只能看看业务日志是否可以恢复。PXC的限制还是很多的,比如跨IDC和集群节点数量等,运维成本也远高于原版。目的是全部自动,一些核心重要的业务可能需要人工介入判断,会有端口分级的策略。
问题十:官方的fabric怎样?
目前还在lab阶段,离生产还有距离。
问题十一:读写分离,你们是程序员写的不同IP吗?还是用的啥代理?
DNS域名。当时也开发过几个版本中间件,各种原因,线上使用的也不是很广泛。其实当时微博使用的也是类似TDDL的做法,proxy封装在前端。
问题十二:说说备份,冷备,mysqldump、xtrabackup您什么情况下用什么软件,说说原因,给点建议
一般使用xtrabackup就可以了,除非你要做逻辑备份,使用mysqldump。