条带深度:条带的大小;条带宽度:条带深度的产量或者一个条带集中的驱动数。
 
条带深度一般设置:256K~1M
一个逻辑IO尽量在一次物理IO中完成。
在并发系统,OLTP,粗粒度条带,以保证多IO请求在一次物理IO中完成。
在低并发,DSS,细粒度条带。
 
条带化(Striping) 
条带化(Striping)是把连续的数据分割成相同大小的数据块,把每 段数据分别写入到阵列中不同磁盘上的方法。此技术非常有用,它比 单个磁盘所能提供的读写速度要快的多, 当数据从第一个磁盘上传输 完后,第二个磁盘就能确定下一段数据。数据条带化正在一些现代数 数 据库和某些 RAID 硬件设备中得到广泛应用。 
 
条带化的设置 
由于现在的存储技术成熟、成本降低,大多数系统都采用条带化来实 现系统的 IO 负载分担。 如果操作系统有 LVM Logical Volume Manager ( 逻辑卷管理 管理器)软件 软件或者硬件条带设备,我们就可以利用这些***来 管理 软件 分布 IO 负载。当使用 LVM 或者硬件条带时,决定因素是条带深度 (stripe depth)和条带宽度(stripe width) : 
条带深度指的是条带的大小,也叫条带单元; 
条带宽度指的是条带深度的产量或者一个条带集中的驱动数; 需要根据系统的 IO 要求来合理的选择这些数据。 对于 Oracle 数据库 系统来数,比较合理的条带深度是从 256K 到 1M。下面分析影响条带 深度和条带宽度的影响因素。 
 
条带深度 
为了提高 IO 效率, 我们要尽量使一次逻辑 IO 请求由一块磁盘的一次 物理 IO 请求。 因而影响条带的一个重要因素就是一次逻辑 IO 请求的 大小。 
此外,系统中 IO 的并发度不同我们对条带的配置要求也不同。例如, 在高并发度且 IO 请求的大小都比较小的情况下,我们希望一块磁盘 能同时响应多个 IO 操作; 而在那些存在大 IO 请求的低并发度系统中, 我们可能就需要多块磁盘同时响应一个 IO 请求。无论是一个磁盘还 是多个磁盘响应 IO 请求, 我们的一个原则是让一次逻辑 IO 能被一次 处理完成。 
下面先看下影响 IO 大小的操作系统和 Oracle 的相关参数:
db_block_size:Oracle 中的数据块大小,也决定了 Oracle 一次单 个 IO 请求中的数据块的大小;
db_file_multiblock_read_count:在多数据块读时,一次读取数据 块的数量, 它和参数 db_block_size 一起决定了一次多数据块读的大 小,它们的乘积不能大于操作系统的最大 IO 大小;
操作系统的数据块大小:这个参数决定拉 Redo Log 和 Archive Log 操作时的数据块大小,对于大多数 Unix 系统来说,该值为 512K; 最大操作系统 IO 大小: 决定了一次单个的 IO 操作的 IO 大小的上限, 对于大多数 Unix 系统来说,由参数 max_io_size 设置;
sort_area_size:内存中 sort area 的大小,也决定了并发排序操作 时的 IO 大小;
hash_area_size:内存中 hash area 的大小,也决定了哈希操作的 IO 大小。 其中,前面两个是最关键的两个参数。
在 OLTP 系统中,会存在大量小的并发的 IO 请求。这时就需要考虑选 择比较大的条带深度。使条带深度大于 IO 大小就称为粗粒度条带 (Coarse Grain Striping) 。
 
在高并行度系统中,条带深度为(n * db_block_size) ,其中 n 为大于 1 的整数。 通过粗粒度条带能实现最大的 IO 吞吐量 (一次物理 IO 可以同时响应 多个并发的逻辑 IO) 。大的条带深度能够使像全表扫描那样的多数据 块读操作由一个磁盘驱动来响应,并提高多数据块读操作的性能。
 
在低并发度的 DSS 系统中,由于 IO 请求比较序列化,为了避免出现 热点磁盘,我们需要避免逻辑 IO 之由一块磁盘处理。这是,粗粒度 条带就不适合了。我们选择小的条带深度,使一个逻辑 IO 分布到多 个磁盘上,从而实现 IO 的负载均衡。这就叫细粒度条带。条带深度 的大小为(n * db_block_size) ,其中 n 为小于多数据块读参数 (db_file_multiblock_read_count)大小的整数。 另外,IO 过程中,你无法保证 Oracle 数据块的边界能和条带单元的 大小对齐。如果条带深度大小和 Oracle 数据块大小完全相同,而它 们的边界没有对齐的话,那么就会存在大量一个单独的 IO 请求被两 块磁盘来完成。 在 OLTP 系统中, 为了避免一个逻辑 IO 请求被多个物理 IO 操作完成, 条带宽度就需要设置为两倍或者两倍以上于 Oracle 数据块大小。例 如,如果条带深度是 IO 大小的 N 倍,对于大量并发 IO 请求,我们可 以保证最少有(N-1)/ N 的请求是由一块磁盘来完成。 
 
条带宽度 
正如我们前面所述,无论是一个还是多个磁盘响应一个逻辑 IO,我 们都要求 IO 能被一次处理。因而在确定了条带深度的基础上,我们 需要保证条带宽度 >= IO 请求的大小 / 条带深度。
 
此外,考虑到以后系统容量的扩充,我们也需要规划好条带宽度。 如今大多数 LVM 都支持在线动态增加磁盘。也就是在磁盘容量不足 时,我们可以随时将新磁盘加入到一个已经使用的逻辑卷中。这样的 话, 我们在设置逻辑卷时就可以简单地将所有磁盘都归入到一个卷中 去。 但是,有些 LVM 可能还不支持动态增加磁盘。这时我们就需要考虑以 后的容量扩充对 IO 均衡的影响了。因为你新增加的磁盘无法加入原 有卷,而需要组成一个新的卷。但一般扩充的容量和原有容量比较相 对比较小,如果原有卷的条带宽度比较大的话,新增加的卷的条带宽 度无法达到其大小,这样就会使新、旧卷之间出现 IO 失衡。
例如,一个系统的初始配置是一个包含 64 块磁盘、每块磁盘大小为 16G 的单一逻辑卷。磁盘总的大小是 1T。随着数据库的数据增长,需 要增加 80G 的空间。 我们把新增加的 5 个 16G 磁盘再组成一个逻辑卷。 这样就会导致两个卷上的 IO 失衡。为了避免这种情况。我们可以将 原有磁盘配置成每个条带宽度为 8 个磁盘的 8 个逻辑卷, 这样在新增 加磁盘时可以也增加为 8 个磁盘的新卷。 但必须要保证 8 个磁盘的条 带宽度能够支持系统的每秒 IO 吞吐量。 如果你的条带宽度设置得比较小, 就需要估算出你的各个数据库文件 的 IO 负载,并根据负载量不同将他们分别部署到不同卷上一分担 IO 负载。 
 
人工条带 
如果系统不支持 LVM 或者硬件条带,IO 负载就必须由 DBA 根据数据 库文件的 IO 负载不同手工将他们分散到各个磁盘上去以保证整个系 统的 IO 负载均衡。 有许多 DBA 会将哪些使用频率非常高的表和它的索引分开存储。 但实 际上这种做法并不正确。在一个事务中,索引会先被读取到然后再读 取表,它们的 IO 操作是有前后顺序的,因此索引和表存储在同一个 磁盘上是没有冲突的。 仅仅因为一个数据文件即包含了索引又包含了 数据表而将它分割是不可取的。我们需要根据文件上的 IO 负载是否 已经影响到了数据库的性能来决定是否将数据文件分割。 为了正确分布文件,我们首先必须先了解各个数据库文件的 IO 负载 需求以及 IO 系统的处理能力。鉴定出每个文件的 IO 吞吐量。找出哪 些文件的 IO 吞吐率最高而哪些 IO 量很少, 将它们分散分布到所有磁 盘上去以平衡 IO 吞吐率。 
如果你不了解或者无法预计文件的 IO 负载,就只能先估计他们的 IO 负载来规划文件分布,在系统运行过程中再做调整。
 
 

3.2.7.1  条带深度

为了提高I/O效率,要尽量使一次逻辑I/O请求有一块磁盘的一次物理I/O请求。因而影响条带的一个重要因素就是一次逻辑I/O请求的大小。

此外,系统中I/O的并发度不同,对条带的配置要求也不同。例如,在高并发度且I/O请求都比较小的情况下,人们希望一块磁盘能同时响应多个I/O操作;而在那些存在大I/O请求的低并发度系统中,可能就需要多块磁盘同时响应一个I/O请求。无论是一个磁盘还是多个磁盘响应I/O请求,一个原则是让一次逻辑I/O能被一次处理完成。

下面介绍影响I/O大小的操作系统和Oracle的相关参数。

db_block_size:Oracle中的数据块大小,也决定了Oracle一次单个I/O请求中的数据块的大小。

db_file_multiblock_read_count:在多数据块读时,一次读取数据块的数量,它和参数db_block_size一起决定了一次多数据块读的大小,它们的乘积不能大于操作系统的最大I/O大小。

操作系统的数据块大小:这个参数决定了Redo Log和Archive Log操作时的数据块大小。

最大操作系统I/O大小:决定了一次单个的I/O操作的I/O大小的上限,对于大多数Unix系统来说,由参数max_io_size设置。

sort_area_size:内存中sort area的大小,也决定了并发排序操作时的I/O大小。

hash_area_size:内存中hash area的大小,也决定了哈希操作的I/O大小。

其中,前面两个是最关键的两个参数。

在OLTP系统中,会存在大量小并发的I/O请求。这时就需要考虑选择比较大的条带深度。使条带深度大于I/O大小就称为粗粒度条带(Coarse Grain Striping)。在高并行度系统中,条带深度为n×db_block_size,其中n为大于1的整数。

通过粗粒度条带能实现最大的I/O吞吐量(一次物理I/O可以同时响应多个并发的逻辑I/O)。大的条带深度能够使像全表扫描那样多数据块读操作由一个磁盘驱动来响应,并提高多数据块读操作的性能。

在低并发度的DSS系统中,由于I/O请求比较序列化,为了避免出现热点磁盘,需要避免逻辑I/O只由一块磁盘处理。这时,粗粒度条带就不适合了。选择小的条带深度,使一        个逻辑I/O分布到多个磁盘上,从而实现I/O的负载均衡,这就叫细粒度条带。条带深度的大小为n×db_block_size,其中n为小于多数据块读参数db_file_multiblock_read_count的整数。

另外,I/O过程中,用户无法保证Oracle数据块的边界和条带单元的大小对齐。如果条带深度大小和Oracle数据块大小完全相同,而它们的边界没有对齐的话,那么就会存在大量一个单独的I/O请求被两块磁盘来完成。

在OLTP系统中,为了避免一个逻辑I/O请求被多个物理I/O操作完成,条带宽度就需要设置为Oracle数据块大小的两倍或者两倍以上。例如,如果条带深度是I/O大小的N倍,对于大量并发I/O请求,可以保证最少有(N-1)/ N的请求是由一块磁盘来完成。

3.2.7.2  条带宽度

正如前面所述,无论是一个还是多个磁盘响应一个逻辑I/O,都要求I/O能被一次处理。因而在确定了条带深度的基础上,需要保证条带宽度 >= I/O请求的大小 / 条带深度。

此外,考虑到以后系统容量的扩充,也需要规划好条带宽度。

如今大多数LVM都支持在线动态增加磁盘。也就是在磁盘容量不足时,可以随时将新磁盘加入到一个已经使用的逻辑卷中。这样的话,在设置逻辑卷时就可以简单地将所有磁盘都归入到一个卷中。

但是,有些LVM可能还不支持动态增加磁盘,这时就需要考虑以后的容量扩充对I/O均衡的影响。因为新增加的磁盘无法加入原有卷,而需要组成一个新的卷。但一般扩充的容量和原有容量比相对较小,如果原有卷的条带宽度比较大的话,新增加的卷的条带宽度无法达到其大小,这样就会使新、旧卷之间出现I/O失衡。

例如,一个系统的初始配置是一个包含64块磁盘、每块磁盘大小为16GB的单一逻辑卷。磁盘总的大小是1TB。随着数据库的数据增长,需要增加80GB的空间。把新增加的5个16GB磁盘再组成一个逻辑卷。这样就会导致两个卷上的I/O失衡。为了避免这种情况,可以将原有磁盘配置成每个条带宽度为8个磁盘的8个逻辑卷,这样在新增加磁盘时可以也增加为8个磁盘的新卷,但必须要保证8个磁盘的条带宽度能够支持系统的每秒I/O吞吐量。

如果条带宽度设置的比较小,就需要估算出各个数据库文件的I/O负载,并根据负载量不同将它们分别部署到不同卷上分担I/O负载。

3.2.7.3  条带大小计算方法

stripe width(条带宽度):RAID中的磁盘数,就是组成这个stripe的磁盘数。例如,4个磁盘组成的RAID 0,条带宽度就是4。

stripe depth(条带深度):单块磁盘上条带的大小,有时也称为stripe unit。

stripe size(条带大小):stripe depth×stripe width。有时也称block size块大小、chunk size簇大小、stripe length条带长度、granularity粒度,是单块磁盘上的每次I/O的最小单位。

RAID条带大小的另一个计算公式为:

条带大小=(0.25×平均定位时间×数据传输速率×(并发用户数-1)×1.024)+0.5KB。

平均定位时间=(平均延时+平均寻道时间)(ms);数据传输速率单位为:Mbps;1.024 = 1s/1000ms×1024KB/1MB(单位转换因子)。

举例来说,磁盘寻道时间是6ms,传输速率80MB,且有20个并发用户的条带大小应该为:(0.25×6×80×19×1.024)+0.5=2335.22KB(差不多2MB)。