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

A ZFS fan

文章分类
文章存档

2014年(17)

分类: 服务器与存储

2014-06-21 10:33:59

说ZIL(ZFS Intent Log)之前,我们先说一下日志文件系统的概念。

关于日志文件系统(Journaling file system),不知道是否有人跟我开始的时候有着一样的误解。日志嘛,就是想磁盘中写入数据或者读取数据的时候,记录一条信息,表明本次操作的时间啊,操作内容等等。其实并不是这样的,这里的日志从Journaling翻译过来,如果按照我之前的理解,日志文件系统应该是Log File System了吧。

 

理论上来说,我们在往磁盘上写数据的时候,应该是直接把要写入的数据写到磁盘上相应的位置就好了。其实早期的文件系统在相当长的一段时间内也都是这么做的。但是,在写数据的过程中,总可能会发生这样或那样的突发现象,比如说宕机,比如说断电了。如果数据刚刚写到一半,突发情况发生了,那会怎么样?很显然磁盘上的数据将会是错误的,而且是无法修正的。如果要检查这类错误,就要扫描整个文件系统。(我们应该有这样的印象:在很久之前使用Window时,发现死机了,然后强行把电源拔了,再次启动时,系统会对硬盘惊醒扫描检查,这个过程将持续很长的时间,到了windows7之后这种情况就不存在了,为啥呢?)

 

那么,为了防止上面的事情发生,就产生了日志文件系统。其主要的原理是:在对磁盘操作的时候(主要是修改磁盘上的数据,包括写、修改、删除等),现将数据写到一个被称为“日志”的地方,之后找个合适的时间再把修改的数据写到文件系统中。这样一来,如果我们在写日志的过程中发生断电,那么文件系统中是原有的数据,是完整的,如果在从日志回写到文件系统是发生故障,日志中的数据时完整的,也不用担心。这样就解决了修改过程中突发状况导致文件系统数据不一致的问题。

 

其实,我刚开始研究ZFS的时候对ZIL有两个误解:

  1. 认为ZFS是日志文件系统,也理所当然地认为ZIL类似于日志文件系统的“日志”
  2. 认为ZIL是ZFS的写缓存。

来解释一下这两个误解:

 

ZFS在设计的时候就有这样的理念:既然我们要把数据写到“日志”,然后再回写到文件系统中,那么,为什么不让“日志”本身成为文件系统的一部分呢?因此ZFS使用COW(Copy-On-Write)与事务技术就足以保证磁盘操作过程不会因为突发情况导致数据不一致的现象发生。也就是说ZFS不需要日志功能,ZFS也不是日志文件系统(我是这么理解的)。所以ZIL跟日志文件系统的“日志”毫无关系。

 

下面,我们来看一个存储池的示例:

# zpool status tank
  pool: tank
 state: ONLINE
 scrub: none requested
config:

                     NAME             STATE     READ WRITE CKSUM
                       tank           ONLINE       0         0          0
                          c2t0d0    ONLINE       0          0          0
                       cache
                          c2t5d0     ONLINE      0          0          0
                       logs
                          c0t6d0     ONLINE      0          0          0

errors: No known data errors

 

上面的配置中我们可以看到两个关键字“cache”和“logs”,这里cache对应的设备用于读缓存,用来提高ZFS读数据的性能。于是我们依此类推,logs就对应写缓存,用来提高写数据的性能。!!!但是,这么类推是不对滴!!!

 

ZFS的写缓存是内存,而不是这些logs设备。ZFS设定了定时器,用于每个一段时间将内存中修改的数据写到硬盘上,在触发时间没到的情况下,所有的数据都是缓存在内存中的,而不是logs设备。那要ZIL有什么用?当然是提升性能。ZIL又是如何提升ZFS的性能的?

 

首先我们来看一下ZFS同步写数据的几种。

ZFS同步写数据的方式

ZFS文件系统中,同步将数据从内存到硬盘上主要由三种方式:

  1. 将数据同时往ZIL设备中写,由于ZIL设备速度块,而且写入空间整,所以会很快返回“OK”信号给客户端,这时客户端收到信号后可以立刻去做其他事情,在下一个同步数据触发信号触发时,系统将数据写到文件系统中。

  1. 将数据写入文件系统,然后将数据在文件系统中的块指针写到ZIL设备中,再返回“OK”信号给客户端。这是防止突然断电了,文件系统可以找到上次写入文件系统的数据的位置。

  1. 不经过ZIL,直接将数据写入文件系统,然后更新对应的元数据之类的,最后返回“OK”信号给客户端。

 

从上面三幅图来看,由于ZIL设备比文件系统设备要快很多,写完ZIL之后应用程序就可以接着做其他的事情,而不需要等待数据完全写入低速的存储设备,这样,效率也就大大滴提升了。

 

在默认的情况下,ZFS是开启ZIL写的,既然默认开启,如果没有存储池中没有ZIL设备该怎么办?这时,ZFS会在文件系统中划出一块空间来作为ZIL设备使用,上面方式一的图也就变成下面的样子了:

 

 

从图中可以看出,这样的ZIL设备,速度上与文件系统所在磁盘是一样的,而且还要白白写两次数据。也就是说这并不能提高ZFS的性能。所以说:ZIL设备的选择上,要选择SSD这样的高速设备,尽量不要选择低速的机械盘。唉?速度一样就干脆不要,为什么要用“尽量”?机械磁盘受顺序写和随机写的性能影响是相当大的。假设这样一种情况:往文件系统中写涉及到随机写,而ZIL的写基本上是用完就扔(绝对不会被读取),那么会有大段的连续空间,这么一来也还是能提高一下性能的吧。(至少我是这么认为的)

写完ZIL断电怎么办?


从上面的图可以看出,没有从ZIL设备读数据的过程,写入文件系统磁盘也是从RAM直接写入的。而且上面也已经说了,ZIL设备是不会被读取的,那如果数据写入ZIL设备,还没有来得及写入文件系统该怎么办呢?

其实,说不会被读取并不是绝对的。在一种情况下ZIL会被读取(也仅仅只有这一种情况),就是在系统重新启动之后,ZFS模块被加载后。ZFS模块加载后的第一件事就是看上次关闭之前是否有未完成的工作。如果有,就需要创建一个“Claim”类型的ZIO,来完成这个工作。这点在ZIL流水线设计的博客中也有说明.

 

总结

其实ZIL对性能的提升主要就是一点:减小写数据延时。通过高速的存储设备迅速响应应用程序给出的写数据请求,而不把时间浪费在等待数据写入慢速设备的过程中。





阅读(8646) | 评论(0) | 转发(0) |
0

上一篇:ZFS - RAIDZ

下一篇:没有了

给主人留下些什么吧!~~