您的位置:首页 > 数据库 > MySQL

淘宝商品库MySQL优化实践的学习

2013-02-03 22:49 253 查看


转自:http://ourmysql.com/archives/1191

淘宝商品库是淘宝网最核心的数据库之一,采用MySQL主备集群的架构,特点是数据量大且增长速度快,读多写少,对安全性要求高,并发请求高。由于MySQL最初的设计不是用来存储大规模数据的,但淘宝的数据量非常惊人,所以在I/O方面,尤其是CPU I/O层面会有很大瓶颈,因此淘宝的主要目标也是解决IO方面的瓶颈问题。

以下内容整理自淘宝的演讲,演讲内容包括淘宝商品库硬件的选型决策,安全性和性能的平衡,特别是创新引入PCI-E Flash卡和Flashcache作为Cache提高IO性能,在保证安全性的前提下就包括MySQL、InnoDB引擎、文件系统、系统Page Cache、 IO调度算法、DM层(Flashcache)、Raid卡、设备驱动在内的整条IO路径的Cache进行优化,进一步挖掘了系统IO的潜能,重点介绍优化过程中的一些经验教训、测量手段和工具。

一、商品库项目背景介绍以及约束

淘宝的产品线很多,以淘宝的商品库为例,商品库是卖家卖的所有的商品信息数据库。我们都知道淘宝商品是非常多的,有可能是十亿级别的,而且淘宝每年的数据都会翻番,在淘宝上,由于卖家是非常活跃的,所以每天的交易数也是非常多的,而且每天的访问量也是相当大的。更比如在一些高峰期,比如节假日,像光棍节促销,当时一天的访问量可就是平常的好几倍,几十倍的样子。

商品库(单机,测试)情况

[align=left]无复杂查询,离散度高[/align]

[align=left]记录数:1亿条键值对[/align]

[align=left]记录大小:100字节[/align]

[align=left]数据文件:170G[/align]

[align=left]访问热点情况:20%的键占用55%的访问量[/align]

[align=left]键读写比例: 10:1[/align]

硬件选择

主机: Dell; PowerEdge C2100;

处理器: physical = 2, cores = 12, virtual = 24

内存: 96 G

RAID卡:LSI MegaSAS 9260/512MB Memory

PCI-E Flash卡: Fusion-io ioDrive 320GB/MLC

硬盘: SEAGATE ST3300657SS 300G x 12

软件选择

发行版: Red Hat Enterprise Linux Server release 5.4

内核: Kernel | 2.6.18-164.el5

文件系统:Ext3

Flashcache: FB内部版本

MySQL 版本: 5.1.48-log Source

二、技术要求和方案

1、商品库技术要求:

高可用,安全第一。因为淘宝卖家的商品都存在上面,一大堆数据,商品没了,淘宝会非常的难受;

高性能,性能平稳,性价比高。因为数据量大,而且未来增长的速度会非常快,以前系统是跑在Oracle的小机上面,它的成本是非常高的。现在改用高性能的PC服务器,性价比较高,而且Oracle数据库的能力不足以维持淘宝的更新速度;

控制运维风险。Oracle是有一套完整的工具,利用它们我们可随时查看相关的状态和预测它的一些变化。MySQL作为开源产品,这部分的功能稍显欠缺,因此就需要根据运维团队和DBA的需求去开发一些工具。

2、调优指导思想

杜绝拍脑袋,理论(源码)指导+精确测量+效果验证

内存为王

数据访问规律导向,随机数据和顺序数据尽量分离

尽量提高IO的利用率,减少无谓的IO能力浪费

在安全性的前提下,尽可能的利用好系统各个层次cache

3、技术方案

[align=left]MySQL数据库集群,数据水平切割,主从备份[/align]

[align=left]采用高性价比PC服务器,大内存,强劲CPU,可靠性高[/align]

[align=left]采用高性能PCI-E Flash卡作为cache, 提高系统的IO性能[/align]

[align=left]充分利用系统各部件的cache, 大胆采用新技术[/align]

[align=left]充分考虑容灾,在各个层面考虑数据的安全性[/align]

4、调优工具

[align=left]源码+emacs+大脑[/align]

[align=left]必备工具:systemtap、oprofile、latencytop 、blktrace/btt/seekwatcher、aspersa、tcprstat、sar、gdb[/align]

[align=left]自制工具:bash脚本、gnuplot脚本[/align]

三、系统资源规划

内存分配:

MySQL

InnoDB buffer pool

OS pagecache

驱动程序

IO能力分配:

读能力,零散读,提高IOPS

写能力,集中写,提高吞吐量

Cache分配:

MySQL内部cache

匿名页面/文件页面

Flashcache 混合存储

Raid卡内部cache

1、MySQL数据库

考虑因素:

主从备份带来的性能影响

复杂数据查询操作是否需要预留内存以及上限

数据备份dump对系统的影响,避免系统swap

开启binlog带来的性能开销

限制最大链接数

#############################

[align=left]max_binlog_cache_size=2G[/align]

[align=left]max_binlog_size = 500M[/align]

[align=left]max_connections = 1020[/align]

[align=left]max_user_connections=1000[/align]

[align=left]query_cache_size = 30M[/align]

2、InnoDB引擎

考虑因素:

尽可能大的BP(buffer pool)

日志和数据分设备存储

离散数据走direct-IO,顺序日志走buffered-IO

减少脏页的同步,提高命中率

减少锁对多核CPU性能的影响

提高底层存储默认的IO能力

#############################

[align=left]innodb_buffer_pool_size = 72G[/align]

[align=left]innodb_flush_method = O_DIRECT[/align]

[align=left]innodb_sync_spin_loops=0[/align]

[align=left]innodb_log_group_home_dir = /u02/[/align]

[align=left]innodb_io_capacity=2000[/align]

[align=left]innodb_thread_concurrency = 64[/align]

3、高速页缓存

考虑因素:

page资源倾斜给数据库, 尽量不浪费,兼顾临时内存申请

避免NUMA架构带来的zone内存分配不均而导致的swap现象

cache大部分由InnoDB日志产生,适时清除,限制page数量

#############################

[align=left]# numactl -interleave=all mysqld[/align]

[align=left]# sysctl vm.drop_caches = 1[/align]

[align=left]vm.swappiness = 0[/align]

[align=left]vm.dirty_ratio = ?[/align]

[align=left]vm.dirty_background_ratio =?[/align]

[align=left]vm.pagecache = ?[/align]

4、文件系统

考虑因素(选择):

Ext3/4

Xfs

考虑因素(配置):

减少元数据变化产生的IO

对混合存储系统友好

关闭barrier

#############################

[align=left]/dev/mapper/cachedev (rw,noatime,nodiratime,barrier=0) /u01[/align]

[align=left]/dev/sda12 (rw,barrier=0) /u02[/align]

5、IO调度

考虑因素:

调度算法对减少磁头移动的效果

关闭预读

设备队列长度

#############################

[align=left]sda | [deadline] 128[/align]

[align=left]sdb | [deadline] 128[/align]

6、混合存储(Flashcache)

考虑因素

结合磁盘的大容量,PCI-E Flash卡的高随机读写性能优点

数据尽可能多停留在PCI-E Flash卡上,提高读写命中率

减少同步次数,保留磁盘的IO能力

适时同步数据,减少安全风险

#############################

[align=left]dev.flashcache.dirty_thresh_pct = 90[/align]

[align=left]dev.flashcache.cache_all = 0[/align]

[align=left]dev.flashcache.fast_remove = 1[/align]

[align=left]dev.flashcache.reclaim_policy = 1[/align]

7、Raid卡

考虑因素:

逻辑分卷

Cache使用写优先,读少分配(数据无相关性效果不好)

数据安全和raid level

少预读

#############################

[align=left]Controller | LSI Logic / Symbios Logic LSI MegaSAS 9260 (rev 03) [/align]

[align=left]Model | LSI MegaRAID SAS 9260-8i, PCIE interface, 8 ports[/align]

[align=left]Cache | 512MB Memory, BBU Present[/align]

[align=left]BBU | 95% Charged, Temperature 28C, isSOHGood=[/align]

[align=left]VirtualDev Size RAID Level Disks SpnDpth Stripe Status Cache[/align]

[align=left]0(no name) 278.875 GB 1 (1-0-0) 2 1-1 64 Optimal WB, RA[/align]

[align=left]1(no name) 1.361 TB 1 (1-0-0) 2 5-5 64 Optimal WB, RA[/align]

8、存储设备驱动

考虑因素:

减少IO的抖动,提高IOPS

提高寿命

关闭或减少预读

#############################

PCI-E Flash卡驱动:

$cat /etc/modprobe.d/iomemory-vsl.conf

[align=left]options iomemory-vsl use_workqueue=0[/align]

[align=left]options iomemory-vsl disable-msi=0[/align]

[align=left]options iomemory-vsl use_large_pcie_rx_buffer=1[/align]

四、具体优化内容

1、安全保证

Raid卡带Flash,掉电保护,raid level10防止磁盘损害

PCI-E卡自身有日志系统,恢复时间最差10分钟

Ext3文件系统带日志保护

Flashcache上的cache数据最多24小时都会同步到SAS盘

数据库Innodb引擎本身有redo日志,数据安全校验,高级别日志同步

MySQL主从备份

商品库应用方有事务日志

2、性能保证

解决IO瓶颈:

高速PCI-E Flash卡做Cache,读写速度可达800/500M

10 x SAS 300G 存放离散度高数据文件

2 x SAS 300G 存放顺序binlog和trx日志

控制数据库脏页面的刷新频率和强度

优化操作系统的pagecache,资源倾斜, 杜绝swap发生

优化文件系统减少meta数据的产生,以及写入延迟

优化IO调度器和预读

开启raid卡的读写cache

优化设备驱动,适应高强度的读写请求,减少jitter

解决CPU瓶颈:

业务上优化掉复杂查询

优化自旋锁

3、运维保证

数据预热:

支持热点数据每秒150M从磁盘直接加载到混合存储

数据库重新启动,无需重新预热

数据库DDL 操作:

控制数据表的大小,让DDL时间可接受

减少DDL对性能的冲击

混合存储cache:

通过设置白名单,减少诸如备份操作对cache的干扰

混合存储cache可管理

五、优化成果

经过优化从机器的运算能力上来看的话,比原来要高很多,从设备的总体的价格来看的话,相比原来小机的价格,现在的价格相当于原来的几分之一。具体细节为:

充足的容量规划,可对抗突增业务,满足未来几年业务增长

系统总体运行平稳,系统负载CPU util <50%,磁盘 util <10%,PCI-E Flash卡 util < 20%

QPS/36000,其中读/32800,写/3200

请求平均延时时间:260微秒(包括网络时间)

掉电和操作系统失效的情况下,数据无丢失

第一次预热时间半个小时以内,之后只需几分钟

六、一些重要讨论问题的分享

1、优化MySQL的过程中有没有涉及到水平分片,或者垂直分片,大概的策略是什么?

这块因为之前的MySQL从业务的角度上我们已经优化过了。涉及到业务上的复杂SQL查询,基本上都把它当成Key-Value来处理。所以说在水平切割上就变得非常简单,只需要根据用户的这些ID把它平均地分割到集群的各个机器上去即可,所以说这块会做得非常简单,也不会有那些非常复杂的SQL。

2、淘宝在去Oracle化过程中,最终选择了MySQL。是怎样的原因使你没有去选择NoSQL或是其它技术来作为提高性能优化方面的考虑呢?

主要考虑到以下这几个方面,第一是因为MySQL已经是非常成熟的产品,而且也是经过大规模系统考验的,所以它的稳定性,开发的便捷性还是比较有优势的。从另外一个角度上来讲,也能最大限度的保障历史系统的迁移,这是第一个方面。此外,之所以没有采用NoSQL主要基于以下几个方面的考虑,第一由于市面上流行的NoSQL方案相对来说都比较年轻。然而对于淘宝商品库来讲,它是作为淘宝非常重要的库,是不允许我们有丝毫闪失的,不能出现任何问题。第二点,现在流行的NoSQL方案,从程序的架构上来讲,就是对传统数据库的过程进行了精简。但是它的存储、内存等问题其实还是存在的。只是解决问题的思路变得轻量。但是这些问题依旧在的。现在我们在数据库层面,因为平常都是从引擎层面去开发,在原码级别去做优化,甚至包括操作系统级的优化。所以我们可以很清楚的知道问题在哪里,应该解决什么问题,最终能达到什么样的效果。那这样做的好处就是我们既能解决问题,又能充分利用传统数据库的方便性以及稳定性。

3、优化过程中具体还做了哪些工作?

优化听起来好像没什么内容,但实际上我们做了很多的工作。首先要有明确的目标,我们的目标是什么,是为了提高性能还是提高安全性,还是提高其他的什么指标,这个目标要清晰和完整。第二点是测量,你不能说,我拍脑袋看到某某某,他怎么优化的,然后我也上去这样照着优化,这不是我们做事的风格。我们要测量现在的瓶颈在哪里?我们的系统遇到了什么问题,这点我们会借助一些工具来实现。比如说测量CPU的使用,我们会非常精确的去测量I/O的使用,比如说在设备层面,I/O是怎么使用的,在软件系统层面I/O是怎么使用的,在数据库引擎层面I/O是怎么使用的。通过非常精细的测量,我们就能找出,对I/O使用不恰当的地方,然后就是要去解决这种问题,为什么会比设想的要多呢,或者为什么要比设想的要慢呢,我们会针对此类问题做理论上的分析,甚至会去翻翻源码它到底是怎么实现的,这样我们就可以比较有针对性将问题解决。

4、优化过程中有哪些创新和亮点?

这次有一个创新,用高速的SSD盘去做2级Cache,因为传统的MySQL数据库都是引擎里面发挥pool的功能,然后直接在软件系统存储。就是引擎里边吐出来东西到那边去,命不中东西从磁盘读进去,由于是传统的磁盘,所以它的寻道时间是非常长的。那它的I/O其实是不高的,但是吞吐量大。为了解决问题,我们采用一种叫PCI-E的Flash卡。这个卡的特点是,它是电子盘,所以它没有寻道时间,随机特性非常好,同时它的读写吞吐量非常高,读能大概到1G,写能达到几百兆。采用其作为二级cache,数据从InnoDB引擎这边出来,不到磁盘去,而是先写到高速卡中。由于高速卡很快,它完成的I/O
PS是微秒级的,几十微秒就写完了,然后传统磁盘却是十个毫秒级的。所以从数据库引擎的角度来看,只需写入几十微妙就解决了。写入数据开始是随机的,随机累计起来以后它就不是随机的,我们通过把它排序,就可以使其变为顺序的。然后我们再把这顺序的数据利用磁盘的高吞吐量特点,由于数据库半夜时候它可能会比较轻松。那这时候,把它导到磁盘中去,这样就大大的提高整个系统的IO能力。这是比较大的一个创新点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: