码迷,mamicode.com
首页 > 系统相关 > 详细

【Linux】系统 之 RAID

时间:2015-12-26 23:32:32      阅读:361      评论:0      收藏:0      [点我收藏+]

标签:

本人从事DBA相关的工作,最近遇到了IO抖动伴随shread running抖动的情况,主机宕机重启后备库及下游解析binlog出现binlog损害的案例,向一些有经验的同事咨询学习,其中最大的嫌疑是:raid卡问题,今天带各位一起走进raid卡的世界

  1. RAID卡是什么,为什么会用到RAID卡
  2. RAID卡的缓存与磁盘自带的缓存的关系
  3. 使用RAID卡应该注意的事项

了解MySQL的你,一定不会对InnoDB的事务日志陌生,InnoDB使用日志来减少提交事务时的开销,因为日志中记录了事务,就无须在每个事务提交时把缓冲池的脏块刷新(flush)到磁盘中,并且事务修改的数据通常会映射到表空间的随机位置,所以刷新这些变更需要很多的随机I/O,InnoDB用日志把随机I/O变成顺序I/O。一旦日志安全写到磁盘,事务就持久化了,即使变更没写到数据文件。如果一些糟糕的事情发生了(例如断电了),InnoDB可以重放日志并且恢复已经提交的事务。

日志缓冲必须被刷新到持久化存储,以确保提交的事务完全被持久化了,在这里不得不提到一个控制日志刷新的频繁程度的变量:innodb_flush_log_at_trx_commit,其配置对于 MySQL 的性能有很大影响。

set @@global.innodb_flush_log_at_trx_commit=xxx;

1. 当取值为 0 时,log buffer 会每秒写入到日志文件并刷写(flush)到磁盘。但每次事务提交不会有任何影响,也就是 log buffer 的刷写操作和事务提交操作没有关系。在这种情况下,MySQL性能最好,但如果 mysqld 进程崩溃,通常会导致[最后 1s]的日志丢失。
2. 当取值为 1 时,每次事务提交时,log buffer 会被写入到日志文件并刷写到磁盘。这也是默认值。这是最安全的配置,但由于每次事务都需要进行磁盘I/O,所以也最慢。
3. 当取值为 2 时,每次事务提交会写入日志文件,但并不会立即刷写到磁盘,日志文件会每秒刷写一次到磁盘。这时如果 mysqld 进程崩溃,由于日志已经写入到系统缓存,所以并不会丢失数据;在操作系统崩溃的情况下,通常会导致最后 1s 的日志丢失。

如图:

技术分享

上面说到的「最后 1s」并不是绝对的,有的时候会丢失更多数据。有时候由于调度的问题,每秒刷写(once-per-second flushing)并不能保证 100% 执行。对于一些数据一致性和完整性要求不高的应用,配置为 2 就足够了;如果为了最高性能,可以设置为 0。有些应用,如支付服务,对一致性和完整性要求很高,所以即使最慢,也最好设置为 1.

以上的所有的阐述都讲了redo log相关的策略,是InnoDB特有的,同样重要的参数还有sync_binlog 控制MySQL 的二进制日志(binary log)同步到磁盘的频率。

set @@global.sync_binlog=xxx;

1. 如果 autocommit 开启,每个语句都写一次 binary log,否则每次事务写一次。
2. 默认值是 0,不主动同步,而依赖操作系统本身不定期把文件内容 flush 到磁盘。
3. 设为 n 时,MySQL server 在binary log 每写入 n 次后,刷写到磁盘。
设为 1 最安全,在每个语句或事务后同步一次 binary log,即使在崩溃时也最多丢失一个语句或事务的日志,但因此也最慢。大多数情况下,对数据的一致性并没有很严格的要求,所以并不会把 sync_binlog 配置成 1. 为了追求高并发,提升性能,可以设置为 100 或直接用 0. 而和 innodb_flush_log_at_trx_commit 一样,对于支付服务这样的应用,还是比较推荐 sync_binlog = 1.

讲到这个似乎有点偏题,但是又不得不向各位交代。

了解清楚“把日志缓冲写到日志文件”和“把日志刷新到持久化存储”之间的不同是很重要的,在大部分的操作系统中,把缓冲写到日志只是简单的把数据从InnoDB的内存缓冲转移到了操作系统的缓冲,也是在内存中,并没有真正的持久化,与此相反,把支持刷新到持久化存储意味着InnoDB请求操作系统把数据刷出缓存,并确认确实写入到磁盘了。这是一个阻塞I/O的调用,知道数据被完全写入才完成,因为写数据到磁盘是相当慢的操作,作为数据库,尤其是高并发,对性能要求比较高,一定是接受不了的,换个角度看,对于写的实时性并不如读的实时性那么高,只要保证写进去就好。

高性能事务处理需要的最佳配置是把innodb_flush_log_at_trx_commit设置为1且把日志文件放到一个有电池保护的写缓存的RAID卷中,终于看到了我们今天要讲的内容!!!。这兼顾了安全和速度。

我们看到了在持久化设备磁盘前面还有一层RAID卷,日志文件写入到RAID就默认是写道磁盘了,这里包括 redo log 和 binary log 一旦RAID有问题,I/O性能会收到影响,并且数据都有可能丢失。

接下来我们正式进入正题

RAID卡是什么,为什么会用到RAID卡

为了简化问题,各位可以把RAID当做是磁盘CACHE,其主要的两大功能:预读和回写

1. 预读
CACHE预读提高了计算机系统中的硬盘读的功能,尤其是在读取含有大量文件碎片的文件时。具有良好预读功能的RAID卡能在看起来很随机的读访问中,识别出读取磁盘的规律, 通过这个规律提前将系统要读取的数据放在CACHE中。
预读的两种方式:
Read Ahead 
由于硬盘数据经常是以一族连续的硬盘扇区组织起来的,所以有时侯如把系统所请求的扇区随后的一个扇区里的数据 同时读进来是有价值的。对于数据文件的读取有利,特别是系统CPU的性能低时。
Pre-Fetch
当RAID卡发现系统要读的是先前已经读过的数据时,在 这一次,便将这一个数据块的数据写到CACHE里。对于程序文件的读取有利 。

2. 回写
回写是通过暂时将数据存在CACHE里,从而推迟将数据写到慢设备(如硬盘、磁带机)的一种工作方式。数据将在随后的时间,硬盘闲置的时候写到硬盘中。写的时候也是统一将CACHE内的尚未写出的数据按照数据块的在硬盘中的BLOCK序号写入,这样可以提高写的效率。 
回写需要加电池给CACHE供电,以免数据在写到硬盘之前系统断电导致硬盘数据丢失。 

增加CACHE大小对于预读来说,为系统提供了更多的来自CACHE的可供读取的记录。 对于回写来说,允许控制卡保存更多的记录留待后期写磁盘。特别是对于电梯式回写,使得连续的回写段之间有更近的间隔,降低硬盘写操作的平均访时间并提高了吞吐率。

写策略
1. 通写
所有数据在以命令完成状态返回到计算机之前,直接写到硬盘。
2.回写
可大幅度提高性能。但回写具有一定的数据危险性。在突然断电的情况下,会丢失存于Cache尚未写入硬盘的数据。

RAID卡工作在写策略为THROUGH时,缓存大小对RAID卡的性能影响很小,只有当写策略改为BACK时,缓存的作用才会发挥出来。

RAID卡的缓存与磁盘自带的缓存的关系

RAID卡是否有(启用)缓存对“随机读写”性能有巨大的影响。中高端的RAID卡都有缓存(价格也高)。 那么RAID卡的缓存与磁盘自带的缓存是如何设置的?

戴尔服务器的perc H710 RAID卡有512M缓存,并带电池。
建立阵列的时候(raid5),关于RAID卡缓存的默认选项是:
读取策略:自适应 
写策略:回写 
磁盘高速缓存策略:禁用 

属性解释:
读取策略:一般要启用,采用预读取策略,可提高“随机读取”性能。第二次读取相同数据时可以命中缓存。
写策略:
一般要启用"回写",操作的是RAID卡上的缓存。
写入数据时先写入到缓存就算写入成功了,然后RAID卡控制器再把多个写IO合并为一个写IO一次性写入磁盘,提高“随机写入”的性能。
因为RAID卡带电池,机房停电时,电池可给缓存供电72小时。缓存中的数据不会丢失。
另外,如果没有给缓存接电池,默认“写缓存”是不被启用的(除非强行设定为“没有电池也启用写缓存”)。

磁盘高速缓存策略: 
操作的是磁盘自带的高速缓存。 做RAID时,一般要禁用,防止机房停电时磁盘自带缓存中的数据丢失。磁盘可不带电池。
RAID卡控制器可控制磁盘自带的缓存是否启用。
家用台试机(未使用RAID卡)在windows操作系统中有选项可以控制磁盘自带的缓存是否启用(默认启用)。

使用RAID卡应该注意的事项

影响RAID卡性能的因素很多,其中可调因素主要有RAID卡缓存(CACHE)大小、写策略(WRITE POLICY)、读策略(READ POLICY)、条带的大小(STRIPE SIZE)。

  • RAID策略
1. 开启 Write Back,提高写效率
2. 开启 Bad BBU Write Back
默认情况下,如果 Raid 卡电池坏掉,Raid 卡会自动将 Write Back 切换到 Write Through,这个时候 I/O 就会变慢
开启 Bad BBU Write Back 的情况下,如果电池坏掉,那么 I/O 依然得到保障,但是带来了丢失数据的风险。假如此时机器断电,而 Cache 中的数据没有电池(BBU)的保护,数据就丢失了。
相比于机器断电,Raid 卡电池充放电会更常见,因此开启 Bad BBU Write Back 保证 I/O 速度。
3. 关闭读操作使用 Cache
因为 Raid 卡 Cache 容量有限,为了保证写 Cache 的使用,因此关闭读 Cache
4.关闭磁盘本身 Cache
因为使用 Raid 卡 Cache,因此关闭磁盘 Cache
5.开启 Adaptive ReadAhead
ReadAhead 是预读,而预读仅仅对顺序磁盘 I/O 有性能提升,因此将其关闭。
Adaptive ReadAhead 是自适应读,自动决定是否预读
按照以上描述设置后,MySQL服务器的 Current Cache Policy 理应如下:

Adapter 0-VD 1(target id: 1): Cache Policy:WriteBack, ReadAdaptive, Direct, Write Cache OK if bad BBU

从左至右逗号隔开的次,分别对应上文中的 1,5,3,2 的设置结果
  • 充放电

DELL服务器的Riad卡都有可充电池的特性,这块可充电电池,在不使用时,也会有微弱的放电现象,当它的电量放电到低到一定程度时,Raid卡控制器就会对电池进行一次“放电”,将剩余的电量放掉,然后再进行一次“充电”。这其实是一种对“电池”保护机制,以及对Raid阵列卡可用性提供保障的机制。

但是问题就出在这个放电、充电的过程上:

默认情况下,当RAID卡的电池的电量低于某阈值时,RAID卡固化程序认为此时的电池是不可用的,为了保证数据的安全,会禁用RAID的“缓存”,这种默认的机制本来是合情合理的,没有什么可“质疑”的。问题是,当RAID的缓存被禁用之后,RAID的I/O能力会大幅度下降。对于高I/O的应用来说,这种下降,有可能是致命的,可能会导致系统I/O阻塞,raid放电时(一秒以内),cache会禁写,cache策略由WB-》WT转化,会带来io抖动,目前无解。我的猜测:为了保证cache数据不丢的风险,并没有使用机器供电。构架不良的系统,有可能会被这个“故障点”(正在充放电的设备上的应用)拖死,简直太要命了!!!

  • BBU坏了
  • No-Battery Write Cache: Enabled 及Write Back ok if Bad BBU的情况下,如果电池坏掉,那么I/O依然得到保障,但是带来了丢失数据的风险。即使机器没有断电,Cache中的数据一旦没有电池(BBU)的保护,数据就丢失了,集团采用此策略,以数据丢失换取故障风险,单份数据集不建议开启此策略,OB的多份数据写成功的解决了这个问题。
  • No-Battery Write Cache: Disabled 情况下cache会禁写,cache策略由WB-》WT转化,遇到业务高峰,极有可能达到io瓶颈,造成故障。

公司在做断电演练的时候,没有全部raid卡writethrough,出现binlog文件损坏的问题,也出现过一台机器block corrupt。后期会设置为 NoCachedBadBBU ,当设置为NoCachedBadBBU,那么只要BBU电池坏了,或者电量不足,就会自动转换为WT模式,来避免 BBU 损坏导致的数据丢失。 write through 对性能影响的初步实验结果是,会导致 rt 平均增加 5ms,load 和 iowait 也有显著提高 load 0.44 -> 2.4, cpu iowait 0.1->4。

  • 系统crash或者掉电

BBU能够保障机器数据不丢失,等到机器重启上电后立刻刷盘,一般可以保证数小时的数据存储,这也是BBU的唯一作用。

机房的市电都是经过ups然后才到实际机器上的,当发生机房断电时,ups的存在可以让机器无感知仍旧工作,但不能保证30分钟以上,此时需要工作人员尽快启动柴油机发电,这也是为什么机房距离加油站较近的原因。

总结&反问

  1. 设置合适的RAID卡策略保证数据的安全性的同时最大化性能,我们真的可以保证数据不丢?数据不丢不意味着数据不会损害,不代表有用。如commit后,刷新事务数据时,事务需要保证完整性,但是刷到一半时断电,内存数据丢失,事务并没有完整持久化,此时会丢失一个事务。当刷binary log时同样导致已经传输到备库或者下游的数据没有及时持久化,这些文件都会损害,但最起码raid保证了持久化的数据不丢。
  2. RAID卡策略并不是唯一的,可以根据不同的业务场景选择,如No-Battery Write Cache的cache,当性能重要选择打开,数据安全更重要是选择关闭。

案例分享:

1、现象描述 在2015-12-07 21:28 收到 thread_running 357的告警

首先DB的tps和qps并没有什么特别变化,lor也是正常

技术分享

查看IO发现异常,在21:28的时候await很高

技术分享

查看raid日志

技术分享

基本可以确定这次的thread_running 飙高的原因是:raid卡充放电,导致raid卡缓存失效,io变慢。

参考:

磁盘CACHE的两大功能

RAID卡的缓存与磁盘自带的缓存的关系

Dell服务器Raid卡电池策略调整

MySQL服务器Raid卡Cache策略的设置总结

MegaCLI Scripts and Commands

【Linux】系统 之 RAID

标签:

原文地址:http://www.cnblogs.com/zhiqian-ali/p/5079164.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!