Оптимальный способ создания монго-документов с учетом ttl и дискового ввода-вывода

Какова наилучшая стратегия использования индекса TTL в БД Mongo с учетом соотношения дискового ввода-вывода.

Предисловие:

Я работаю в кластерной инфраструктуре mongodb (v2. *), Где каждый узел имеет около 1 ТБ жесткого диска.
Там информация о регистрации сохраняется в течение 7 дней. По истечении этого времени они не нужны и должны быть удалены. Существует 6 баз данных с 10 коллекциями в каждой и более 10 миллионов документов на коллекцию. Давайте предположим, что мы храним 100 ГБ временных данных каждый день.

Поэтому я создал простой индекс в поле createAt.

  db.my_collection.ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 604800, background : true });

Это удалит все документы, вставленные в эту коллекцию, через 7 дней после отметки времени, которая была введена в createdAt, Это ясно для меня. Но я не уверен, как создавать документы, которые будут сохранены в коллекции.

Документы Монго для фоновых индексов гласят:

The background task that removes expired documents runs every 60 seconds.

Вопрос:

Каков наилучший способ создать этот индекс TTL, если подумать о будущем удалении.

например
Вот 3 способа, которыми мы можем создать объекты для сохранения. Синтаксис, который я использовал, php, но это не имеет значения.

Опция 1:

   'createdAt' => new MongoDate(strtotime(date('Y-m-d')))

Здесь все документы, созданные сегодня, будут сохранены со временем создания, например. «2015-04-09 00:00:00».
Это означает, что все документы будут «истек» на «2015-04-16 00:00:00».

Pro:

  • Каждый день, вскоре после полуночи, дискус должен уменьшаться на 100 ГБ.
  • Вы можете легко увидеть, если есть и ошибка. Если нет дискусинга, что-то пошло не так.

Минусы:

  • Удаление 100 ГБ данных приведет к огромным дисковым операциям и, возможно, замедлит другие процессы.
  • Документы сохраняются менее чем за 7 дней до пропущенных часов и минут.

Вариант 2:

   'createdAt' => new MongoDate(strtotime(date('Y-m-d h:i:s')))

Здесь все созданные документы будут иметь разное время создания, например, «2015-04-09 13:23:45».
Это означает, что срок действия этого образца документа будет истек «2015-04-16 13:23:45».

Pro:

  • Документы сохраняются ровно 7 дней.
  • Диск будет почти постоянным в течение всего дня. Возможность вмешательства в другие процессы меньше.

Минусы:

  • Проверить наличие ошибки не так просто, как вариант 1, так как документы будут удалены в течение дня.
    Там не будет огромный скачок в использовании диска.

(Вариант 3):

Я думаю, что это должно быть так же, как вариант 2. Тем не менее, я хотел бы упомянуть об этом здесь.

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

db.my_collection.ensureIndex( { "deleteAt": 1 }, { expireAfterSeconds: 0, background : true });

А затем создайте объект следующим образом:

'deleteAt' => new MongoDate(strtotime("+7 days")),

Как вы думаете, это лучшая возможность? У кого-нибудь был опыт с такой проблемой / инфраструктурой? Я хотел бы получить отзывы от опытных разработчиков mongodb.

0

Решение

отказЯ ни в коем случае не разработчик PHP, поэтому я не могу дать вам никакого кода PHP.

Проблема здесь в том, что вы хотите удалить все данные в начале дня. Поэтому, когда задача TTL запускается впервые после 00:00, она пытается удалить все документы, как вы написали

Однако ваши предположения не совсем точны. Если запись в журнале была сделана сегодня в 16:00, точной датой истечения срока хранения с недельным хранением (604800 секунд) будет четверг, 16 апреля 2015 г. в 16:00.

Таким образом, самый простой способ распределить дисковый ввод-вывод в течение 1440 запусков фонового процесса TTL — это использовать не только дату в качестве ссылки, но и время.

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

{
_id: <SomeObjectId>,
entry: "Something happened!"createdAt: ISODate("2015-04-02T09:11:27.038Z")
}

Вы сможете выбрать все соответствующие записи так же просто, как

db.logentries.find({createdAt:{$gt:ISODate("2015-04-03T00:00:00.000Z") } })

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]