Распределение идентификатора хранилища данных с использованием PRNG - PullRequest
1 голос
/ 11 июля 2019

Google Cloud Datastore документирует, что если необходимо предварительно выделить идентификатор объекта, то следует использовать метод allocateIds: https://cloud.google.com/datastore/docs/best-practices#keys

Кажется, что этот метод выполняет вызов REST или RPC с задержкой. Я хотел бы избежать этой задержки, используя PRNG в моем приложении Kubernetes Engine. Вот код скалы:

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 гарантирует, что идентификатор еще не используется. Но в моем конкретном случае использования есть два смягчающих фактора для игнорирования этой проблемы:

  1. На основании подсчета сущностей вероятность конфликта составляет 1 на 100 миллионов.
  2. Этот конкретный тип сущности не является существенным и может позволить себе конфликт "один раз в голубой луне".

Меня больше беспокоит равномерное распределение в пространстве ключей, потому что это нормальная ситуация использования.

Будет ли работать этот подход, особенно с равномерным распределением в пространстве ключей? Является ли метод allocatedIds необходимым или он просто помогает разработчикам избежать простых ошибок?

Ответы [ 2 ]

1 голос
/ 16 июля 2019

Чтобы избавиться от коллизий, используйте больше битов - для всех практических целей 128 [См. Статистику UUID V4 ] никогда не создаст коллизию.

Другой метод заключается в вставке новых сущностей с более коротким случайным числом и обработке ошибки. Облачное хранилище данных возвращает данные, если они уже существуют, повторяя попытку с новым идентификатором (пока не встретится тот, который в настоящее время не используется ).

Что касается распределения ключей: ключи будут случайным образом распределены в пространстве ключей, что сделает хранилище данных Cloud счастливым.

0 голосов
/ 15 июля 2019

Учитывая, что вы не хотите, чтобы идентификатор сущности основывался на внешнем значении, вы должны разрешить Cloud Datastore назначать вам идентификаторы .Таким образом, у вас не будет никаких конфликтов.Идентификаторы, назначенные Cloud Datastore, будут соответствующим образом разбросаны по пространству клавиш.

...