对于ZFS我是一直在强烈推荐的,因为实在太好用了。但是直到现在,它还是只能运行于Oracle的Solaris和FreeBSD两个系统上,为了将它分享给别的系统只能通过NAS或SAN的方式。
NAS的方式很简单,我一直在用Samba实现,当然NFS也是可以的,SAN的话之前还没试过。使用上当然是SAN更好一些,而且现在网速也够快。虽然对于存储来说,NAS和SAN都是外部存储,但对于客户机来说,它知道NAS是网络设备,而SAN则会被视同本地设备,这是二者的主要区别。之所以会这样,是因为NAS走的是网络层的协议,SAN走的是更底层的块设备协议。
传统上SAN都是比较高大上的,因为都是走光纤通道(FC),直到后来有了iSCSI这个大救星——使用iSCSI的SAN又被称为IP-SAN。而且有了iSCSI以后,NAS和SAN的区别已经不那么明显了,因为现在有一些NAS设备也提供iSCSI支持。
不过要注意一点:正因为NAS是走网络协议,所以对客户机来说,是以通用的网络文件系统方式访问,不需要关注服务端是用什么具体的文件系统,这也就意味着在不同系统中可以共享NAS中的文件。比如我现在就是在服务端用ZFS格式存放文件,通过SAMBA共享给Linux、Mac和Windows,在四个完全不同的系统中访问共享文件都没有问题。但是SAN是走底层块设备协议,所以是客户机独用的,Linux用的target不能与Windows共用(格式化后的文件系统不同),同样在服务端也无法直接看到相应target里的具体内容(可以通过服务端的本地Initiator连接后mount为指定文件系统操作,但也仅限于服务端本身支持的文件系统格式)。
之前版本的FreeBSD虽然也支持iSCSI,但是是一个用户级的应用,个人感觉不好,所以没试过。在最新的FreeBSD 10中,iSCSI被集成到系统中去了,这真是个喜大普奔的好消息,最近试了一下感觉还不错。
关于iSCSI的基本原理大致是这样:iSCSI本身是一个协议,是一个在IP网络上的虚拟SCSI实现。客户端能过iSCSI Initiator模拟一个本地的块设备(可以理解为一个虚拟的SCSI硬盘),然后由iSCSI Initiator把收到的SCSI指令通过IP网络传递到服务端,服务端的再将相应的指令转为对实际硬盘的操作。
在服务端(即存储端)有一些物理或逻辑硬盘,被组织成所谓的LUN(逻辑单元号),可以理解为一种逻辑卷,比如一块硬盘,一个分区,一组RAID,或是一个ZFS。当这个存储端把这些LUN通过iSCSI对外提供存储服务的时候,我们叫它iSCSI target。同时,在存储端上可以通过多种途径对外提供服务,比如通过不同的IP,不同的网卡,不同的身份认证方式等,每一种途径叫做一个portal group。portal group和target可以自由组合,以满足客户端的各种存储需求。
在客户端,则是通过前面所说的iSCSI Initiator实现,它在本地表现为一个虚拟硬盘(在/dev下有设备名,但没有实际的物理设备),对它的所有操作都会被通过iSCSI传递到对应的iSCSI target上去。
iSCSI target
首先在服务端创建一个ZFS供target之用:
zfs create -s -V 4G -b 4k tank/testtarget
注意需要-V参数才能在/dev/zvol下创建相应的块设备供iSCSI之用。-V表示创建ZFS卷,-s表示不在创建时分配空间,不加此参数则会创建一个实际占用指定容量的卷。-b指定块大小(即传统意义上的扇区大小,一般用4096或512)。
然后在 /etc/rc.conf 里加入以下一行启用ctld(iSCSI服务):
ctld_enable="YES"
接着是配置ctld,创建 /etc/ctl.conf 文件,内容为:
portal-group san {
discovery-auth-group no-authentication
listen 192.168.x.x
}
target iqn.2014-05.com.example:target0 {
auth-group no-authentication
portal-group san
lun 0 {
path /dev/zvol/tank/testtarget
blocksize 4096
size 4G
}
}