Храните «расширенные» метаданные для сущностей, хранящихся в Azure Cosmos DB, в виде документов JSON - PullRequest
0 голосов
/ 15 декабря 2018

Мы создаем REST API в .NET, развернутом в службе приложений Azure / приложении Azure API.С помощью этого API клиент может создавать «Продукты» и запрашивать «Продукты».Сущность продукта имеет набор общих полей, которые все клиенты должны предоставить при создании продукта, например, поля ниже (пример)

{
"id": "cbf3f7aa-4743-4198-b307-260f703c42c1"
"name": "Product One"
"description": "The number one product"
}

В настоящее время эти продукты хранятся в виде автономных документов.в БД Azure Cosmos.

Вопрос 1: Разделение.В коллекции не будет храниться огромное количество документов, мы говорим о максимально около 2 500 000 документов размером от 1 до 5 КБ каждый (оценки).В настоящее время мы выбрали поле идентификатора (которое является идентификатором, сгенерированным нашей системой, а не внутренним идентификатором документа Cosmos DB) в качестве ключа раздела, что означает 2 500 000 логических разделов с одним документом на каждый раздел.Документы будут использоваться в некоторых рабочих нагрузках с низкой задержкой, но эти рабочие нагрузки будут запрашивать по идентификатору (ключу раздела).Клиенты также будут запрашивать, например, по имени, и тогда у нас будет запрос разветвления, но эти запросы не будут критичны к задержке.На портале вы больше не можете создавать одну коллекцию разделов, но вы можете сделать это из SDK или иметь фиксированное значение ключа раздела.Если у нас есть все эти документы в одном единственном разделе (мы говорим о данных намного ниже 10 ГБ здесь), мы никогда не будем получать какие-либо разветвленные запросы, а будем больше полагаться на индекс в одном логическом разделе.Итак, вопрос: даже если у нас нет огромных объемов данных, все же разумно разделить, как мы это делали в настоящее время?

Вопрос 2: Расширенные метаданные.Мы столкнемся с клиентами, которые хотят писать метаданные, относящиеся к клиенту / приложению / клиенту, помимо основных общих полей.Каков наилучший способ сделать это?

Несколько мозговых штурмов от меня ниже.

1: Просто выведите все в один автономный документ.

Один из вариантов - разрешить клиентам в API добавлять типвложенное поле "extendedMetadata" с парами ключ-значение при создании продукта.Cosmos DB не зависит от схемы, поэтому теоретически это должно работать нормально.Некоторые продукты могут иметь ноль расширенных метаданных, в то время как другие продукты могут иметь много расширенных метаданных.Для клиентов мы можем обещать основные общие поля, но для расширенного поля метаданных мы не можем ничего обещать с точки зрения количества полей, именования и т. Д. Размер документа будет варьироваться.Эти продукты будут, как уже упоминалось, по-прежнему использоваться в рабочих нагрузках, критичных к задержке, которые будут выполнять запросы по «id» (ключу раздела). Расширенные метаданные никогда не будут использоваться в любых рабочих нагрузках, критичных к задержке. Как много и как в целом влияет на документувеличить производительность / пропускную способность? Для сценария чтения, критичного к задержке, оптимизатор запросов сразу перейдет к нужному разделу, а затем воспользуется индексом для быстрого извлечения интересующих полей документа, или же весь документ всегда будет загружаться и обрабатываться независимо.из каких полей вы хотите запросить?

{
"id": "cbf3f7aa-4743-4198-b307-260f703c42c1"
"name": "Product One"
"description": "The number one product"
"extendedMetadta" : {
    "prop1": "prop1",
    "prop2": "prop2", 
    "propN": "propN"
}
}

Расширенные метаданные полезны только для извлечения из того же API в определенных ситуациях. Затем мы можем сделать что-то вроде:

  • api.org.com / products / {id} - всегда возвращает продукт с основными общими полями
  • api.org.com / products / {id} / extended - возвращает полный документ (базовый+ расширенные метаданные)

2: разделить документ

Один из вариантов может быть сделать этоя как бы раскалывается.Если клиент из API создает продукт, который содержит расширенные метаданные, мы можем реализовать некоторую логику, которая разделяет документ, если extendedMetadata содержит данные.Я думаю, что разделение может быть сделано разными способами, мозговым штурмом ниже.Я полагаю, что главная цель разделения документов (что требует больше работы над операциями записи) - повысить пропускную способность в случае, если размер документа играет здесь важную роль (в большинстве случаев клиенты будут в порядке с основными общими полями).

  • Один базовый документ, который содержит только основные общие поля, и один расширенный документ, который (с тем же идентификатором) содержит основные общие поля + расширенные метаданные (дублирование основных общих полей). Мы можем добавить поле типа, котороеРазличает основной и расширенный документ.Если клиент запрашивает расширенный, мы будем запрашивать только документы типа «расширенный».
  • Один базовый документ, который содержит только основные общие поля + ссылка на расширенный документ, который содержит только расширенные метаданные.Это означает, что операция чтения, при которой клиент запрашивает продукт с расширенными метаданными, требует чтения двух документов.
  • Рассмотрим разбиение его на разные коллекции: одна коллекция содержит основные документы с пропускной способностью, предназначенные для сценариев чтения с малой задержкой, и однаколлекция для расширенных метаданных.

Извините за длинный пост.Надеюсь, что это было понятно, с нетерпением ждем ваших отзывов!

1 Ответ

0 голосов
/ 16 декабря 2018

Ответ 1:

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

(Имейте в виду, однако,что каждый раз, когда люди думают, что могут гарантировать такие вещи, как максимальный размер чего-либо, это обычно не срабатывает.)

Стратегия разделения / id эффективна только в том случае, если вы ВСЕГДА можете предоставить идентификатор.Это называется чтением.Если вам нужно выполнить поиск по любому другому свойству, это означает, что вы выполняете запрос.Это то место, где система не будет работать так хорошо.

В идеале вы должны создать свою коллекцию Cosmos DB таким образом, чтобы вы никогда не делали перекрестный запрос как часть повседневной рабочей нагрузки.Может быть, один раз в синей луне по причине сообщения.

Ответ 2:

База данных Cosmos по какой-то причине является базой данных без схемы NoSQL.Второй подход в вашем мозговом штурме подойдет для традиционной базы данных RDBMS, но здесь этого нет.Вы можете просто использовать свой первый подход и либо располагать все в одном свойстве, либо просто располагать их на верхнем уровне.

Помните, что вы можете просто сопоставить ответ с любым объектом, который вам нужен, поэтому вы можете простоесть 2 DTO.Тонкая и расширенная версия и просто сопоставление с различными версиями в зависимости от конечной точки.

Надеюсь, это поможет.

...