Chinaunix首页 | 论坛 | 博客
  • 博客访问: 164324
  • 博文数量: 17
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 342
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-19 11:38
个人简介

A ZFS fan

文章分类
文章存档

2014年(17)

分类: 服务器与存储

2014-04-11 21:17:03

翻译 Jeff Bonwick博客:https://blogs.oracle.com/bonwick/en/entry/zfs_block_allocation

块分配是每个文件系统的中枢。它不仅仅影响到性能,而且影响到管理模块(比如说条带化配置),甚至会影响到类似事务、压缩以及快照之间共享blcok等一些核心的功能。所以说确保块分配的正确性是很重要的。

 

ZFS的块分配策略有三个组件构成:

  • 选择设备(动态条带化)
  • 选择Metaslab
  • 选择Block

在设计上,这三部分是相互独立且可插拔的。他们可以根据意愿修改而无需修改磁盘上的格式,这给我们在未来的时间里有很大的灵活性。

 

那么,我们开始分配一个block。

 

1. 选择设备(即:动态条带化)

  • 我们第一个任务就是选择一个设备。目标是分散存储池中的磁盘负载,是我们获得最大的带宽,而无需考虑条带组。你添加越多的磁盘,就会有越多的带宽。我们称这个为动态条带化。
  • 有很多种方法来选择一个设备。任何一种方法都可行,包括随机选择一个。但是有一些显示情况需要考虑:
  • 如果一个设备刚刚被添加到pool,那么它相对而言比较空。为了弥补这种不平衡,我们倾向于选择使用较少的设备。这样可以是所有的设备都有相同的使用程度。
  • 在其他条件相同的情况下,我们使用round-robin策略来选择磁盘,但是这需要小心地设定轮转策略。如果粒度过大(比如1GB),我们在做顺序读写过程中,只能使用一个磁盘的贷款。如果粒度太小的话(比如1block),就不能充分利用磁盘自身的缓存。在实际应用中,我们发现每512K轮转一次在当前的磁盘情况下比较合适。
  • 对于Intent Log设备而言,我们必须每次写入之后就轮换一次。这是因为log block的生命周期比较短暂,我们并不期望能再次读他们;因此我们在写log block时需要最大的IOPs
  • 对于不同的类型的数据我们需要不同的策略,比如说大的连续的数据,或是小的随机的数据,短暂的数据(比如Intent Log)以及dnodes
  • 如果一个设备由于某种原因而导致很慢或是被降级,它应该被跳过。

 

2. 选择Metaslab

  • 由于总体的架构上是通过slab allocator实现,我们把每个设备分成几百个成为metaslab的区域。既然已经选择了一个设备,我们应该使用哪个metaslab呢?直观上来说,我们总是希望选择空闲空间最多的,但是这里也有一些其他的因素要考虑:
  • 现代的磁盘有着相同的密度和恒定的角动量。因此,外圈的区域要比内圈的区域更快,具有较大的带宽,外圈与内圈的比通常是21。因此我们在计算的时候给外圈的metaslab赋予更高的权重。实际上,我们在选择metaslab时,是选择更高带宽而不是简单地选择较多空闲空间的。
  • 如果一个pool相对比较空,我们希望一直分配磁盘外圈的区域。这样既有较大的带宽,又有较低的延时(寻址距离短)。所以我们给之前使用过的metaslab赋予更高的权重。
  • 所有的这些考虑都可以在metaslab_weight()函数中。确定了权重方案之后,选择算法就很简单了:总是权责权重最高的metaslab

 

3. 选择Block

选择了metaslab之后,我们就必须在这个metaslab中选择block。当前的分配策略只是采用first-fit算法;似乎我们有更好的选择。我希望以后我们不仅有更好的算法,而是一组算法。对于特定的情况下都有比较完美的算法。

本文乃nnusun原创文章,请勿转载。如须转载请详细标明转载出处。

阅读(3547) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~