Service Fabric — как мы можем сгенерировать partitionKey?

У меня есть служба с отслеживанием состояния с диапазоном ключей разделов от
-9223372036854775808 до 9223372036854775807 (UniformInt64Partition).

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

Спасибо


person DevDev    schedule 13.08.2018    source источник
comment
Вы можете создать хэш. См. раздел Выберите алгоритм хэширования по адресу документы   -  person Peter Bons    schedule 13.08.2018
comment
это именно то, что я искал, спасибо   -  person DevDev    schedule 13.08.2018


Ответы (2)


Для такого большого диапазона ключей разделов лучше всего использовать алгоритм хэширования поверх поле или набор полей для генерации ключа (числа) с наименьшим коллизией.

Предполагая, что вы храните информацию о клиенте, например, хэш для имени клиента от «Джон Смит» может сгенерировать хэш-значение 32, потому что любой пользователь с тем же именем, что и «Джон Смит», будет генерировать тот же хэш, если он не часто, не было бы проблемой, потому что 32 не является идентификатором, и они могут повторяться, имея один и тот же хеш, они будут храниться в одном разделе.

Если вы действительно хотите распределить эти значения как можно более равномерно, вы можете использовать другое объединенное поле, чтобы отличить «Джона Смита» от «Джона Смита», например дату рождения. И если оба не родились в один и тот же день, вы найдете разные значения для каждый.

В вашем случае, поскольку диапазон очень велик, вы должны использовать алгоритм хеширования, чтобы хешировать эти значения, чтобы они соответствовали диапазону от -9223372036854775808 до 9223372036854775807.

Вам нужно столько ключей?

Если в вашей системе не ожидается очень большое количество разделов, простой способ справиться с этим — использовать натуральное число, которое точно отражает диапазон ключей, предоставляемых выбранной вами функцией хеширования, вы можете выбрать вариант с более высокой производительностью, или нижнее столкновение, или и то, и другое.

person Diego Mendes    schedule 13.08.2018
comment
Помечено как принятое, спасибо. Я не знаю, нужно ли нам так много ключей, но мне кажется, что это слишком много, я спрошу у своего менеджера. Спасибо еще раз - person DevDev; 13.08.2018

Если вы уже используете GUID в качестве ключа для идентификации ваших данных, это несложно сделать. Важно знать, что идентификаторы GUID, хотя (практически) глобально уникальны, даже близко не распределены по всему диапазону. Я использую алгоритм хеширования SHA1 для хеширования GUID, потому что, несмотря на его недостатки как криптографического алгоритма, он хорошо справляется с созданием равномерно распределенных хэшей, не требуя слишком многого от сервера (с точки зрения вычислений и оперативной памяти).

Кроме того, переходя с GUID на long, вы создаете потерю данных (идентификаторы GUID эквивалентны 128-битному целому числу). Поскольку цель состоит в том, чтобы распределить данные по разделам, это нормально... не парьтесь по мелочам. На самом деле вы могли бы использовать меньший диапазон, чем Int64, но если у вас уже есть GUID, то зачем беспокоиться.

См. приведенный выше код для метода расширения для создания ключа раздела из GUID. Мой код реализации сворачивает его в две строки, но я разбил его ниже, чтобы иметь возможность аннотировать его.

public static ServicePartitionKey ToPartitionKey(this Guid id)
{
    // Hash algorithms need byte arrays, so we're converting the Guid here
    byte[] guidBytes = id.ToByteArray();

    // SHA1 is light weight and good at creating distribution across the range.
    // Do not use for encryption!
    SHA1CryptoServiceProvider hasher = new SHA1CryptoServiceProvider();

    // Hash the Guid's bytes.
    byte[] hashedBytes = hasher.ComputeHash(guidBytes);

    // Now that our data is repeatibly but distributed evenly, we make it a long
    long guidAsLong = BitConverter.ToInt64(hashedBytes, 0);

    // return the partition key
    return new ServicePartitionKey(guidAsLong);
}
person Michael Meadows    schedule 20.08.2018