Как хранить и читать миллионы записей в Azure с вторичной индексацией - PullRequest
1 голос
/ 29 мая 2020

Мне нужно хранить десятки миллионов записей в Azure. Мне нужно сортировать их по дате вставки в порядке убывания. Наконец, мне нужно ввести предложения where для 3 полей.

public class Record
{
   public DateTime CreatedOn {get; set;}
   public string Filter1 {get; set;}
   public string Filter2 {get; set;}
   public bool Filter3 {get; set;}
}

Я считаю, что Azure Table Storage не поддерживает вторичные индексы, поэтому я рассматриваю CosmosDB. Проблема в том, что каждый логический раздел в CosmosDB ограничен 20 ГБ. Я не могу вывалить все в один раздел. Я думаю о разрезании данных по горизонтали на основе поля CreatedOn (dd/mm/yyyy без компонента времени). Это помогает мне распределять данные, но я застрял в части запроса, чтобы прочитать их.

Данные генерируются пользователем; таким образом, я не знаю, какие значения CreatedOn будут присвоены. Если я разбиваю на CreatedOn, как я могу сделать свой запрос интеллектуальным, чтобы знать, какой будет следующий ключ раздела, когда я достигну конца предыдущего раздела?

Пример:

Record1 CreatedOn => 28.05.2020

Record2 CreatedOn => 28.05.2020

Record3 CreatedOn => 22.05.2020

Record4 CreatedOn => 5/10/2020

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

Что касается запросов:

Filter1 и Filter2 могут иметь 5 и 12 различных значений соответственно. Filter3 - это просто логическое значение.

Пример запроса будет выглядеть так:

select top 20 from record 
where Filter1 = 'Value1' and Filter2 = 'Value2' and Filter3 = false 
order by CreatedOn desc

Другой пример запроса такой же, как и выше, без Filter2.

select top 20 from record 
where Filter1 = 'Value1' and Filter3 = false 
order by CreatedOn desc

1 Ответ

0 голосов
/ 30 мая 2020

Используйте Cosmos SQL API. Вы можете использовать Order by для сортировки по запросу. По умолчанию все поля проиндексированы. Вы можете настроить политику индексирования, включив составные индексы, чтобы сделать запросы более эффективными.

Выберите PK, который будет иметь широкий диапазон возможных значений для равномерного распределения потребления единиц запроса (RU) и хранения данных по всем логическим разделам. Кроме того, вы должны знать значение PK для большинства ваших запросов. Вы будете использовать это в своем предложении where, чтобы механизм запросов запрашивал только c разделы, в которых находятся интересующие данные.

В вашем случае, каким должно быть это свойство PK?

public class Record
{
   public DateTime CreatedOn {get; set;}
   public string Filter1 {get; set;}
   public string Filter2 {get; set;}
   public bool Filter3 {get; set;}
}

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

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

public class Record
{
   public DateTime CreatedOn {get; set;}
   public string Filter1 {get; set;}
   public string Filter2 {get; set;}
   public bool Filter3 {get; set;}
   public string UserID {get; set;}
}

Теперь вы можете запросить

select top 20 from record 
where Filter1 = 'Value1' and Filter2 = 'Value2' and Filter3 = false  and UserID = 'somevalue' order by CreatedOn desc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...