2012-02-04 9 views
2

私はNのレコードを持つデータベーステーブルを持っています。それぞれのテーブルは4時間ごとにリフレッシュする必要があります。 「リフレッシュ」操作はかなりリソースを消費します。私は時折実行されるスケジュールされたタスクを書いて、それらをリフレッシュして、負荷のスパイクを滑らかにしたいと思います。定期的な作業を時間外に分散/平滑化する

every 10 minutes: 
    find all records that haven't been refreshed in 4 hours 
    for each record: 
     refresh it 
     set its last refresh time to now 

(技術的な詳細::;それだけピックアップして実行するワーカースレッドプールのタスクをキューに上記非同期であり、「それはリフレッシュ」

私が始めた、最も単純なタスクは、この(擬似コード)であります)

この原因は、4時間ごとに巨大なリソース(CPU/IO)の使用が急増し、残りの時間が空転することです。マシンは他のものもやっているので、これは悪いです。

これらのリフレッシュを多かれ少なかれ均等に配置する方法を見つけようとしています。つまり、N/(10mins/4hours)の周りに、N/24のように、毎回リフレッシュしたいと思います走るもちろん、正確である必要はありません。

注:

  • 私だけではめったにとして、私は、(その最初の24時間のスパイクがあるでしょうが、それらは、時間をかけて滑らかになり、言う)アルゴリズムは、作業を開始するために時間を割いてと大丈夫ですよスケジューラーをオフラインにする予定です。
  • レコードは他のスレッドによって絶えず追加されたり削除されているので、反復の間にはNの値については何も想定できません。
  • 4時間+/- 20分ごとにレコードが更新されても問題ありません。
+0

レコードが頻繁に更新される場合(10分に2回など)は問題ですか?もちろん、長期的にはそうではありませんが、最初の移行中に許可されていれば事態を単純化するかもしれません。 –

+0

ええ、それはいいです。夕方になると全体的な作業が増えることは明らかですが、平均的なケースではCPUが駄目にならない限りは問題ありません。 – nitwit

+0

通常、アップデートにはどのくらいの時間がかかりますか? (ジョブキューが空になるまでの時間) –

答えて

1

すべてのタイムスタンプを同期させるには、完全にリフレッシュしてください。その時点から、10分ごとに、最も古いN/24レコードをリフレッシュします。

負荷は最初から安定しており、24回の実行(4時間)後、すべてのレコードは4時間間隔で更新されます(Nが固定されている場合)。挿入するとリフレッシュ間隔が短くなります。削除は、削除されたレコードのタイムスタンプに応じて増減を引き起こす可能性があります。しかし、あなたは40分のウィンドウの外に何かを押し始める前に、(一度にあなたのテーブルの10%のように)かなり多くを削除する必要があると思う。安全な側にいるためには、N/24回以上走らせることができます。

+0

素晴らしいソリューションです。特にシンプルです。私は4時20分より古いレコードを強制的にリフレッシュするようにしました。これにより、レコードの削除が長すぎたり、タスクのスケジュールが欠落したりしても、失われたレコードはなくなりました。 – nitwit

0
Each minute: 
    take all records older than 4:10 , refresh them 
    If the previous step did not find a lot of records: 
     Take some of the oldest records older than 3:40, refresh them. 

これは、最終的にはより均等に間隔をあけ最終更新時間を作る必要があります。 「たくさん」と「いくらか」というのは、あなた自身を(おそらくNに基づいて)決めるべきであることを意味します。

0

各レコードに独自のリフレッシュ間隔時間を与えます。これは、3:40から4:20の間の乱数です。

関連する問題