2

正如标题所示,我想在某些事件发生时触发通知。

上面的事件可以是用户定义的,例如updating specified files in 1-miniute.

如果文件存储在本地,我可以通过系统调用轻松完成inotify,但情况是文件位于分布式文件系统上,例如 mfs..

怎么做?我想知道是否有一些解决方案或开源项目可以解决这个问题。谢谢。

4

1 回答 1

2

如果您对远程系统只有黑盒访问(例如 NFS 协议),那么您没有太多选择,除非该协议支持您的需要。所以我假设你可以控制远程系统。

“微不足道”的方法是在每台计算机上运行本地 inotify/fanotify 侦听器,该侦听器将通过网络转发通知。 FAM 可以通过 NFS 执行此操作

所有基于通知的系统的一个问题是在各种边缘情况下丢失通知的风险。这在网络上变得更加严重 - 例如,客户端确认收到通知,然后立即崩溃。您可以建立可靠的消息队列,但恕我直言,这种方式很疯狂......

更明智的方法是基于散列的无状态扫描。

我喜欢将以下设计称为“hnotify”,但这不是一个既定术语。这些想法被许多版本控制和备份系统广泛使用,可以追溯到Plan 9

核心思想是,如果您知道文件的加密哈希,您可以组成一个表示文件目录的单个哈希 - 如果任何文件发生更改,它就会更改 - 您可以构建这些自下而上来表示整个文件系统的状态
Git 以这种方式存储东西并且非常高效。)

为什么哈希树很酷?如果你有两棵哈希树——一个代表你在过去看到的文件系统状态,一个代表当前状态——你可以很容易地找出它们之间的变化:

  1. 你从根源开始。如果它们不同,则读取 2 个根目录并比较子目录的哈希值。
  2. 如果一个子目录在两棵树中具有相同的哈希值,那么它下面的任何内容都不会改变。去那里没意义。
  3. 如果一个子目录的哈希值改变了,递归地比较它的内容——调用步骤(1)。
  4. 如果一个有一个子目录,另一个没有,那就是一个变化。使用一些全局表,您还可以检测移动/重命名。

请注意,如果更改的文件很少,您只能读取当前状态的一小部分。因此,远程系统不必向您发送整个哈希树,它可以是“给我这个目录的哈希;现在这个……”的交互式乒乓球。
(这类似于 Git 的愚蠢 http 协议的工作方式;有一个更新的协议,往返次数更少。)

这就像轮询整个文件系统的更改一样健壮和防错误——你不会错过任何东西——但相当有效!

但是服务器如何跟踪当前的哈希值?

不幸的是,对大多数人来说,完全散列所有磁盘写入的成本太高了。如果您有幸运行重复数据删除文件系统(例如 ZFS 或 Btrfs),您可能会免费获得 if。
否则,您将不得不重新读取所有更改的文件(这比在文件系统层执行此操作更昂贵)或使用假文件哈希:在对文件进行任何更改时,发明一个新的随机“哈希”以使其无效(并尝试在移动中保留假散列)。仍然计算树上的真实哈希值。现在你可能会有误报——当内容相同时你“检测到变化”——但绝不会出现误报。

无论如何,关键是无论你做什么有状态的黑客攻击(例如,确保定期扫描 inotify),你只能在服务器本地进行。在整个网络中,您只发送代表当前状态(或其子树)快照的哈希值!这样,您就可以拥有一个具有许多服务器和客户端、间歇性连接的分布式系统,并且仍然保持您的理智。

PS Btrfs 可以有效地找到与旧快照的差异。但这是在服务器上拍摄的快照(并导致所有数据都被保留!),不如客户端轻量级哈希树灵活。

PS 您的标签之一是 HadoopFS。我对它不是很熟悉,但我怀疑它的很多文件都是一次写入后不可变的,它可能能够原生地为您提供某种可以用作假哈希的文件/块 ID?

现有工具

  • 我想到的第一个工具是bup index. bup是一个非常聪明的基于 git 的重复数据删除备份工具(仅可扩展为大数据),因此它位于上述基础之上。理论上,在服务器上对 bup 中的数据进行索引并git fetch通过网络进行操作甚至可以实现我上面描述的新功能的哈希遍历比较——不幸的是,bup 生成的 git 存储库对于 git 本身来说太大了。此外,您可能不希望 bup 读取和存储您的所有数据。但是bup index是一个单独的子系统,它可以快速扫描文件系统以查找潜在更改,而无需读取更改的文件。
    目前 bup 不使用 inotify 但已经深入讨论过

    哦,bup 使用 Bloom Filters,这是一种近乎最佳的方式来表示具有误报的集合。我几乎可以肯定 Bloom 过滤器在优化无状态通知协议中发挥作用(“这是我所有的压缩位图;你应该能够用它来缩小查询范围”或“这是我的压缩位图希望收到有关“的通知”)。不确定bup 使用它们的方式是否对您直接有用,但这种数据结构绝对应该在您的工具带中。

  • 另一个工具是git 附件。它也基于 Git(您注意到趋势了吗?),但旨在将数据本身排除在 Git 存储库之外(所以git fetch应该可以正常工作!)并且有一个“WORM”选项,它使用假散列以获得更快的性能。

替代设计:压缩的可重播日志

我曾经认为以上是客户检查更改内容的唯一理智的无状态方法。但我刚刚阅读了关于 OS X 的 FSEvents 框架的http://arstechnica.com/apple/2007/10/mac-os-x-10-5/7/,它的设计可能更简单:

  • 所有更改都记录到文件中。它被永远保存了下来。
  • 客户可以要求“为我重播自事件 51348 以来的所有内容”。
  • 魔术是日志的粒度很粗(“这个目录里有什么东西改变了,去重新扫描看看”,30秒内重复的改变是结合在一起的)所以这个日志文件非常紧凑。

在底层你可能会使用类似的技术——例如哈希——但顶层接口是不同的:你处理事件的时间线而不是快照。它可能更适合某些应用程序。

于 2014-08-06T13:41:39.340 回答