`
jiagou
  • 浏览: 2530739 次
文章分类
社区版块
存档分类
最新评论

文件系统开发手记-第1篇 文件系统开发的八大苦处

 
阅读更多

首先从下面的统计图说起。该图是Linux源码中各类系统所占的比例。可以发现设备驱动占内核源码中最大一块,紧接着是架构。这两块占据了超过70%。文件系统是除此之外的第三大块,其重要性不言而喻。Linux内核中文件系统有不下60种。但是各类文件系统的差异性并不是天生的,这与驱动程序不同。驱动程序的差异性是因底层设备的差异决定的,因而彼此间天然地存在差异。文件系统则与此不同,它们都与一样的底层块设备接口打交道,都向上提供一样的接口,其差异存在于具体设计和实现中。正因为这种差异的后天性,所以各种文件系统之间会互相学习,一种文件系统的某种功能或特性,往往过了一阵子就会出现在另一种文件系统中。

文件是类Unix系统中最为重要的概念,没有之一。这种重要性直接来自于UNIX的哲学:“一切都是文件”。试想如果我们在类Unix系统执行不了lscat这些操作文件的命令,那么还能做些什么?因此,这些文件接口的命令都被称为核心工具(coreutils)。使用文件的接口是如此清晰、自然,以至于很多系统都尝试用文件的形式提供接口,虽然它们偏离了文件的原始含义,比如FIFOsocketproc等等。而近几年来,云存储、大数据等概念在业界流行开来,围绕着存储周边的软硬件都将迎来快速的发展,文件系统也不例外。在接下来的十年里,坚持做存储将是一个不错的选择。

不过,文件系统的开发是一个充满荆棘的道路,这体现在:

  • 一、接口复杂。文件系统提供的文件操作有打开、关闭、读写、偏移、上锁、mmap、同步、异步读写、截断、属性读写、扩展属性读写删、权限判别。核心与此相关的主要数据结构有superdentryinodefilepage、线性区等等。一个文件系统开发出来,已经能接触到内核里面的很多概念,对整个内核也能有全貌的认识了。文件系统要提供这么多的接口,牵连到这么多的数据结构,其开发难度可见一斑。
  • 二、内核调试困难。几乎所有的用户层调试手段,在内核层一律不好用。很多时候只能使用最原始的方法——加打印、看日志。由于内核一死,就什么都做不了了,所以为了取得打印日志,还不得不采用系统崩溃转储机制。远古时代,我们使用的是netdump,将内核崩溃信息通过网络转存到网络上另一台机器上。netdump有很多的问题,我们不得不迁移到kdump上。kdump机制看上去很美:在现有内核之上再运行一个后备内核。实际用起来也不错,但是存在这两个问题:一个是它需要消耗100MB左右的内存空间,作为后备内核的运行空间,虽然这对于有着几十GB内存的服务器算不得什么,但总之是浪费了;另外一个问题是在遇到系统盘比较奇葩的时候,后备内核经常无法向系统盘写入,因此又不得不转向类似netdump的方式,将崩溃信息转存到网络上的其他节点上。一切环境配置好,才能开始在日志里捕捉蛛丝马迹。而这时,烦恼才刚刚开始。如果你想体会一下核心调试有多复杂,请阅读Dtrace的作者Bryan Cantrill在《代码之美》的那篇文章《一匙污水》。
  • 三、内核过于复杂。Linux-2.6.27版内核源码规模就已经超过了1000万行。一个如此复杂的系统,任何人都难以将所有细节研究透彻。为这样一个复杂系统开发一个子系统,最困难的事情并不是新系统的实现细节,而是充分理解原有系统。对我来说,文件系统的开发过程,也是一个摸着石头过河,不断学习的过程,稍不注意就会遇到陷阱,有时又会陷入复杂的系统中,无法挣脱。任何要进行文件系统开发的人都需要做好充分的心理准备,这不是一个轻松的工作。
  • 四、内核太过关键。大型软件存在错误就像是豪宅的犄角旮旯里面藏着蟑螂一样无可避免。曾经见到有人自嘲自己所在部门做出的Java服务软件,因为它BUG太多,往往撑不过一个星期就崩溃了,又实在找不到彻底解决问题的办法,所以最后干脆一不做二不休,写一个例程,过了一段确定时间,就在夜深人静的时候,悄没声地重启服务。这虽然是没有办法的办法,但是至少能掩盖问题,为彻底解决争取时间。然而,对于文件系统这种核心层的软件来说,我们不能运用重启大法。一旦遇到了BUG,最理想的情况就是系统直接死掉,服务完全不可用。更坏的情况是,系统仍然在运行,但是一切都没有响应了。没有办法登陆服务器,没有办法看到核心转储,甚至没有能留下错误的任何蛛丝马迹。在这个时候,我们所能做的就是祈祷数据不会丢,文件系统状态不会变异常,一切在服务器重启之后还能恢复正常。
  • 五、开发的封闭性。开发封闭性中指的是其开发由一个很小的团体把持着,有时甚至是一个人完成所有的设计、开发、实现。这是由于文件系统本身就是一个具有相当封闭性,讲究精悍,难以模块化增量开发的系统。这种封闭性给系统的发展带来了风险。俄罗斯人Raiser决定着Raiserfs的发展,在他枪杀妻子的那一刻,也就相当于把Raiserfs推向了末路。最近刚刚从LWN上得知,大名鼎鼎的glibc也是在相当一段时间以来都被Ulrich Drepper把持着。平心而论,这家伙对GLIBC功不可没,只是他使用手中的特权,有意无意地排挤其他贡献者,反而阻碍了GLIBC的发展。在开源界,这种问题并不在少数。当然,公司里这种事情也不是没有,只是公司会采取各种措施,有意避免开发过于依赖某个人的情况发生。开发的封闭性,也给开发者本身带来了苦恼。从我自己的经验来看,由于找不到其他理解了系统内部结构的人,所以即使找人讨论起来,也是隔靴挠痒,最终只能自己想办法。
  • 六、市场空间小。文件系统等系统软件一旦无法成为市场上的主流,那么就意味着盈利的空间完全被挤压殆尽。请君看一看内核之中有多少类型的文件系统,但是您真正听说过、用过的又有几种。更糟糕的是,极少有个人愿意为了这种基础的系统软件买单。而与此形成鲜明对比的是,游戏等应用软件的用户虽然被分割成各种用户圈,但是由于用户众多,绝对数量并不在少数。而且纵然用户圈再小,仍然存在愿意为此付款的客户。至于为什么会出现这种分化的现象,我将在另一篇文章里进行分析。
  • 七、用户对数据安全性极为敏感。文件系统存储着对用户来说最重要的东西:数据。CPU等部件的毁坏,只会带来计算能力的暂时缺失。服务停了可以重启,机器坏了可以再买,但数据丢了,除了干瞪眼,我们还能做什么?对用户来说,数据的丢失是完全无法忍受的。XFS出现已经颇有时日,它在大块数据上的性能优势也得到了普遍肯定。但是到现在为止,仍有一堆的用户怒斥XFS对数据保护不力,坚持使用古老的ext3。文件系统的什么新特新啊,高性能啊,都不是最重要的,最重要的是确保数据的安全。这是一切的基础,只有这个基础打好了,才能在上面盖高楼大厦,才能打出新特性、高性能的幌子招摇过市,吸引眼球。
  • 八、黑锅问题。文件系统是存储软硬件提供给应用的最终接口,不管是哪里的问题,反映在用户那里就是文件系统存在问题。因此文件系统,尤其是大规模分布式文件系统经常为底层问题背黑锅。按常理来说,从成百上千的盘阵和机器堆里,时不时蹦出几个捣乱的家伙,简直是再正常不过的事情了。然而,在这种情况下,一旦文件系统的容错做得不足,就会把问题捅到应用层,俺们开发维护人员就等着听抱怨吧。

好了,牢骚太盛防肠断,就此打住。其实,对于个人来说,既可以顺应潮流高歌猛进,也可以避开潮头,到沙滩上捡些小虾小蟹,只要努力,其实都可以取得不错的收获。

本文章欢迎转载,请保留原始博客链接http://blog.csdn.net/fsdev/article

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics