架空的的理想文件系统设计,又名:如果穿越回 1970 年,你该怎么设计文件系统

2016-08-29 19:03:39 +08:00
 schezukNewTos

你有没有遇到过如下的困扰?

这些不是你的错,是文件系统设计的错。

文件系统的设计在不断发展之中,以适应新的硬件带给我们的更多可能性空间。
以 M$为例,从最早把所有文件都存在根目录下的 8-bit FAT,
到初次引入树状目录的 MS-DOS 2 ,到支持硬链接的 NTFS 。
文件组织理念逐渐进步——虽然早在 M$开始做任何操作系统之前这些就已经应用了。

传统的文件系统的思维是,储存文件的最近快照,并用目录树组织它、用文件名描述它。
这种静态僵化思维违反文件变动的本质,缺失重要的必需功能,不得不以外部应用补全。
文件的组织、查找、整理、版本维护、删除恢复,用户要么借助工具,要么掣肘于困难。

自 JFS 起引入了日志, WinFS 引入了标签(虽然成了先烈), APFS 引入了写入时复制。
这些都证明,传统的文件系统的思维,显露出的不灵活不适用的特点已经得到关注了。

让我们回到文件的本质吧:
文件是一段变化的数据,和对这一忒修斯之船的一组可变的描述。
任何设计若轻视文件的变化本质,静态看待其内容和描述,都会迫使用户持续陷入困扰。
(请读者联系亲身体验)。

版本标签概念进入到文件系统中,就像日志和软硬链接一样理所当然。
——虽然肯定有人为链接破坏了文件在目录树下唯一定位的特性而经历过困惑。
——那么这些人还会为不完全路径访问、副本的取消、复制概念的消失而惊讶。

一个理想的文件系统,他应当具有如下的特征:

这个架空的文件系统,其文件组织应当包括一下三个要素:
文件节点(inode),文件特征(meta),文件内容(content)。

文件节点是操作文件的独一凭据,是记录文件存在的根本标识。文件特征记载于此。
它使用链表记录文件的流变过程,链表上的每一个 hash 指向存储在硬盘上的一个版本。

文件内容是文件的数据本体,如文本,图片视频二进制数据, Office 文件,文件包……
写入打开一个文件创建一个新的文件内容,它暂存挂载在文件节点上,当写完则转正。
转正即哈希并提交到文件节点,文件内容按版本单独存放,互相不覆盖,同哈希则 GC 。
不同文件可绑定同一文件内容。需要压缩或者加密的,也在这一层次上进行操作。

文件内容根据可修改 IMMUTABLE 与可随机写入 Random-accessible 分为四类:
可修改、可随机写入:文本和某些二进制文件,行插入不影响有效性,需记录版本。
可修改、不可随机写入:日志文件,流媒体等,文件尾部不断追加,无需记录版本。
不可修改、可随机写入:数据库等等,由对应的应用自行管理写入,无需记录版本。
不可修改、不可随机写入:图像、媒体、文件包等,要么从不修改,要么记录版本。

文件特征全面取代目录树、文件名、文件权属和文件头,记录数据本体以外的信息。
它单独记录在链表上面。同时,创建、每次修改、删除,都同步到文件系统的索引上。
索引筛选取代目录访问,索引不能直接操作,通过操作特征来修改,用于按标签筛选。
文件元数据与文件内容独立,但是文件内容的可修改性、随机写入性、哈希是元数据。

文件的每一条元数据称为一个标签(tag),传统的文件夹代替以按标签筛选。
标签可以代替文件头:文件的每一条媒体信息都作为一条标签存储在文件元数据中。
标签可以代替文件名、扩展名、时间:同时取代了魔术字,文件头的标题、时间等等。
标签可以代替文件权属,文件权属应当同时精确到用户和应用,例: auth:usr1/app1 。
标签可以代替目录树:多数情况下重名文件分属不同用户应用,以文件权属代替。
标签必要的时候可以有多个级别,文件权属是用例之一,标签筛选也可以指定级别。

该文件系统采用与传统不同的一套 API 。随之而来的是完全不同的使用理念。
——尽管迫于历史包袱,可能仅限于理论讨论、思想实验,或作为一层虚拟界面层。
在计算机的早期采用固然好,但当时的硬件性能不足以支持,实在是很遗憾的事。

寻找文件通过提供一个标签字典或字符串,包含文件权属。返回一个文件节点号数组。
因为标签和历史版本消除了存储多个副本的必要,绝大多数情况只会有一个返回值。
万一有多个返回值意味着违背了这一设计哲学,用户可以添加标签区分、或合并副本。

访问文件通过文件节点号。返回记载标签和哈希的版本数组。有一个独特的暂存 API 。
读取文件读取指定哈希对应的文件内容,暂存文件创建一个可以写入的文件内容。
写入文件将暂存区转正,文件标签的修改也在此时保存到该文件节点的链表中。
本地不应当复制。用户 /计算机间可以创建副本,但授权应当改变。备份同理变更标签。
下载被抄送取代,接收方应当妥善接收标签,并作本地化,因为这是文件系统的一部分。


以上脑洞由 WinFS 、 APFS 、 Git 、 REST 等启发,可以视作无脑黑 Unix FS 和对 M$的吹捧。
作者本人,思虑不周。欢迎批评,谢勿转载。

4811 次点击
所在节点    程序员
44 条回复
bombless
2016-08-29 23:03:35 +08:00
翻到最后没有发现广告, v 站变了

unix 设计搞成这样主要两个原因
1 是资源紧张, pdp-11 都不被认为是真正的电脑,而说是连接电脑用的终端,就这用来跑 unix
2 是用 c 做软件设计一复杂就特别费劲,大家都没有劲把软件做完善

你真要做不考虑性能的接口的话直接 rest 来交互,底层设计随时演变随时加功能
kaneg
2016-08-29 23:15:47 +08:00
楼主提的这些与目前的文件系统并不冲突,而且只是文件系统复杂功能的一个非常小的简化版。你完全可以搞一个应用程序代替 Explorer 来屏蔽掉底层文件系统的目录。
duzhe0
2016-08-30 00:08:28 +08:00
科技的发展不可能跳过低级阶段直接进入高级阶段。
nikoukou
2016-08-30 04:51:05 +08:00
“关于过去知道的不多,为了爱情曾去过那里” by 楼主

楼主其实是为了寻找那个中学就失去联系的青梅竹马的妹子,是的,他想她想的发疯了,在他展开树结构人生 log 后,发现,改变文件系统是唯一的办法。于是楼主读了计算机博士,发明了时间机器,成功穿越到了 1970 年,却因时空震荡,昏睡了过去。

然而,当楼主醒来, 发现自己身处在一个漆黑的屋子里,于是当楼主 看到一个人朝他走来时,迫不及待的说了一句“ hello ”。

对方超楼主竖起了中指,不屑的发话了: hello , I am linus torvalds the forked version , welcome to the prison of time repository,aka /dev/null/snapshots/dummies/..

然后顿了了一下,缓缓而略带幽怨地说: and she has been waiting you for a long time to start merging....

TBC 。。。
schezukNewTos
2016-08-30 07:25:12 +08:00
@bombless @kaneg 除了无文件头带来的特性外(这个没办法向过去兼容),其实都可以通过虚拟层实现。
问题是,对用户操作习惯的改变太大,我觉得以至于必须借全新体验的新平台的东风( Web 、智能手机、 H5 ……)才推行得下去。 Vista 就栽了跟头。而且现在网上那么多标签不完善的历史遗留资源也不怎么配合。

@duzhe0 诚然,这还只是一个“为什么他们走入了二进制歧途,理想的计算机需要三进制”般的文章。
fjzjk
2016-08-30 09:26:15 +08:00
不愧是程序员思想...........穿越回 1970 年你就想着写代码...........
goreliu
2016-08-30 10:25:35 +08:00
你开发一个软件,如果没有几个用户用,那么绝对不是仅仅因为用户习惯了之前(笨拙低效)的操作方式。如果这样的话,人机交互界面在几十年期间怎么会一而再再而三地变化?真正原因就是不好用。诚然,你可能解决了一些问题,但这同时引入了其他问题,比如使用门槛过高,易用性很差,兼容性不好,额外的开销太大等等。这些都是需要切实解决的问题,而不是仅仅空想就可以了。

拿最简单的文件标签来说。为了解决一个文件可以分到多个类别的问题,可以引入文件标签。但文件标签并非必须在文件系统引入,在文件管理器引入多数情况也是可行的,而且现在已经有文件管理器可以用标签来管理文件。那么这类文件管理器为什么没有大规模流行起来?排除多数没有该需求的用户后,剩下的用户也并不都喜欢标签。一个很重要的原因是标签的复杂性。拿笔记类软件举例,很多笔记类软件既支持子目录方式安排笔记,也支持用标签方式。很多人因为有一个笔记属于多种分类的情况,想全部使用标签管理,但不久后就发现使用标签管理成本太大。因为如果所有标签都平级的话满足不了需求,于是有了父子标签,于是标签的简洁性不复存在。也就是如果想完全用标签管理笔记,不只要承担所有用子目录管理的复杂性外,还需要承担一个笔记属于多个标签所导致的混乱情况。

其实显而易见,完全用标签管理文件,就相当于用树型目录管理文件,外加用硬连接将一些文件连接到其他目录(于是所有的目录名都变成了标签名,父子目录变成父子标签)。这在文件系统层面是已经实现好的了,为什么很少有人这么用,还是因为太复杂了(它给人的感觉就是各种各样的重复文件,即使这些重复文件并没有占用额外的空间,但感觉起来就是这样)。实际情况就是,大多数用户没有按标签管理文件的需求,而有这种需求的用户,也可以用更成本更低的方法实现(比如用专门的图片管理软件来管理图片)。因为多数用户都没有需求,所有很少有这方面的成功案例,这不是一个习惯二字就能解释的清的。
Siril
2016-08-30 10:28:02 +08:00
@msg7086
标签的神奇之处不是在于增加维度么, 比如 一个文件同时具有 10 个属性,将其作为标签, 搜索时递增过滤的标签数量, 即不断缩小范围。 这个用目前的文件系统基本表达不出来。


@schezukNewTos 其实和硬盘一样快的内存现在还很常见。。。 在各种嵌入式平台上常见。
“ memory technology devices ”, 好像是这么叫。 如果以后能提高速度远超目前的 DRAM 。。。

都不看科幻吗? 飞跃界遍地都是的 “巨库” 才是终极方案啊。 同时是存储中心和超级计算机,带有相当高级的人工智能。 用法就是你向它 提问。。。 它直接出答案。
sammo
2016-08-30 10:29:37 +08:00
小孩子玩玩具:

1. 把玩具从盒子里拿出来
2. 玩玩具
3. 把玩具放回盒子里,下次还从那里拿

怎么会乱?
Actrace
2016-08-30 10:39:10 +08:00
最近也在设计文件系统,对楼主说的有点感触。
简化文件系统并抽象出来,实际上不管是通过标签还是路径来管理都无所谓了。
文件系统的目的得以体现就完全足够了。
nicevar
2016-08-30 10:42:42 +08:00
别穿越了,回到现实吧,其他文件系统能有 NTFS 的 usn 相近的就不错了
goreliu
2016-08-30 10:59:03 +08:00
然后谈一下如何解决这些困扰:
1. 找一个文件,因此翻遍了整个 D 盘
2. 为按用途还是时间整理文件而选择困难
3. 同一个文档在硬盘里放得到处都是
4. 因为程序对路径名的依赖,不能修改为更合适的名字
5. 把 office 文件命名为 111/222/aaa/最终修改版,以保存历史版本
6. 不小心覆盖了旧文件,无从恢复
7. 给文件添加元信息,副作用是新旧文件不一致

1. 为什么找一个文件需要翻遍整个 D 盘,显示是放文件时没有有章可循的规则。如果 D 盘下全是 aaa 、 bb 、一些资料、 good 这样没有意义的目录名,那么怎么可能快速找到。如果按照既有的规则创建目录名,比如 文本、图片、音频、视频,我总不会去图片目录里找视频文件吧,又何谈翻遍整个 D 盘?

2. 那图片举例,很多人是有这个困扰。比如图片可以按拍摄地点、人物分类,也可以按时间、相机镜头分类。那么最好的办法就是用专门的图片管理软件。音乐、视频也是如此。唯一不大好处理的就是文档类(包括 Office 文件、 pdf 文件等),但这类文件也有特点,一般以按用途分类为主,如果想按时间找,可以按时间搜索,基本上也是不存在什么大问题的。如果需求更多,也有专门管理文档的软件。

3. 这个问题其实就是问题 1 和问题 2 的另一种描述,解决了前两个问题,这个问题也就不复存在。

4. 这个是程序的设计问题,或者说是软件开发规范的问题,怎么也赖不到文件系统层面上来。

5. 这个是软件自身的设计问题。如果一类文件是非常依赖版本的,那么它可以自己实现版本控制,就像图片里的图层似的,每次打开的时候都可以选择打开之前的某个版本。这同时也解决了文件分发的问题。在文件系统层面解决的话,文件分发就很难解决了,因为这个问题不是文件系统改解决的。当然如果一定要文件系统来解决的话,现在 Windows 已经有文件版本的功能了,可以直接使用,如果信不过这个功能而不去用(很多人宁愿自己改名字,也不想用 Windows 自带的文件版本功能),就是另一回事了。还有一种方案,是用 git 之类软件专门管理文件版本,如果是我的话,我会选择这种方法,它同样不依赖文件系统的实现,而且只文件分发上也没有问题(甚至解决了文件的网络同步问题),使用成本也不是很大。

6. 这个问题同 5 ,不赘述。

7. 不知道这里的元信息指什么,如果是标签之类,同问题 2 。如果是备注之类,那么备注不应该放到文件内容中吗?

综上,我感觉这些困扰没有一个是需要在文件系统层面解决的,归罪于文件系统实在是很冤。当然这些现有的解决方式未必合理,如果楼主想在软件层面解决,我是非常支持的。但如此“架空”一番就只能被别人当笑话看了。
bombless
2016-08-30 11:16:17 +08:00
说起来 ntfs 有个特性叫流,可以向文件附带额外的字节流
印象中就是 CreateFile 中文件名用文件的名字加上冒号并带上流的名称打开一个对应的句柄。(大概记错

那个应该可以用来模拟文件头
hqtc
2016-08-30 11:28:11 +08:00
有次解压了一个 zip 包导致, windows7 下文件名过长,然后每一级的目录名也过长,怎么删都删不掉。。。 这个问题感觉是 bug , 既然无法删除,那怎么能够通过解压创建出来呢?
zhicheng
2016-08-30 12:08:26 +08:00
树形是人类最容易理解的模型,因为人类社会的组织结构就是树形,其它的不要想太多。
williamx
2016-08-30 12:54:45 +08:00
这必须是“你”的错啊!不应该是文件系统的错。毕竟,不会用是最大的过错!
hitmanx
2016-08-30 13:11:09 +08:00
说几句无关的题外话。

确实有太多东西妥协于于设计之初的科技水平了,而后为了不断地保持后向兼容,直到有一天会变成一个很奇怪的四不像。有些东西比较容易推倒另起炉灶,比如很多新的语言的设计理念都是把易用性摆在效率之上的。但是有些就很难了,比如 os kernel 。一个经典的例子就是有人问 Ken Thompson 如果能回到当初来重新设计 unix 系统,他最想做的是什么。他回答“ I'd spell creat with an e.”( https://en.wikiquote.org/wiki/Ken_Thompson )。这儿有个典故是*nix 有个系统调用叫 creat ,去创建(create)一个 file/device.当初就是因为资源极其紧张,所以能省一个字母也是好的。同样的例子还有 umount -> unmount ,参照这儿( http://unix.stackexchange.com/questions/9832/why-is-umount-not-spelled-unmount)的说法,第一版 unix 文件名包括扩展名在内最长限定在 8 个字母,而大部分的系统调用都有自己对应的源文件形如*.c,所以系统调用最长只能有 6 个字母,因此 unmount 只能是 umount 了。
zjqzxc
2016-08-30 14:16:58 +08:00
粗略看了一下对于网盘来说比较适用;但感觉即使时再当前的技术条件下,对操作系统来说不可取,大部分“特性”实现起来代价太大了。

计算机发展到现在,性能瓶颈就是硬盘;对于绝大多数的硬盘访问来说,楼主提出的这些特性都是无关紧要的,而为了这些无关紧要的东西进一步牺牲硬盘性能时不必要的。
硬盘最主要的功能不过是增删改查,在应用了如上的新特性后,如何在当前技术条件下保持硬盘的效率不会大幅度降低实在是不好解决。“任何问题都可以引入中间层来解决”,但是这个中间层并不“免费”。

对于计算机中数以十万计的文件来说,真正的个人文件过千都是很不容易的了。而对于这些文件,直接通过第三方工具建立索引进行分类或者检索反而更为简单,例如照片等可使用 lightroom 进行管理。

举例来说:
“把 office 文件命名为 111/222/aaa/最终修改版,以保存历史版本”;现在虚拟机的快照功能大概就是这样的。有一份根文件,每创建一次快照后,后续的写入并不直接写入这个原始文件,而是在另一个文件中记录对根文件做了哪些修改。实际上代价非常高昂, vmware 不建议在生产环境中启用快照。此外,因为逻辑比较复杂,快照的操作据说很容易踩坑,一旦踩坑就准备跟数据说再见了。

1 、如果楼主说要设计一套网盘系统来解决如上问题,双手赞同;
2 、如果是要设计文件系统,至少在当前技术条件下这件事我认为不可行;建议楼主阅读下《现代操作系统》中第四章文件系统部分。
exch4nge
2016-08-30 15:25:00 +08:00
近几年一直在做 Windows 上的文件系统相关内容,对文件系统也比较了解,就来强行评论下。 LZ 的这篇文章的很多 idea 确实不错,也能看出楼主对文件系统有过研究并且关注流行技术及原理,支持下楼主。
loryyang
2016-08-30 15:29:11 +08:00
这个本质上还是易用性和功能性上面的折衷,但是易用性可以随着用户使用习惯的积累而提高。
所以 lz 的想法其实完全可行,问题就是是否有办法推广,让用户慢慢习惯使用,依赖这种文件使用方式。
换句话说,发展到现在,已经完全没有可能了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/302524

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX