everything 索引原理探讨
MFT 如何获取硬盘所有文件信息和监控整个硬盘文件变动,这两个比较简单,我做了一个简单实现可以在 200 毫秒扫描整个硬盘所有分区下所有文件信息,总共 100 万个对象的信息,这个第一步比较简单。
主要是第二步,如何高效的为文件增加索引? everything 如何在 5 毫秒内完成 100 万文件的全文搜索并排序的?我利用 everything 开启 HTTP 服务,发送请求计算出来总共需要 5 毫秒就能完成这个搜索。这对我来说太难,我想了很久也没有想明白是如何做的。
思路 1:使用全文搜索,建立倒排索引,因为文件名经常出现比如“abc.txt“”这样的,所以很难分词,如果按每个字母建立倒排索引的话,100 万文件大约需要 1 个 GB 的空间,因为太多的文件有"a"这种字符,所以这个方案不行。
我看到论坛里有个开源的项目实现的,我粗略的看了一下,他套了一个全文搜索引擎,但是如果搜"a"这种字符,首先结果出来不全,可能只截取了一部分,但是 everything 可以搜索完立刻就知道总共有多少条符合的,而且搜索出来就已经排序了,比如按文件大小排序,我想不明白 5 毫秒内如何做到的。
思路 2:并行计算,我把 100 万文件并行去计算,我的极限可以把 100 万文件全文搜索控制在 6 毫秒,而且还没排序,但是我 7900x 的 24 核心芯片的每一个核心都参与了计算,而我在 everything 搜索的时候,我发现其 CPU 基本不怎么波动,没有出现大量核参与运算的样子,他是如何做的?
思路 3:使用 simd ,看着也不像,我感觉 everything 搜索的时候 CPU 波动非常的小。
思路 4:前缀树后缀树,这个只能搜索某个字符串开头的,没法实现全文搜索。
思路 5:我研究了一些多模态匹配字符串搜索算法,但是无论我怎么优化,都无法实现 5 毫秒这么快的速度。
思路 6:我研究了各种排序算法,我个人认为比如搜索“a”在我机器上有几十万个文件,无论用什么有我知道的算法,极限并行排序 100 万文件需要 10 毫秒左右,所以我才猜测 everything 不像是结果直接全部排序完成才返回的,更像是只获取前 100 个,然后后面慢慢排序,在你拖动滚动条的时候再把结果放出来。
思路 7:B+树,这个可能对排序建立索引有点用,但是全文搜索没什么帮助。
思路 8:索引建立速度,根据我录屏然后慢速分析,我发现,everything 1.4 扫描所有文件信息到建立索引,在我的机器上 1 秒以内就能完成,这是如何做的,我尝试了很久,如果算法太复杂就会消耗太多时间,显然 everything 的算法应该非常轻量高效。
希望高人能指点一下上面的谜题,让我能了解一下这个原理,非常感谢。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.