只知道HDFS和GFS?你其实并不懂分布式文件系统( 四 )


 
2、存储节点的高可用
 
在前面“持久化”章节,在保证数据副本不丢失的情况下,也就保证了其的高可用性 。
 
八、性能优化和缓存一致性 
这些年随着基础设施的发展,局域网内千兆甚至万兆的带宽已经比较普遍,以万兆计算,每秒传输大约 1250M 字节的数据,而 SATA 磁盘的读写速度这些年基本达到瓶颈,在 300-500M/s 附近,也就是纯读写的话,网络已经超过了磁盘的能力,不再是瓶颈了,像 NAS 网络磁盘这些年也开始普及起来 。
 
但这并不代表,没有必要对读写进行优化,毕竟网络读写的速度还是远慢于内存的读写 。常见的优化方法主要有:
 

  • 内存中缓存文件内容;
  • 预加载数据块,以避免客户端等待;
  • 合并读写请求,也就是将单次请求做些积累,以批量方式发送给 Server 端 。
 
缓存的使用在提高读写性能的同时,也会带来数据不一致的问题:
 
  • 会出现更新丢失的现象 。当多个 Client 在一个时间段内,先后写入同一个文件时,先写入的 Client 可能会丢失其写入内容,因为可能会被后写入的 Client 的内容覆盖掉;
  • 数据可见性问题 。Client 读取的是自己的缓存,在其过期之前,如果别的 Client 更新了文件内容,它是看不到的;也就是说,在同一时间,不同 Client 读取同一个文件,内容可能不一致 。
 
这类问题有几种方法:
 
  • 文件只读不改:一旦文件被 create 了,就只能读不能修改 。这样 Client 端的缓存,就不存在不一致的问题;
  • 通过锁:用锁的话还要考虑不同的粒度 。写的时候是否允许其他 Client 读? 读的时候是否允许其他 Client 写? 这是在性能和一致性之间的权衡,作为文件系统来说,由于对业务并没有约束性,所以要做出合理的权衡,比较困难,因此最好是提供不同粒度的锁,由业务端来选择 。但这样的副作用是,业务端的使用成本抬高了 。
 
九、安全性 
由于分布式文件存储系统,肯定是一个多客户端使用、多租户的一个产品,而它又存储了可能是很重要的信息,所以安全性是它的重要部分 。
 
主流文件系统的权限模型有以下这么几种:
 
  • DAC:全称是 Discretionary Access Control,就是我们熟悉的 Unix 类权限框架,以 user-group-privilege 为三级体系,其中 user 就是 owner,group 包括 owner 所在 group 和非 owner 所在的 group、privilege 有 read、write 和 execute 。这套体系主要是以 owner 为出发点,owner 允许谁对哪些文件具有什么样的权限 。
  • mac:全称是 Mandatory Access Control,它是从资源的机密程度来划分 。比如分为“普通”、“机密”、“绝密”这三层,每个用户可能对应不同的机密阅读权限 。这种权限体系起源于安全机构或军队的系统中,会比较常见 。它的权限是由管理员来控制和设定的 。linux 中的 SELinux 就是 MAC 的一种实现,为了弥补 DAC 的缺陷和安全风险而提供出来 。关于 SELinux 所解决的问题可以参考 What is SELinux?
  • RBAC:全称是 Role Based Access Control,是基于角色 (role) 建立的权限体系 。角色拥有什么样的资源权限,用户归到哪个角色,这对应企业 / 公司的组织机构非常合适 。RBAC 也可以具体化,就演变成 DAC 或 MAC 的权限模型 。
 
What is SELinux:https://www.cyberciti.biz/faq/what-is-selinux/
 
市面上的分布式文件系统有不同的选择,像 ceph 就提供了类似 DAC 但又略有区别的权限体系,Hadoop 自身就是依赖于操作系统的权限框架,同时其生态圈内有 Apache Sentry 提供了基于 RBAC 的权限体系来做补充 。
 
十、其他 
1、空间分配
 
有连续空间和链表空间两种 。连续空间的优势是读写快,按顺序即可,劣势是造成磁盘碎片,更麻烦的是,随着连续的大块磁盘空间被分配满而必须寻找空洞时,连续分配需要提前知道待写入文件的大小,以便找到合适大小的空间,而待写入文件的大小,往往又是无法提前知道的 (比如可编辑的 word 文档,它的内容可以随时增大);
而链表空间的优势是磁盘碎片很少,劣势是读写很慢,尤其是随机读,要从链表首个文件块一个一个地往下找 。
 
为了解决这个问题,出现了索引表——把文件和数据块的对应关系也保存一份,存在索引节点中 (一般称为 i 节点),操作系统会将 i 节点加载到内存,从而程序随机寻找数据块时,在内存中就可以完成了 。通过这种方式来解决磁盘链表的劣势,如果索引节点的内容太大,导致内存无法加载,还有可能形成多级索引结构 。


推荐阅读