【问题标题】:fastest hashing in a unix environment?在 unix 环境中最快的散列?
【发布时间】:2010-07-24 11:40:57
【问题描述】:

我需要在 unix 平台上检查某个脚本的输出 1000 次,并检查其中是否有任何变化。

我一直在这样做:

(script_stuff) | md5sum

并存储此值。我实际上并不需要“md5”,只需要一个简单的哈希函数,我可以将它与存储的值进行比较,看看它是否改变了。如果偶尔出现误报也没关系。

有什么比 md5sum 更好的方法可以更快地生成一个相当可用的哈希值?脚本本身会生成几行文本 - 可能平均 10 到 20 行,最多 100 行左右。

我查看了fast md5sum on millions of strings in bash/ubuntu - 这很好,但我无法编译新程序。需要一个系统实用程序... :(


额外的“背景”细节:

我被要求监控一组 1000 个左右的域的 DNS 记录,如果有任何变化,立即调用某些其他脚本。我打算做一个 dig xyz +short 语句并将其输出散列并存储它,然后将其与先前存储的值进行检查。任何更改都会触发另一个脚本,否则它会继续。目前,我们计划将 cron 用于一组这 1000 个,但可以完全不同地考虑“严重”的使用 - 大约 20,000 个。

我不知道这样的系统有什么用,我只是为别人做这件事......

【问题讨论】:

  • 在典型的桌面系统上,md5sum 每秒可以处理数百兆字节的数据(检查pv /dev/zero | md5sum)。无论使用哪种散列算法,I/O 和进程生成开销都可能在您的情况下占主导地位。
  • 你为什么要把它写成一个shell脚本:| - python 和其他脚本语言在其标准库中具有散列函数。每个哈希的进程启动会产生很多开销。

标签: shell hash md5 unix


【解决方案1】:

cksum 实用程序计算非加密 CRC 校验和。

【讨论】:

  • 哇——这对我来说是 caf——这在 200 个测试集上缩短了 8 秒(唯一的变化是用 cksum 替换了 md5sum)!伟大的!我什至不知道有这样的工具!
  • 嗯,在我的笔记本电脑 (i3-5005U) 上,cksum 的速度是 md5sum 的一半。
【解决方案2】:

您要检查的输出有多大?最多一百行。我只需保存整个原始文件,然后使用cmp 来查看它是否已更改。鉴于哈希计算无论如何都必须读取每个字节,从校验和类型计算中获得优势的唯一方法是这样做的成本低于读取该大小的两个文件。

而且cmp 不会给你任何误报或否定:-)

pax> echo hello >qq1.txt
pax> echo goodbye >qq2.txt
pax> cp qq1.txt qq3.txt
pax> cmp qq1.txt qq2.txt >/dev/null
pax> echo $?
1
pax> cmp qq1.txt qq3.txt >/dev/null
pax> echo $?
0

根据您的问题更新:

我被要求监控一组 1000 个左右的域的 DNS 记录,如果有任何更改,请立即调用某些其他脚本。我打算做一个 dig xyz +short 语句并将其输出散列并存储它,然后将其与先前存储的值进行检查。任何更改都会触发另一个脚本,否则它会继续。目前,我们计划将 cron 用于一组这 1000 个,但对于“严重”的使用情况完全不同 - 大约 20,000 个。

我不确定您是否需要过多地担心文件 I/O。以下脚本首先使用文件 I/O 执行 dig microsoft.com +short 5000 次,然后输出到 /dev/null(通过更改 cmets)。

#!/bin/bash
rm -rf qqtemp
mkdir qqtemp
((i = 0))
while [[ $i -ne 5000 ]] ; do
        #dig microsoft.com +short >qqtemp/microsoft.com.$i
        dig microsoft.com +short >/dev/null
        ((i = i + 1))
done

每次运行 5 次的经过时间为:

File I/O  |  /dev/null
----------+-----------
    3:09  |  1:52
    2:54  |  2:33
    2:43  |  3:04
    2:49  |  2:38
    2:33  |  3:08

去除异常值并取平均值后,文件 I/O 的结果为 2:49,/dev/null 的结果为 2:45。 5000 次迭代的时间差为 4 秒,每个项目仅 1/1250秒。

但是,由于超过 5000 次的迭代最多需要三分钟,这就是检测问题所需的最大时间(平均一分半钟)。如果这不可接受,您需要从 bash 转移到另一个工具。

鉴于单个dig 只需要大约 0.012 秒,假设您的检查工具根本不需要时间,理论上您应该在 60 秒内完成 5000 次。您最好在 Perl 中执行类似的操作并使用关联数组来存储来自 dig 的输出。

Perl 的半编译特性意味着它的运行速度可能比bash 脚本快得多,而 Perl 的奇思妙想将使这项工作变得容易得多。但是,您不太可能仅仅因为运行 dig 命令需要多长时间而将 60 秒的时间缩短很多。

【讨论】:

  • 感谢 pax - 但我认为大量的磁盘调用会进一步减慢程序的速度。你同意吗?
  • 您所说的庞大数字究竟是多少?你的问题提到了一百行文字。除非它们是很很长的行,否则你根本谈不上太多 I/O。
  • 此脚本将每隔 2-3 分钟左右运行一次,包含 5000 个数据集(将独立更改)。如果当时没有“记录”/比较输出,我会错过生成必要的警报
  • 好的,@RubiCom10,基于这个和你的最后一个问题,你最好退后一步告诉我们你想要实现什么,而不是如何。通过预先假设解决方案,您束手无策。经典示例,如果您只想查看哪些文件正在更改,则可以使用上次修改时间而完全忘记它们的哈希值。对 5,000 个文件执行此操作的脚本速度可能非常快。
  • 这里没有文件...这些文件是您的解决方案生成的文件。我之前的问题与这个问题有关,因为 md5sum 为每个调用生成一个“-”输出(在我的问题中,我错误地认为它是一个 '*' 字符)。我会在我的问题中添加更多细节......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 2018-11-08
  • 1970-01-01
相关资源
最近更新 更多