java - 使用来自谷歌 Guava 的 Murmur3 生成长唯一 ID

标签 java guava uuid murmurhash

目前我正在尝试在客户端生成 long 类型的唯一标识符。 我有一个父/子关系,其中父已经有一个 UUID 作为标识符。 我想考虑使用 Parent-UUID 来计算 long 类型的 Child-Id。

我现在有这个实现:

public static void main(String[] args) {

    /** Funnel. */
    final Funnel<UUID> UUID_FUNNEL = new Funnel<UUID>() {
        @Override
        public void funnel(UUID parentUUID, PrimitiveSink into) {
            final UUID tmpId = UUID.randomUUID();
            into
             // consider parent uuid
            .putLong(parentUUID.getMostSignificantBits())
            .putLong(parentUUID.getLeastSignificantBits())
             // consider tmp uuid
            .putLong(tmpId.getMostSignificantBits())
            .putLong(tmpId.getLeastSignificantBits());
        }
    };

    final UUID parentUUID = UUID.randomUUID();
    System.out.println(parentUUID.toString());

    for (int i = 0; i < 1000; i++) {
        final long childId = Hashing.murmur3_128().newHasher()
                                .putObject(parentUUID, UUID_FUNNEL)
                                .hash().asLong();
        System.out.println(childId);
    }
}

您如何看待这个想法? 欢迎提出任何建议。

我已经读过这个问题: How to generate unique Long using UUID

最佳答案

这真的行不通。肯定不会比随机 long 更好。

  • 没有 tmpId:您只散列 parentUUID,因此同一父项的所有子项都得到相同的 long
  • 使用 tmpId:您可以使用 UUID.randomUUID().getLeastSignificantBits() 或仅使用 random.nextLong() 并保存所有内容工作(散列随机值会导致随机结果,无论您添加什么)。

I have multple clients not only one.

然后询问一个独特的服务器。这包括一些可以使用 hi-lo algorithm 轻松最小化的开销。 .

At the DB level the child id's must be unique.

那就不管了,让DB生成id。每个数据库都有一些 AUTOINCREMENT 或 SEQUENCE 正是为此而设计的。

如果您在访问数据库之前需要客户端中的 ID,请询问数据库(并使用 hi-lo 算法以最大程度地减少开销)。

离线工作

我刚看到你的评论:

The clients should not go to a server to get the next id. It must be possible to work offline.

这是一个很大的痛苦。您可以做的任何散列都不会比随机 long 更好。

  • 一组一百万个随机 long 的碰撞几率约为 1e-6,这可能是可以接受的。请注意,由于生日悖论,机会随集合大小二次增长。
  • 您可以尝试在没有 ID(使用其他标识符)的情况下处理离线创建的实体,但这听起来很痛苦。
  • 您可以为每个客户预分配一些 ID。这听起来很浪费,但为一百万个客户中的每一个预先分配 100 个 ID 使用的 ID 不到所有可能 ID 的 5%。
  • 您可以切换到随机 UUID。由于它们的长度为 128 位,因此即使对于数十亿个 ID,冲突机会也几乎为零。

关于java - 使用来自谷歌 Guava 的 Murmur3 生成长唯一 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41613540/

相关文章:

java - 玩!框架 2.7 - 无法连接到数据库

java - 如何查找div类下的文本

java - SOAPAction header 值异常 java web 服务

java - Guava 功能组成

c - 如何将 64 位哈希值缩短为 48 位值?

java - 如何在浏览器中显示DynamicReports而不下载到客户端驱动器?

java - 从对象列表到基于 Java 8 或 Guava 的键和值对对象进行分组

java - Jackson ObjectMapper 用方括号包裹每个元素(即使是单个值)

java - 为什么两个不同的 java.util.UUID 对象比较相等?

php - 从 Mysql 迁移到 Cassandra