Есть ли выигрыш в производительности для отключения AutotoIIDGeneration при создании документов в CosmosDB? - PullRequest
0 голосов
/ 29 августа 2018

При создании документов в CosmosDB с использованием .Net Core SDK есть возможность отключить автоматическую генерацию идентификаторов документов. Это позволит разработчику установить собственное значение для свойства id и будет выдавать исключение, если оно не установлено.

Например, здесь показаны оба подхода:

public class CosmosExample
{
    private readonly IDocumentClient _docClient;
    private Uri _collectionUri;

    public CosmosExample(IDocumentClient docClient)
    {
        _docClient = docClient;
        _collectionUri = UriFactory.CreateDocumentCollectionUri("MyDatabase", "MyCollection");
    }

    public async Task CreateWithId(DataModelWithId model)
    {
        model.id = Guid.NewGuid();
        var result = await _docClient.CreateDocumentAsync(_collectionUri, model, disableAutomaticIdGeneration: true);
    }

    public async Task CreateAutoId(DataModel model)
    {
        var result = await _docClient.CreateDocumentAsync(_collectionUri, model);
    }
}

public class DataModelWithId
{
    public Guid id { get; set; }
    public string Name { get; set; }
}

public class DataModel
{        
    public string Name { get; set; }
}

Я пишу приложение, которое создает большое количество документов, и я хотел бы оптимизировать пропускную способность и стоимость RU (Request Unit).

Повышает ли производительность или стоимость отключение автоматической генерации идентификаторов и генерацию идентификаторов в коде?

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Я думаю, что это не должно сильно влиять не на производительность (всего несколько миллисекунд), но вы можете получить точное время по-разному с GUID и без GUID. Ниже кода я использовал для получения RU и время по запросу.

private static void Main(string[] args)
    {
        string docId = Guid.NewGuid().ToString();
        string attId = Guid.NewGuid().ToString();

        var myDoc = new { id = docId, Name = "Max", City = "Aberdeen" }; // this is the document you are trying to save

        var client = GetClientAsync().GetAwaiter().GetResult();
        var createUrl = UriFactory.CreateDocumentCollectionUri("mytestdb", "test");
        ResourceResponse<Document> document = client.CreateDocumentAsync(createUrl, myDoc).GetAwaiter().GetResult();

        // Measure the performance (request units) of writes
        // ResourceResponse<Document> response = await client.CreateDocumentAsync(collectionSelfLink, myDocument);
        Console.WriteLine("Insert of document consumed {0} request units", document.RequestCharge);
        // Measure the performance (request units) of queries

        IDocumentQuery<dynamic> queryable = client.CreateDocumentQuery(
            UriFactory.CreateDocumentCollectionUri("mytestdb", "test"), "select top 1 * from c").AsDocumentQuery();

        FeedResponse<dynamic> queryResponse = queryable.ExecuteNextAsync<dynamic>().GetAwaiter().GetResult();
        Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
        Console.Read();

    }

    private static DocumentClient documentClient;

    private static async Task<DocumentClient> GetClientAsync()
    {
        if (documentClient == null)
        {
            var endpointUrl = "https://catecosmos.documents.azure.com:443/";
            var primaryKey = "73dDwfcDetx7Xr91kGs22QOkcgJgfMgyyJ8xKBbes6mooRtXY1vRo0gk5T5poFNAYviI9So53xsKgPiTsQ==";

            documentClient = new DocumentClient(new Uri(endpointUrl), primaryKey);
            await documentClient.OpenAsync();
        }

        return documentClient;
    }
0 голосов
/ 29 августа 2018

Вот код, который генерирует новый GUID, если вы отключите автоматическую генерацию. Этот код взят путем обратного проектирования эмулятора CosmosDB и извлечения кода движка Javascript.

// generate GUID
function getHexaDigit() {
    return Math.floor(Math.random() * 16).toString(16);
}
function generateGuidId() {
    var id = "";
    for (var i = 0; i < 8; i++) {
        id += getHexaDigit();
    }
    id += "-";
    for (var i = 0; i < 4; i++) {
        id += getHexaDigit();
    }
    id += "-";
    for (var i = 0; i < 4; i++) {
        id += getHexaDigit();
    }
    id += "-";
    for (var i = 0; i < 4; i++) {
        id += getHexaDigit();
    }
    id += "-";
    for (var i = 0; i < 12; i++) {
        id += getHexaDigit();
    }
    return id;
}

Судя по этому, генерация на стороне сервера происходит быстрее, потому что она не учитывает то, что учитывает C # Guid.NewGuid(), а вместо этого просто выполняет RNG.

Guid.NewGuid() фактически примет во внимание больше вещей, чтобы сгенерировать это значение.

  • MAC-адрес машины, использованной для генерации GUID
  • Отметка
  • Дополнительные "аварийные биты Uniquifier"
  • Идентификатор алгоритма

Имейте в виду, что это верно только в том случае, если служба Azure CosmosDB использует тот же код JS с эмулятором (что я лично считаю, но гарантии нет).

В заключение, автоматическая генерация идентификатора - это скорее функция качества жизни, которая дает больше контроля разработчику, чем то, что может улучшить или ухудшить производительность приложения (или пропускную способность). Это сводится к следующему. Если логично иметь идентификатор в составе DTO, используйте его. Если нет, то удалите его. Имейте в виду, однако, что для работы Replace и Upsert требуется id.

РЕДАКТИРОВАТЬ: Кроме того, читая ваш вопрос еще раз, вы звучите так, что если разработчик устанавливает id вручную и автоматическая генерация не отключена, CosmosDB автоматически сгенерирует новый идентификатор поверх указанного. Это неправда. Если вы установите id вручную, идентификатор не будет переопределен CosmosDB, независимо от настройки.

...