分配使用PRNG数据存储ID(Allocating datastore id using PRNG)

2019-09-28 01:27发布

谷歌云存储的文档,如果一个实体ID需要预先分配的,那么应该使用allocateIds方法: https://cloud.google.com/datastore/docs/best-practices#keys

这种方法似乎使一个REST或RPC调用其中有延迟。 我想,以避免潜伏在我的Kubernetes Engine应用程序使用PRNG。 这里是Scala代码:

import java.security.SecureRandom

class RandomFactory {

  protected val r = new SecureRandom

  def randomLong: Long = r.nextLong

  def randomLong(min: Long, max: Long): Long =
    // Unfortunately, Java didn't make Random.internalNextLong public,
    // so we have to get to it in an indirect way.
    r.longs(1, min, max).toArray.head

  // id may be any value in the range (1, MAX_SAFE_INTEGER),
  // so that it can be represented in Javascript.
  // TODO: randomId is used in production, and might be susceptible to
  // TODO: blocking if /dev/random does not contain entropy.
  // TODO: Keep an eye on this concern.
  def randomId: Long =
    randomLong(1, RandomFactory.MAX_SAFE_INTEGER)
}

object RandomFactory extends RandomFactory {

  // MAX_SAFE_INTEGER is es6 Number.MAX_SAFE_INTEGER
  val MAX_SAFE_INTEGER = 9007199254740991L
}

我还计划安装haveged在吊舱,以帮助熵。

我明白allocateIds确保了ID是不是已经在使用。 但在我的具体使用情况下,有两种缓和因素来忽视了关注:

  1. 基于实体数,冲突的机会是1亿1。
  2. 这种特殊的实体类型是可有可无的,并能“在一个蓝色的月亮一次”冲突不起。

我更关心的密钥空间分布均匀,因为那是在正常使用情况下的关注。

请问这种方法的工作,特别是在密钥空间均匀分布? 是allocatedIds方法必不可少的,或者它只是帮助开发人员避免简单的错误?

Answer 1:

为了摆脱冲突的使用更加位-所有的实际目的128 [见后面统计UUID V4 ] 永远不会产生冲突。

另一种方法是用更短的随机号码中插入新的实体和处理错误,如果他们已经用一个新的ID再次试图存在云存储返回(直到你碰巧在一个当前未使用 )。

至于密钥分发云:密钥将密钥空间内随机分布将保持云存储高兴。



Answer 2:

既然你不希望实体标识符是基于外部值,你应该让云存储来分配的ID给你 。 这样,你不会有任何冲突。 通过云存储分配的ID将通过按键空间可以适当分散。



文章来源: Allocating datastore id using PRNG