【问题标题】:What hashing techniques to use when building a bloom filter in clojure?在 clojure 中构建布隆过滤器时使用哪些散列技术?
【发布时间】:2012-03-22 04:15:52
【问题描述】:

我想在 Clojure 中构建一个布隆过滤器,但我对基于 JVM 的语言可能可用的所有哈希库了解不多。

对于 Clojure 中最快(而不是最准确)的布隆图实现,我应该使用什么?

【问题讨论】:

  • 您的密钥是什么类型的数据?字符串?字节数组?整数? UUID?
  • 我正在针对一组字符串测试成员资格
  • 您可以尝试对字符串上的hash() 方法报告的内置哈希值重复应用混合哈希函数,例如cris.com/~Ttwang/tech/inthash.htm 生成的值可能相关性太强,这可能会使布隆过滤器失效。我过去使用的一种方法是使用具有很长结果的哈希函数,例如 SHA-256,并将结果分成块。对于您的目的而言,这可能太慢了。最简单的可能只是在谷歌上搜索“字符串哈希函数”并实现它给出的一些结果。

标签: java clojure hash bloom-filter


【解决方案1】:

看看Apache Cassandra 中的布隆过滤器实现。这使用非常快的MurmurHash3 算法并以不同的方式组合两个哈希(或相同哈希的两个部分,因为升级到 MurmurHash3 而不是 MurmurHash2)来计算所需的哈希数。

组合生成方法在this paper中描述

这是来自 Cassandra 源代码的 sn-p:

    long[] hash = MurmurHash.hash3_x64_128(b, b.position(), b.remaining(), 0L);
    long hash1 = hash[0];
    long hash2 = hash[1];
    for (int i = 0; i < hashCount; ++i)
    {
        result[i] = Math.abs((hash1 + (long)i * hash2) % max);
    }

另见Bloomfilter and Cassandra = Why used and why hashed several times?

【讨论】:

    【解决方案2】:

    所以布隆过滤器的有趣之处在于,为了有效地工作,它们需要多个哈希函数。

    Java 字符串已经内置了一个可以使用的哈希函数 - String.hashCode() 返回一个 32 位整数哈希。对于大多数用途来说,这是一个 OK 的哈希码,而且这可能就足够了:例如,如果您将其划分为 2 个单独的 16 位哈希码,那么这可能足以让您的布隆过滤器正常工作。您可能会遇到一些冲突,但这没关系 - 布隆过滤器预计会有一些冲突。

    如果没有,您可能想要自己滚动,在这种情况下,我建议使用 String.getChars() 访问原始 char 数据,然后使用它来计算多个哈希码。

    帮助您入门的 Clojure 代码(只是总结字符值):

    (let [s "Hello"
          n (count s)
          cs (char-array n)]
      (.getChars s 0 n cs 0)
      (areduce cs i v 0 (+ v (int (aget cs i)))))
    => 500
    

    注意使用 Clojure 的 Java 互操作来调用 getChars,使用 areduce 可以非常快速地对字符数组进行迭代。

    您可能还对我在 Github 上找到的这个 Java 布隆过滤器实现感兴趣:https://github.com/MagnusS/Java-BloomFilter。 hashcode 的实现乍一看还不错,但它使用字节数组,我认为它比使用 chars 效率低一些,因为需要处理字符编码开销。

    【讨论】:

    • 已经用 Java 编写了一个布隆过滤器(问题是关于 JVM 和散列算法),不需要多个散列函数。确实(请参阅下面的答案),一个好的 MumurHash 非常适合 Bloom Filters,因为它们非常快,并且碰撞发生率的轻微增加并不是一个真正的因素,因为 Bloom Filters 本来就具有误报率。 Set 中的数据类型也不相关,因为性能和管理误报率的最佳实践是通过对输入键进行哈希处理来平滑位集分布。
    • @Darrell - 你需要足够的独立计算的 bits 才能将结果分割成多个散列函数。这就是下面的答案 - 我将其定义为“使用多个哈希函数”:-)
    • 问题是关于“可能对基于 JVM 的语言可用的哈希库”,因此评论是指那些与使用/计算的“哈希桶数”相比。我认为“哈希函数”这个短语意味着一个函数或方法(实现),而下面的评论指出“计算所需的哈希数”。很抱歉有任何混淆,但希望这可以为新用户澄清,因为这是一个相当繁重的计算机科学主题。
    猜你喜欢
    • 2019-01-21
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    • 2011-11-29
    • 1970-01-01
    相关资源
    最近更新 更多