【问题标题】:UUID shorteningUUID 缩短
【发布时间】:2012-07-14 19:50:21
【问题描述】:

我需要计算一个应用的每日唯一用户数。

我可以唯一识别用户的唯一方法是通过他们的 UUID(这是外部提供的,所以我不得不使用它)。

我知道我的每日用户数是几百万用户。

我想在 Redis 中使用 bitset 来进行人口计数,但为了使其工作,我需要一种方法来缩小我的 UUID 以便它可以轻松地适应 long。我知道发生碰撞的可能性,但我并不关心确切的数字。

以前有人用 Java 做过吗?我所追求的是如何将我的 UUID 转换为可以放入 long 的东西。

【问题讨论】:

    标签: java redis uuid


    【解决方案1】:

    UUID 对象上有两种方法可能会让您受益。

    getLeastSignificantBits()getMostSignificateBits()。两者都返回很长。将其中一个作为您的答案(如果您愿意,也可以选择某种组合。)

    【讨论】:

    • 如果您使用将时间放入一个值并将节点和时钟序列放入其他。
    • 感谢您的建议,不幸的是,我发现从 getLeastSignificantBits() 和 getMostSignificantBits() 返回的 long 值仍然太大,无法在 Redis 位集中使用。
    • 从其中一个中获取输出并对其进行屏蔽以减少位数。你允许多少位?
    【解决方案2】:

    您可以生成您的 uuid 的哈希值,该哈希值会生成整数或长整数,并将其用于您的人口计数。

    看看 jedis redis 库中的 `redis.clients.util.MurmurHash'。你可以在https://github.com/xetorthio/jedis找到它

    *编辑:示例

            UUID uuid = UUID.randomUUID();
            ByteBuffer buf = ByteBuffer.allocate(16).putLong(uuid.getMostSignificantBits()).putLong(uuid.getLeastSignificantBits());
            buf.flip();
            int useMe= MurmurHash.hash(buf, 123);
    

    【讨论】:

    • 谢谢乔纳斯。我假设使用像 MurmurHash 这样的东西有碰撞风险(可能很低?)?我注意到在您的示例中您将种子值设置为 123。这是一个适合散列 UUID 的值吗?
    • 嗨,seedhead,很抱歉回答迟了,但这里是这样:每个散列算法都有冲突的风险,但既然你正在做人口计数,你应该没问题。 redis 库使用 '0x1234ABCD' 作为种子,应该没问题
    【解决方案3】:

    这可能足够小,可以直接使用完整的 UUID 作为哈希键。如果适合您的需要,也可以使用less memory 进行近似计算。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多