1

ディスク I/O 比率を考慮して、Mongo DB で TTL インデックスを使用するための最良の戦略は何ですか。

序文:

私は、各ノードに約 1 TB のハードディスクがあるクラスター化された mongodb (v2.*) インフラストラクチャで作業しています。そこには、ログ情報が 7 日間保存されます。それ以降は不要になり、削除する必要があります。それぞれ 10 個のコレクションを持つ 6 つのデータベースがあり、コレクションごとに 1,000 万を超えるドキュメントがあります。毎日 100GB の一時データを保存しているとします。

そのため、createdAt フィールドに単純なインデックスを作成しました。

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

これにより、 に挿入されたタイムスタンプから 7 日後に、このコレクションに挿入されたすべてのドキュメントが削除されcreatedAtます。これは私には明らかです。しかし、コレクションに保存されるドキュメントを作成する方法がわかりません。

バックグラウンド インデックスの mongo ドキュメントには次のように記載されています。

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」に「期限切れ」になることを意味します。

プロ:

  • 毎日、真夜中過ぎにディスク使用量が 100GB 減少するはずです。
  • エラーがあるかどうかを簡単に確認できます。ディスク使用率が低下しない場合は、何か問題が発生しています。

短所:

  • 100GB のデータを削除すると、巨大なディスク io が発生し、他のプロセスが遅くなる可能性があります。
  • 時間と分が欠落しているため、ドキュメントは正確に 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」に「期限切れ」になることを意味します。

プロ:

  • ドキュメントは正確に 7 日間保存されます。
  • ディスク io は 1 日を通してほぼ一定です。他のプロセスに干渉する可能性が低くなります。

短所:

  • ドキュメントは 1 日を通して削除されるため、エラーがあるかどうかを確認するのはオプション 1 ほど簡単ではありません。ディスク使用量が大幅に増加することはありません。

(オプション 3):

これはオプション 2 と同じであると思いますが、ここで言及したいと思います。

特定の時間が経過しても有効期限が切れず、特定の日付になるようにインデックスを変更することもできます。

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

次に、この方法でオブジェクトを作成します。

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

最良の可能性は何だと思いますか?そのような問題/インフラストラクチャを経験した人はいますか? 経験豊富な mongodb 開発者からのフィードバックをお待ちしています。

4

1 に答える 1

1

免責事項: 私は決して PHP 開発者ではないので、PHP コードを提供することはできません。

ここでの問題は、一日の始まりにすべてのデータを削除したいということです。したがって、TTL タスクが 00:00 以降に初めて実行されると、あなたが書いたように、すべてのドキュメントを削除しようとします

ただし、あなたの仮定は正確ではありません。ログエントリが今日の 16:00 に作成された場合、1 週間の保持 (604800 秒) の正確な有効期限は、2015 年 4 月 16 日木曜日の16:00 になります。

したがって、TTL バックグラウンド プロセスの 1440 回の実行にディスク IO を分散させる最も簡単な方法は、日付だけでなく時刻も参照することです。

ただし、過去 6 日間と今日のエントリだけを表示したい場合もあります。これは、クエリの結果を制限することで簡単に実現できます。次のようなドキュメント構造が与えられた場合

{
  _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") } })

これは、今から 6 日前と今日のすべてのエントリを返します。明らかに、この場合、いくつかの日付計算を行う必要があります。

于 2015-04-09T13:48:53.270 に答える