Beats:介绍 Filestream fingerprint 模式

2023年 9月 27日 66.7k 0

作者:Denis Rechkunov

在 Filebeat 8.10.0 和 7.17.12 中,我们引入了一种新的指纹(fingerprint)模式,使用户可以选择使用文件内容的哈希来识别它们,而不是依赖文件系统元数据。 此更改在文件流输入中可用。

什么是文件流?

Filestream 是 Filebeat 中的一种输入类型,用于从给定路径摄取文件。

文件流架构

为了解释什么是指纹模式以及我们在 Filestream 中引入它的具体位置,我们首先解释一下 Filestream 输入的基本架构:

剥掉顶部组件的洋葱皮:

  • 文件扫描程序(File Scanner)收集有关与输入路径匹配的所有文件的信息。
  • 文件观察器(File Watcher)每隔几秒扫描一次文件系统,如在 prospector.scanner.check_interval 设置中指定的那样,然后比较检查之间的文件系统状态。 如果发生变化,它会发出一个描述变化的事件。
  • Prospector 决定如何利用这些文件系统事件:开始/停止收集文件、添加/更新/删除文件的状态等。
    • 为了开始处理文件并管理其在注册表中的状态,Prospector 需要该文件的唯一 ID,该 ID 从输入的 file_identity 参数配置的文件身份提供程序获取。
    • 所有文件状态(如偏移量)都存储在注册表中 - 内存中的存储,每个在 Filebeat 中配置的 registry.flush 间隔都会刷新到磁盘。 它作为操作日志存储在磁盘上。
    • 收集器(havestor)执行实际的文件摄取,并将它们读取的行发送到事件处理管道,该管道执行一些丰富、转换、排队、批处理,并最终将事件传递到输出。

当默认方法不够时

默认情况下,文件扫描程序在搜索重命名/移动时使用文件系统元数据来比较文件,例如:Unix 系统上的 - 字符串(有关 inode 的更多信息可在此处找到)和 Windows 上的 - - 字符串(分别为 nFileIndexHigh、nFileIndexLow 和 dwVolumeSerialNumber — 请参阅 Microsoft 的官方文档了解更多信息)。 相同的字符串用作文件身份提供程序返回的唯一文件标识符,并且该值用作注册表中每个文件的键以查找文件的当前状态。

文件身份提供程序返回的唯一_文件标识符_的全部要点是它必须稳定,这意味着在 Filestream 摄取文件期间它不会更改。 它必须是稳定的,因为 Filestream 使用此标识符来跟踪文件元数据,包括文件的当前偏移量,因此它知道在哪里继续摄取。

如果标识符不稳定怎么办? 它会导致数据丢失或数据重复。

数据丢失示例:

  • 文件 ID 现在与不同的文件(之前未摄取)相匹配。
  • Filestream 没有从偏移量 0 读取此文件,而是将错误的偏移量信息应用于此文件。
  • Filestream 继续读取文件中太向前的日志行,跳过日志行。 这些行永远不会到达输出。

数据重复的示例:

  • 现有文件的文件 ID 已更改。
  • 它现在显示为 Filestream 的新文件。
  • 文件流从偏移量 0 开始读取(重新摄取)。

不幸的是,并非所有文件系统都能产生稳定的 device_id 和 inode 值。

文件系统缓存 inode 并重用它们

如果你尝试在不同的文件系统上运行此脚本,你可能会看到不同的结果:



1.  #!/bin/bash

3.  FILENAME=inode-test

5.  touch $FILENAME
6.  INODE=$(ls -i "$FILENAME")
7.  echo "$FILENAME created with inode '$INODE'"

9.  COPY_FILE
10.  cp -a $FILENAME $COPY_FILENAME
11.  COPY_INODE=$(ls -i "$COPY_FILENAME")
12.  echo "Copied $FILENAME->$COPY_FILENAME, the new inode for the copy '$COPY_INODE'"

14.  rm $FILENAME
15.  echo "$FILENAME has been deleted"

17.  ls $FILENAME

19.  cp -a $COPY_FILENAME $FILENAME
20.  NEW_INODE=$(ls -i "$FILENAME")

22.  echo "After copying $COPY_FILENAME back to $FILENAME the inode is '$NEW_INODE'"

24.  rm $FILENAME $COPY_FILENAME


例如,在 Mac (APFS) 上你将看到:



1.  inode-test created with inode '112076744 inode-test'
2.  Copied inode-test->inode-test-copy, the new inode for the copy '112076745 inode-test-copy'
3.  inode-test has been deleted
4.  After copying inode-test-copy back to inode-test the inode is '112076746 inode-test'


如你所见,在 APFS 上,所有三个文件都有不同的 inode 值:112076744、112076745 和 112076746。因此,这按预期工作。

但是,如果您在 Ubuntu Docker 容器中运行相同的脚本:



1.  inode-test created with inode '1715023 inode-test'
2.  Copied inode-test->inode-test-copy, the new inode for the copy '1715026 inode-test-copy'
3.  inode-test has been deleted
4.  ls: cannot access 'inode-test': No such file or directory
5.  After copying inode-test-copy back to inode-test the inode is '1715023 inode-test'


你可以看到文件系统缓存了我们删除的第一个文件中的 inode 值,并将其重新用于具有相同文件名的第二个副本:1715023、1715026 和 1715023。

它甚至不必是相同的文件名; 不同的文件可以重用相同的 inode:

1. # touch x
2. # ls -i x
3. 1715023 x #

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论