MySQL数据库优化实践

7 5th, 2011 | Posted by jacky | Filed under 大话技术

最近一段时间,我们整理了一些关于Percona,Linux,Flashcache,硬件设备的优化经验,分享给大家:

硬件

1.开启BBWC

RAID卡都有写cache(Battery Backed Write Cache),写cache对IO性能的提升非常明显,因为掉电会丢失数据,所以必须由电池提供支持。电池会定期充放电,一般为90天左右,当发现电量低于某个阀值时,会将写cache策略从writeback置为writethrough,相当于写cache会失效,这时如果系统有大量的IO操作,可能会明显感觉到IO响应速度变慢。目前,新的RAID卡内置了flash存储,掉电后会将写cache的数据写入flash中,这样就可以保证数据永不丢失,但依然需要电池的支持。

解决方案有两种:1.人工触发充放电,可以选择在业务低谷时做,降低对应用的影响;2.设置写cache策略为force write back,即使电池失效,也保持写cache策略为writeback,这样存在掉电后丢失数据的风险。

目前,有一些硬件厂家提供了电容供电的RAID卡,没有电池充放电的问题,可以联系自己的硬件厂商。

2.RAID卡配置

关闭读cache:RAID卡上的cache容量有限,我们选择direct方式读取数据,从而忽略读cache。

关闭预读:RAID卡的预读功能对于随机IO几乎没有任何提升,所以将预读功能关闭。

关闭磁盘cache:一般情况下,如果使用RAID,系统会默认关闭磁盘的cache,也可以用命令强制关闭。

以上设置都可以通过RAID卡的命令行来完成,比如LSI芯片的RAID卡使用megacli命令。

3.开启Fastpath功能

Fastpath是LSI的新特性,在RAID控制器为SSD做了了优化,使用fastpath特性可以最大程度发挥出SSD的能力。如果使用SSD做RAID的方式,可以开启fastpath功能。关于fastpath特性,可以从LSI官网下载资料,并咨询自己的硬件提供商。

4.Fusionio参数调整

基本上,Fusionio无需做任何调整,下列三个参数可能会提升性能:

options iomemory-vsl use_workqueue=0

对于fusionio设备,忽略Linux IO调度,相当于使用NOOP。

options iomemory-vsl disable-msi=0

开启MSI中断,如果设备支持,则打开。

options iomemory-vsl use_large_pcie_rx_buffer=1

打开Large PCIE buffer,可能会提升性能。

操作系统

1.IO调度算法

Linux有四种IO调度算法:CFQ,Deadline,Anticipatory和NOOP,CFQ是默认的IO调度算法。完全随机的访问环境下,CFQ与Deadline,NOOP性能差异很小,但是一旦有大的连续IO,CFQ可能会造成小IO的响应延时增加,所以数据库环境建议修改为deadline算法,表现更稳定。我们的环境统一使用deadline算法。

IO调度算法都是基于磁盘设计,所以减少磁头移动是最重要的考虑因素之一,但是使用Flash存储设备之后,不再需要考虑磁头移动的问题,可以使用NOOP算法。NOOP的含义就是NonOperation,意味着不会做任何的IO优化,完全按照请求来FIFO的方式来处理IO。

减少预读:/sys/block/sdb/queue/read_ahead_kb,默认128,调整为16

增大队列:/sys/block/sdb/queue/nr_requests,默认128,调整为512

2.NUMA设置

单机单实例,建议关闭NUMA,关闭的方法有三种:1.硬件层,在BIOS中设置关闭;2.OS内核,启动时设置numa=off;3.可以用numactl命令将内存分配策略修改为interleave(交叉),有些硬件可以在BIOS中设置。

单机多实例,请参考:http://www.hellodb.net/2011/06/mysql_multi_instance.html

3.文件系统设置

我们使用XFS文件系统,XFS有两个设置:su(stripe size)和sw(stirpe width),要根据硬件层RAID来设置这两个参数,比如10块盘做RAID10,条带大小为64K,XFS设置为su=64K,sw=10。

xfs mount参数:defaults,rw,noatime,nodiratime,noikeep,nobarrier,allocsize=8M,attr2,largeio,inode64,swalloc

数据库

1.Flashcache参数

创建flashcache:flashcache_create -b 4k cachedev /dev/sdc /dev/sdb

指定flashcache的block大小与Percona的page大小相同。

Flashcache参数设置:

flashcache.fast_remove = 1:打开fast remove特性,关闭机器时,无需将cache中的脏块写入磁盘。

flashcache.reclaim_policy = 1:脏块刷出策略,0:FIFO,1:LRU。

flashcache.dirty_thresh_pct = 90:flashcache上每个hash set上的脏块阀值。

flashcache.cache_all = 1:cache所有内容,可以用黑名单过滤。

flashecache.write_merge = 1:打开写入合并,提升写磁盘的性能。

2.Percona参数

innodb_page_size:如果使用fusionio,4K的性能最好;使用SAS磁盘,设置为8K。如果全表扫描很多,可以设置为16K。比较小的page size,可以提升cache的命中率。

innodb_adaptive_checkpoint:如果使用fusionio,设置为3,提高刷新频率到0.1秒;使用SAS磁盘,设置为2,采用estimate方式刷新脏页。

innodb_io_capacity:根据IOPS能力设置,使用fuionio可以设置10000以上。

innodb_flush_neighbor_pages = 0:针对fusionio或者SSD,因为随机IO足够好,所以关闭此功能。

innodb_flush_method=ALL_O_DIRECT:公版的MySQL只能将数据库文件读写设置为DirectIO,对于Percona可以将log和数据文件设置为direct方式读写。但是我不确定这个参数对于innodb_flush_log_at_trx_commit的影响,

innodb_read_io_threads = 1:设置预读线程设置为1,因为线性预读的效果并不明显,所以无需设置更大。

innodb_write_io_threads = 16:设置写线程数量为16,提升写的能力。

innodb_fast_checksum = 1:开启Fast checksum特性。

监控

1.fusionio监控:fio-status命令

Media status: Healthy; Reserves: 100.00%, warn at 10.00%

Thresholds: write-reduced: 96.00%, read-only: 94.00%

Lifetime data volumes:

Logical bytes written : 2,664,888,862,208

Logical bytes read    : 171,877,629,608,448

Physical bytes written: 27,665,550,363,560

Physical bytes read   : 223,382,659,085,448

2.flashcache监控:dmsetup status

read hit percent(99)

write hit percent(51)

dirty write hit percent(44)

–EOF–

MySQL单机多实例方案

6 28th, 2011 | Posted by jacky | Filed under 大话技术

MySQL单机多实例方案,是指在一台物理的PC服务器上运行多个MySQL数据库实例,为什么要这样做?这样做的好处是什么?

1.存储技术飞速发展,IO不再是瓶颈

普通PC服务器的CPU与IO资源不均衡,因为磁盘的IO能力非常有限,为了满足应用的需要,往往需要配置大量的服务器,这样就造成CPU资源的大量浪费。但是,Flash存储技术的出现改变了这一切,单机的IO能力不再是瓶颈,可以在单机运行多个MySQL实例提升CPU利用率。

2.MySQL对多核CPU利用率低

MySQL对多核CPU的利用率不高,一直是个问题,5.1版本以前的MySQL,当CPU超过4个核时,性能无法线性扩展。虽然MySQL后续版本一直在改进这个问题,包括Innodb plugin和Percona XtraDB都对多核CPU的利用率改进了很多,但是依然无法实现性能随着CPU core的增加而提升。我们现在常用的双路至强服务器,单颗CPU有4-8个core,在操作系统上可以看到16-32 CPU(每个core有两个线程),四路服务器可以达到64 core甚至更多,所以提升MySQL对于多核CPU的利用率是提升性能的重要手段。下图是Percona的一份测试数据:

3.NUMA对MySQL性能的影响

我们现在使用的PC服务器都是NUMA架构的,下图是Intel 5600 CPU的架构:

NUMA的内存分配策略有四种:

1.缺省(default):总是在本地节点分配(分配在当前进程运行的节点上);

2.绑定(bind):强制分配到指定节点上;

3.交叉(interleave):在所有节点或者指定的节点上交织分配;

4.优先(preferred):在指定节点上分配,失败则在其他节点上分配。

因为NUMA默认的内存分配策略是优先在进程所在CPU的本地内存中分配,会导致CPU节点之间内存分配不均衡,当某个CPU节点的内存不足时,会导致swap产生,而不是从远程节点分配内存。这就是所谓的swap insanity现象。

MySQL采用了线程模式,对于NUMA特性的支持并不好,如果单机只运行一个MySQL实例,我们可以选择关闭NUMA,关闭的方法有三种:1.硬件层,在BIOS中设置关闭;2.OS内核,启动时设置numa=off;3.可以用numactl命令将内存分配策略修改为interleave(交叉),有些硬件可以在BIOS中设置。

如果单机运行多个MySQL实例,我们可以将MySQL绑定在不同的CPU节点上,并且采用绑定的内存分配策略,强制在本节点内分配内存,这样既可以充分利用硬件的NUMA特性,又避免了单实例MySQL对多核CPU利用率不高的问题。

资源隔离方案

1.CPU,Memory

numactl –cpubind=0 –localalloc,此命令将MySQL绑定在不同的CPU节点上,cpubind是指NUMA概念中的CPU节点,可以用numactl –hardware查看,localalloc参数指定内存为本地分配策略。

2.IO

我们在机器中内置了fusionio卡(320G),配合flashcache技术,单机的IO不再成为瓶颈,所以IO我们采用了多实例共享的方式,并没有对IO做资源限制。多个MySQL实例使用相同的物理设备,不同的目录的来进行区分。

3.Network

因为单机运行多个实例,必须对网络进行优化,我们通过多个的IP的方式,将多个MySQL实例绑定在不同的网卡上,从而提高整体的网络能力。还有一种更高级的做法是,将不同网卡的中断与CPU绑定,这样可以大幅度提升网卡的效率。

4.为什么不采用虚拟机

虚拟机会耗费额外的资源,而且MySQL属于IO类型的应用,采用虚拟机会大幅度降低IO的性能,而且虚拟机的管理成本比较高。所以,我们的数据库都不采用虚拟机的方式。

5.性能

下图是Percona的测试数据,可以看到运行两个实例的提升非常明显。

高可用方案

因为单机运行了多个MySQL实例,所以不能采用主机层面的HA策略,比如heartbeat。因为当一个MySQL实例出现问题时,无法将整个机器切换。所以必须改为MySQL实例级别的HA策略,我们采用了自己开发的MySQL访问层来解决HA的问题,当某个实例出问题时,只切换一个实例,对于应用来说,这一层是透明的。

MySQL单机多实例方案的优点

1.节省成本,虽然采用Flash存储的成本比较高,但是如果可以缩减机器的数量,考虑到节省电力和机房使用的成本,还是比单机单实例的方案更便宜。

2.提升利用率,利用NUMA特性,将MySQL实例绑定在不同的CPU节点,不仅提高了CPU利用率,同时解决了MySQL对多核CPU的利用率问题。

3.提升用户体验,采用Flash存储技术,大幅度降低IO响应时间,有助于提升用户的体验。

–EOF–

关于NUMA可以参考这篇文章:NUMA与Intel新一代Xeon处理器

标签: , ,

Fusionio性能测试与瓶颈分析

6 21st, 2011 | Posted by jacky | Filed under 大话技术

测试环境:Dell R510,2×E5620,24G,Fusion-io ioDrive 320G MLC

测试工具:Redhat Linux 5.3,Oracle Orion 11

测试一:8K随机读,IOPS超过5W,吞吐量超过400M,响应时间在IOPS达到4W时出现拐点(超过1ms),并迅速上升至最高值9.5ms。



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

测试二:4K随机读,IOPS超过7W,吞吐量达到280M,响应时间在IOPS达到7W时保持在1ms以下,随着并发压力不断增大,IOPS出现波动,响应时间逐步增加。

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

测试三:128K连续读,IOPS迅速上升至5000时,到达吞吐量瓶颈(700M),此时响应时间小于10ms,随后并发压力增大,IOPS与吞吐量指标无变化,响应时间迅速上升。

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

测试四:8K随机写,IOPS到达5.8W,响应时间为1ms,随着压力增大,IOPS逐步下降,响应时间随之快速上升。

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

测试五:读写混合模式,8K随机IO,20%写,IOPS到达4.5W,吞吐量360MB,响应时间在IOPS达到3.7W时保持在1ms左右,随着压力增长,响应时间迅速增加。

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

测试六:读写混合模式,8K随机IO,128K连续IO,20%写,IOPS达到5W,吞吐量580MB,响应时间在IOPS达到4W时保持在1ms左右,随着压力增加,响应时间快速增加。

性能分析:

本次性能测试直接读写fusionio卡,无任何缓存的影响,从测试数据我们看出,ioDrive的随机读性能非常好,4k IO的性能最佳,可以达到7W IOPS,8K IO可以达到5W IOPS,响应时间稳定在1ms以下。随机写的表现也非常优秀,8K随机写可以达到5W+。IOPS,响应时间保持在1ms以下。模拟数据库的8K随机IO和128K连续IO,IOPS可以稳定达到4W左右。总之,ioDrive的表现非常优秀。

瓶颈分析:

存储的瓶颈有两个:一个是IOPS,另一个是吞吐量。对于传统磁盘来说,单块盘的IOPS为150,如果每个IO最大为1MB,那么我们可以计算出磁盘的吞吐量瓶颈为150MB(实测吞吐量大致为170-250MB)。我们可以看到,IOPS是磁盘真正的瓶颈,随机IO对磁盘是致命的,而吞吐量对于磁盘通常不是瓶颈,所以磁盘更适合追求吞吐量的系统。

Fusionio与磁盘相比,随机IO可以轻松到达5w+,响应时间小于1ms,而吞吐量瓶颈则大致在600MB-700MB之间,官方数据与实测数据差异不大。通过上述数据分析可以看到,fusionio的IOPS很高,通常不会成为瓶颈,而吞吐量可能会在IOPS之前成为瓶颈。我们可以计算一下,600MB吞吐量,IO大小为128K,IOPS只有4800;8K的随机读,IOPS达到5W时,吞吐量已经接近400MB。虽然单块fusionio卡的吞吐量比磁盘大,但是考虑到价格因素,fusionio并不适合追求吞吐量的系统。

观察Fusionio的响应时间,我们发现当压力未达到瓶颈之前,响应时间稳定在1ms左右,当快到达性能瓶颈时,IOPS和吞吐量不再增加,此时响应时间会出现一个突变,然后快速增加,直到不可接受。所以在实际使用中,必须控制压力在性能瓶颈之下。

Fusionio具备很高的IOPS性能,所以它更适合随机小IO读写。在实际使用的过程中,可以适当减小IO的大小,将吞吐量瓶颈转化为IOPS瓶颈,这点与磁盘系统刚好相反,磁盘系统应该尽可能将IOPS瓶颈转换为吞吐量瓶颈,比如增加IO的大小,这是个很有趣的话题。

随着Flash存储技术的出现,将会颠覆整个存储行业,甚至会改变未来数据库等存储系统的设计,也给了我们巨大的想象空间。

–EOF–

Fusionio的官方数据:

标签: ,

Oracle+Fusionio+Dataguard的高可用方案

5 30th, 2011 | Posted by jacky | Filed under 大话技术

传统的Oracle的高可用方案必须基于共享存储设备,不管是双机主备模式,还是Oracle RAC,数据库必须放在共享的SAN存储上,通过HA或集群软件实现高可用。Oracle DataGuard是很好的容灾软件,但是作为HA解决方案,功能有很多局限性,比如数据丢失,应用透明切换,只能读无法写(11g)等等,目前都没有非常好的解决方案。

自从固态存储技术出现后,单机的IO能力大幅度提升,比如采用PCIE接口的fusionio卡,单块卡就可以提供数万IOPS的能力,单机的IO能力已经超过了传统的磁盘存储。但是,一直困扰我们的是,如何解决无共享存储环境下Oracle数据库的高可用问题?我们团队设计了一种架构,提供简单可靠的高可用功能。

Oracle+fusionio+DataGuard的高可用解决方案

方案简述:利用fusionio卡的强大的IO能力,取代传统存储设备,双机采用DataGuard复制,将主库的controlfile和redo放在一套共享的存储设备上。当主机发生故障时,利用共享存储上的controlfile和redofile将standby数据库恢复到一致状态。

硬件:DELL R710,48G mem,Fusionio ioDrive 320G(数据文件),6×300G SAS RAID10(归档文件)。

存储:SAN存储,存放主库的controlfile与redofile,与其他数据库共用,性能与空间要求不高。

软件:Veritas Cluster Service,提供HA功能,自定义切换脚本。

切换步骤

1.关闭standby;

2.指向共享存储上主库的redofile和controlfile;

3.mount standby;

4.recover database;

5.open database。

优点

1.零数据丢失;

2.简单,可靠;

3.应用透明切换;

4.对存储性能要求不高;

5.适合读多写少应用,提升读性能。

缺点

1.依然需要共享存储,但是可以与其他系统共用;

2.切换时间依赖standby恢复时间,必须保证standby恢复的进度;

3.共享的redofile可能会成为写入瓶颈,最好使用配置write cache的存储。

改进计划

1.实现类似switchover的功能,主备互相切换,无需人工干预;

2.本地fusionio空间不足时,可以将部分数据放在共享存储上,实现混合存储。

–EOF–

目前,这个方案已经通过初步验证,进入方案完善阶段。如果有兴趣,可以与我一起探讨,并不断改进。

标签: ,

数据库咨询服务

5 23rd, 2011 | Posted by jacky | Filed under 大话技术

最近这几年,参与了几个项目,积累了一点经验。我理解的所谓经验,其实就是通过大量的实际应用积累的最佳实践,这种经验是非常有价值的,因为它们是建立在大量实践的基础之上,具备真实性和普遍性。

我们面临的大部分技术问题,都是关于技术方向和架构的选择,我们需要从众多的技术方案中找到最佳方案。因为我所处的环境,可以接触到各种各样的环境,见过或者解决过很多问题,所以也积累了很多最佳实践。我想可以把这些经验分享给其他人,让大家少走弯路。

我有一个想法,为大家提供一些关于数据库方面的咨询服务,比如硬件选型,容量规划,数据库架构,性能调优等,只要不涉及公司的利益,我会知无不言,言无不尽,希望可以对大家有所帮助。当然,我的建议仅供参考,最重要的还是要积累属于自己的最佳实践,因为不存在最优的方案,只有最适合自己的方案。

我的联系方式:freezr@gmail.com。

–EOF–

标签:

数据库与SSD的实践与探索-2011数据库技术大会

4 18th, 2011 | Posted by jacky | Filed under 大话技术

近日参加了IT168组织的2011数据库技术大会,并且分享了一个数据库与SSD实践方面的主题。很遗憾,因为涉及的内容比较多,现场时间有限,所以很多问题都没有解答。

PPT中有我的联系方式,大家可以发邮件给我,我会尽我所能回答大家的疑问。

PPT:数据库与SSD的实践与探索

–EOF–

SSD磨损数据的分析报告

4 3rd, 2011 | Posted by jacky | Filed under 大话技术

我们都知道,SSD存在一个磨损的问题,虽然厂商提供的数据都显示企业级的SSD产品是可靠的,SSD内置的损耗均衡的算法,可以保证磨损是均衡的,不会出现反复擦写某个单元导致SSD损坏的情况。但是我们依然很担心,磨损对可靠性的影响究竟有多大?最近,我们对线上系统的SSD进行了分析,得到了一些关于磨损的数据,分享给大家。

S.M.A.R.T.(Self-Monitoring, Analysis, and Reporting Technology)是磁盘的诊断工具,其中也包括SSD的磨损数据。但是因为我们的SSD做了RAID,因为RAID卡屏蔽了SSD的信息,所以要直接读取SSD的SMART信息有些困难。通过厂商和社区的努力,现在已经有了解决方案。

Smartmontools是一套监控,诊断,分析SMART信息的工具包,包括两个工具:smartctl和smartd。

目前支持的RAID卡包括以下型号:

RAID-Controller Option/

Directive

Supported in OS
Linux FreeBSD MS-Windows NetBSD/

OpenBSD

Solaris MacOS/

Darwin

3ware SATA RAID controller -d 3ware,N Yes 1 Yes 2 Yes 3 ? ? ?
Areca SATA RAID controller -d areca,N Yes 4 No No ? ? ?
HighPoint RocketRAID SATA RAID controller -d hpt,L/M/N Yes 5 Yes 6 No ? ? ?
CCISS (HP/Compaq Smart Array Controller) -d cciss,N Yes 7 Yes No ? ? ?
LSI MegaRAID SAS RAID controller

Dell PERC 5/i,6/i controller

-d megaraid,N Yes 8 Yes 9 No ? ? ?
Intel ICHxR RAID

(Intel Rapid/Matrix Storage driver)

csmi[0-9],N

(device name)

? ? Yes 10 ? ? ?

我们使用的DELL服务器采用LSI的RAID控制器,包含一个Megacli的工具包,可以到LSI的官方网站上下载并安装。通过这两个工具就可以读取SSD的SMART信息了,具体方法可以参考这篇文章:利用smartctl获取Inte SSD寿命

SSD磨损数据分析:
SLC的SSD可以擦除10万次,MLC的SSD可以擦除1万次,Intel X25-E的官方数据:

Mean Time Between Failures (MTBF):2,000,000 Hours

Write  Endurance:2 petabyte of random writes (64 GB)

真实的状况如何呢?我们有一套数据库集群,配置如下:DELL R710,Intel X25-E(64G),硬件RAID5(512M cache),我们读取了SSD的SMART数据,主要有以下三个指标:

1. Media Wearout Indicator

定义:表示SSD上NAND的擦写次数的程度,初始值为100,随着擦写次数的增加,开始线性递减,递减速度按照擦写次数从0到最大的比例。一旦这个值降低到1,就不再降了,同时表示SSD上面已经有NAND的擦写次数到达了最大次数。这个时候建议需要备份数据,以及更换SSD。

解释:直接反映了SSD的磨损程度,100为初始值,0为需要更换,有点类似游戏中的血点。

结果:磨损1点

2. Re-allocated Sector Count

定义:出厂后产生的坏块个数,如果有坏块,从1开始增加,每4个坏块增加1

解释:坏块的数量间接反映了SSD盘的健康状态。

结果:基本上都为0

3. Host Writes Count

定义:主机系统对SSD的累计写入量,每写入65536个扇区raw value增加1

解释:SSD的累计写入量,写入量越大,SSD磨损情况越严重。每个扇区大小为512bytes,65536个扇区为32MB

结果:单块盘40T

4.Timed Workload Media Wear

定义:表示在一定时间内,盘片的磨损比例,比Media Wearout Indicator更精确。

解释:可以在测试前清零,然后测试某段时间内的磨损数据,这个值的1点相当于Media Wearout Indicator的1/100,测试时间必须大于60分钟。另外两个相关的参数:Timed Workload Timer表示单次测试时间,Timed Workload Host Read/Write Ratio表示读写比例。

数据分析报告:

从上述数据分析,SSD写入40T数据,磨损消耗仅为1%,而且基本没有坏块。这是在系统没有做任何优化的情况下,即将所有数据文件都放在SSD上的结果,这证明SSD的损耗均衡算法是很靠谱的。如果磨损是线性的,根据数据可以计算得出,单块SSD(64G)可以写入4PB的数据,与厂商提供的数据相符。而且,40T的数据大部分是系统测试时写入的,真实系统上线后写入的数据量很小,根据计算,我们的SSD如果磨损耗尽,可能还需要几十年的时间。

我们也使用了一些MLC的SSD,比如Intel X25-M,测试结果表明,SLC耐磨损度要远大于MLC,但是也在安全的范围之内。根据我们的实践经验和数据分析,企业级的SSD还是非常可靠的,并不需要特别担心磨损的问题。

读取SSD的SMART信息的最大的意义在于,我们能够提前检测SSD的磨损状况,发现SSD磨损即将耗尽时,可以提前更换,预防同一批次的SSD同时大规模损坏,这样就可以保证系统的可靠性。

目前的数据最多只是小测试,还不是期末考试,SSD的磨损是否是线性的,还有待于时间检验。

–EOF–

Ningoo:使用smartmontools监控磁盘状况

HateMySQL:利用MegaCli和smartCtl工具获得ssd盘使用情况

标签: ,

Database和SSD的实践与探索

3 20th, 2011 | Posted by jacky | Filed under 大话技术

这个主题是周末参加博文视点组织的open party上的演讲,准备不足,所以ppt中的内容不多,大部分内容都是现场即兴发挥。

根据这个ppt,我想整理两篇文章,一篇是如何取得SSD的磨损数据,以及SSD的可靠性分析;另一篇是通过实际案例讲述数据分布对于数据库性能的影响,以及flashcache的解决方案。

关于SSD与database的结合,flashcache的应用,这也是我今年的技术重点。

PPT:Database和SSD的实践与探索

–EOF–

标签: , ,

Library cache内部机制详解II

3 1st, 2011 | Posted by jacky | Filed under 大话技术

我之前曾经写过一篇Library cache内部机制详解,但是遗留了一些关于11g中mutex的改进的问题,最近因为有些11g的数据库频频发生mutex相关的等待事件,所以我又多这个问题做了一些探讨。

关于Mutex,可以参考ORACLE mutex实现机制这篇文章,mutex是从10g开始引入的,在library cache中有大量的使用,它的主要作用有两个:一是用来替换library cache pin,二是作为更轻量级的latch使用。

在9i中,Library cache lock有null,share,exclusive三种模式,lock的作用是控制进程间的并发访问。Library cache pin有share和exclusive两种模式,pin的作用是保证数据一致性,防止数据在访问时被交换出去。我们先来回顾一下library cache lock和library cache pin在不同场景下的使用方式:

Procedure/function/trigger

访问对象:需要在object handle上获取一个null类型的library cache lock(首先获取share,然后转换为null),然后在data heap上获取share类型的library cache pin,在其所依赖的表上不加任何lock和pin(先申请share类型的lock,申请到之后不再持有任何lock和pin,允许修改procedure所依赖的对象,即允许被打破)。

编译对象:需要在object handle上获取一个exclusive类型的library cache lock,然后在data heap上获取exclusive类型的library cache pin,同时在依赖的对象上获取share类型的library cache lock和pin,保证依赖的对象不能被修改。

当持有对象的library cache pin时,同时会在row cache中对相应的对象加锁,就是row cache lock,阻止可能导致数据字典信息混乱的DDL发生,row cache lock和library cache lock/pin一样,都是为了保证对象的一致性。

Cursor

Cursor execute:在object handle上获取null类型的library cache lock(首先获取share,然后转换为null),然后再data heap上获取share类型的library cache pin,在其所依赖的表上不加任何lock和pin(先申请share类型的lock,申请到之后不再持有任何lock和pin,允许修改cursor所依赖的对象,即允许被打破)。

Cursor hard parse:Cursor硬解析需要在object handle上获取exclusvie类型的library cache lock,然后再data heap上exclusive获取类型的library cache pin,同时在依赖的对象上获取share类型的library cache lock和pin,保证依赖的对象不能被修改。

Null类型的library cache lock与share类型的最大区别在于,Null lock并不起到并发控制的作用,它仅仅类似于一个触发器,当cursor所依赖的对象被修改时,需要获取exclusive类型的library cache lock/pin,这时Null lock被打破,Null lock会通知所有访问该对象的进程,表明cursor已经处于失效状态,需要重新解析,所以这种锁又称为“breakable parse lock”。

从上面的分析看出,Cursor和procedure需要获取的lock和pin是一致的。

Oracle 11g的变化

Oracle从10g开始在library cache中引入mutex,在11g中mutex得到了更大规模的使用,主要有以下几个等待事件:

cursor: pin X
cursor: pin S
cursor: pin S wait on X
cursor: mutex X
cursor: mutex S
library cache: mutex X
library cache: mutex S

cursor: pin S,cursor: pin X,cursor: pin S wait on X这三个等待事件,实际上就是替代了cursor的library cache pin,pin S代表执行(share pin),pin X代表解析(exclusive pin),pin X wait on X代表执行正在等待解析操作。这里需要强调一下,它们只是替换了访问cursor的library cache pin,而对于访问procedure这种实体对象,依然是传统的library cache pin。

cursor: mutex S,cursor: mutex X这两个等待也与cursor有关,一些资料上的解释是:cursor: mutex S用于Examining parent cursor, Querying V$SQLSTATS bucket,cursor: mutex X用于Loading new child cursor under parent, Modifying V$SQLSTATS bucket,Updating bind capture data。关于这两个等待的使用场景,目前还不是特别明确,我猜测它们是cursor: pin S,cursor: pin X这两个等待需要获取mutex时的产生的等待,因为cursor pin也是通过mutex实现的。

从上面的分析我们看出,在11g版本中,library cache lock和library cache pin依然存在,Procedure和function等对象仍旧使用原有的方式,Null类型的library cache lock也依然存在,作用同样是在依赖对象改变时,通知失效的cursor,唯一的变化是cursor的library cache pin被mutex的相关等待所取代。

library cache: mutex X,library cache: mutex S,这两个事件很明显是用来替代之前的library cache latch,主要作用是在hash bucket中定位handle时使用。而share pool latch和library cache load lock latch,latch依然存在,估计后续版本可能会逐步被替换掉。

–EOF–

附:9i,10g,11g关于library cache的等待事件比较,从中我们可以看到各版本的变化。

Wait event

Latch

9i

library cache pin

library cache lock

library cache load lock

shared pool

library cache

library cache pin

library cache pin allocation

library cache load lock

10g

cursor: mutex X

cursor: mutex S

cursor: pin S wait on X

library cache pin

library cache lock

library cache load lock

cursor: pin X

cursor: pin S

library cache revalidation

library cache shutdown

library cache

library cache lock

library cache pin

library cache pin allocation

library cache lock allocation

library cache load lock

library cache hash chains

11g

cursor: mutex X

cursor: mutex S

cursor: pin S wait on X

library cache pin

library cache lock

library cache load lock

library cache: mutex X

library cache: mutex S

cursor: pin X

cursor: pin S

library cache revalidation

library cache shutdown

library cache load lock

shared pool

标签:

ORACLE Fusion-io最佳实践

2 20th, 2011 | Posted by jacky | Filed under 大话技术

Fusion-io是基于NAND Flash技术的存储设备,底层存储技术与SSD相同,不同的是,Fusion-io采用PCI-E接口,SSD采用SATA接口。相比较SSD,Fusion-io省略了南桥芯片,RAID控制器等访问路径,所以Fusion-io又把他们的产品称为IO Memory,意思就是可以象内存一样访问,性能比SSD要好很多。

我们目前数据库使用SSD,采用的是硬件RAID5的方案,这个方案的优点是:通过RAID卡提供冗余功能,提升了整体的可靠性。缺点是:RAID会损失部分性能,通过RAID卡屏蔽之后,无法检测到SSD的使用寿命。选择硬件RAID5方案,是在大量测试的基础上,结合我们的实际情况做出的选择,并不一定是最优的方案。

ORACLE使用Fusion-io的方案,需要考虑三个方面的内容:1.数据冗余方案;2.数据存放方案;3.高可用方案。

数据冗余方案:

Fusion-io采用PCI-E接口,无法使用硬件RAID,我们可以使用OS LVM或者ORACLE ASM实现软RAID的功能。

1.External Redundancy (Striping/RAID0)

这个方案相当于RAID0,只是将多块ioDrive(Fusion-io的产品名称)的空间整合为一个统一的DG,不提供任何数据冗余。

2.Normal Redundancy (Mirroring/RAID1)

这个方案相当于RAID10,同时提供了数据冗余与条带,是可靠性比较高的方案。需要注意的是:可以通过ASM failgroup的功能,将两块ioDrive之间做镜像,以防止单块卡出现故障。

3.High Redundancy (Mirroring/RAID10 +1)

这个方案相当于RAID10+1,数据被冗余了三份,进一步提高了可靠性,不过代价有些高。

4.ASM Mirroring with a Read-Preferred Device

这个方案稍微复杂,ioDrive与存储的LUN做RAID10,利用ASM的Preferred mirror read功能,读取时优先读取ioDrive,提高性能的同时,又保证了可靠性。

5.方案分析:

上述四个方案中,方案一没有数据冗余,其他三个方案都有数据冗余,方案三代价过于高昂,方案四必须要有FC存储,方案二是最有可能采用的方案,但是RAID10要损失一半的容量,对于价格昂贵的ioDrive来说,代价依然高昂。回头看看方案一,因为本地数据没有冗余,所以必须采用Data Guard来保证系统高可用,如果要求数据100%不丢失,Data Guard必须采用同步模式,网络延迟必须满足日志同步写入的要求,如果系统压力过大,依然存在丢失数据的可能性。看来没有十全十美的方案,必须有所取舍。

数据存放方案:

1.将所有文件都保存在ioDrive上:

如果存储空间许可,这是最简单可靠,也是性能最好的一种方案。

2.将temp文件保存在ioDrive上:

针对一些DSS系统,temp文件可能是性能的瓶颈,比如大量的sort,Hash join可能耗费大量的temp空间,将temp文件放在ioDrive上可能带来性能上的收益。不过,我很少见到类似的需求,这个方案应该很少使用。

3.将redo保存在ioDrive上:

对于ORACLE数据库,redo log必须同步串行(9i串行,10g以后可以并行),对于write-intensive系统,要求redo必须有很低的写入延迟,否则redo可能成为整个系统的瓶颈。所以,可以考虑将redo log放在ioDrive上,提高响应延迟。但是,我个人并不是特别建议这个方案,因为redo log的写入是一种小IO的顺序写入,顺序写入更适合磁盘,并不适合flash存储(可以参考《基于SSD的数据库性能优化》)。如果磁盘可以满足响应延迟需求,建议将redo log放在磁盘上,而不是ioDrive上。

4.将热点数据保存在ioDrive上:

如果整个系统无法全部放在ioDrive上,而用户可以识别出系统的热点数据,那么可以人工将热点数据放在ioDrive上,将其他数据放在磁盘存储上,从而获得比较好的性能。

5.ioDrive作为flashcache:

将ioDrive作为数据库内存和磁盘之间的cache,Flashcache是用户透明的一种解决方案,系统自动将热点数据加载在flashcache中,提升系统性能。ORACLE  11g R2提供了flashcache功能,当block从SGA中被换出时,会被写入到flashcache中,但是在ORACLE的flashcache方案中,只有clean block才会被写入到flashcache中,Dirty block必须写入到磁盘上(DBWR会优先保证dirty block的写出,只有空闲时才会写flashcache),这就是我们所说的write through模式(Facebook的flashcache方案可以采用write back模式,dirty block首先被写入flashcache,然后定期刷新到磁盘上,flashcache同时承担了读cache和写buffer,这个方案性能更好),ORACLE flashcache是纯粹的读cache,可以大幅度提升读的性能,但是无法提升写的性能。ORACLE的方案很安全,就算flashcache损坏,也不会丢失任何数据,但是性能比WB模式要差一些,而且flashcache预热的过程也比较长。另外一点,ORACLE flashcache必须使用ORACLE LINUX,其他操作系统不提供这个功能。

Flashcache提供了一个高性价比的方案,但是同时增加了系统的复杂度,如果是WB模式,可能存在数据丢失的风险,在做方案时,需要做一些权衡。个人建议:如果空间可以满足需要,可以考虑方案一,性能和可靠性都最好。如果热点数据很明确,可以采用方案四,简单可控,性价比高。另外,Facebook的flashcache方案也是一个很好的选择,淘宝在MySQL数据库上广泛采用了这一技术,百度也在MySQL innodb存储引擎上,自主开发了flashcache的功能。不过,我始终认为flashcache是一个过渡方案,技术上并不是特别成熟,如果技术上无法完全把握这项技术,请谨慎使用flashcache。

数据高可用方案:

ORACLE数据库高可用方案有两个:Data Guard和RAC,Data Gurad相对比较简单,但是可用性并不理想。RAC基于共享存储架构,必须有一套SAN存储,RAC使用FusionIO也有两个方案:

1.共享存储+Fusion-io+Flashcache

这个方案采用传统RAC架构,只是在RAC节点上配置ioDrive,用ioDrive作为数据库的flashcache,提升性能。这里要说明一点,为什么ORACLE flashcache不提供WB模式,原因是ORACLE RAC架构必须基于共享存储,如果dirty block写入RAC节点的flashcache,当发生节点crash的时候,将出现数据不一致的情况。

2.Fusion-io+iSCSI+infiniband

这个方案将配置ioDrive的机器作为存储节点,利用iSCSI和ASM技术,将存储节点整合为共享的存储设备,输出给RAC节点使用。

事实上,很早之前我就做过类似的方案:ORACLE RAC廉价数据仓库解决方案,大致的原理一致,只是存储节点变成了ioDrive。但是,我们在做这个方案时,发现在千兆以太网上运行iSCSI,延迟时间根本无法满足需求。如果存储节点换成ioDrive,存储节点可以提供强大的IOPS能力,但是网络延迟将会成为整个系统的瓶颈。后来,ORACLE Exadata出现了,内部互连采用infiniband技术,这给了我们一个启发,我们同样可以利用infiniband的低延迟特性,来实现这个方案。

Infiniband与以太网不同,采用SRP(SCSI RDMA protocol)协议,是IB SAN的一种协议 ,其主要作用是把iSCSI协议的命令和数据通过RDMA的方式跑到Infiniband网络上,可以认为是iSCSI协议的一种增强和扩展,iSER代表iSCSI Extensions for Remote DMA。下图清晰的展示了各种协议与底层物理链路之间的关系。

ORACLE Exadata的最大优势在于,将OLTP和DSS融合在一套系统之内,Exadata有一些特性,其中smart scan,storage index,hybrid columnar compressed,这几个特性适合DSS应用。而对于OLTP类型的应用,主要是靠存储节点的flash存储和flashcache技术。对于我们的需求来看,DSS系统更适合采用分布式系统,例如hadoop,greenplum等,而对于OLTP系统,高性能的集中式数据库,可以解决很大的问题。所以,上述的方案如果可行,就为我们提供了一个新的方向。

我不知道ORACLE Exadata内部采用何种协议进行互联,我也很想搭建一套系统,去验证这个方案是否可行。另外,现在的存储厂商都可以提供内置SSD的存储产品,很多产品还提供自动分层的技术,从技术的角度看,这是比较成熟的。如果采用上述方案,性价比和风险还有待于进一步验证。

–EOF–

版权说明:本文中的部分内容来自于Fusion-io官方文档《Oracle Fusion-io Best Practices Guide》,最后的协议与链路关系图,来自于同事林钰的PPT,比我画得好多了。

标签: , , ,