私は現在、ユーザーのフィードを取得する必要があるサイトに取り組んでいます。しかし、データベースに 300 個のフィードがある場合、フェッチを最適化するにはどうすればよいでしょうか。フィードをフェッチする cron ジョブをセットアップするつもりですが、1 秒ごとに 5 のように実行する必要がありますか?
PHPでこれを最善の方法で行う方法についてのアイデアはありますか?
私があなたの質問を理解しているなら、あなたは基本的にフィードアグリゲーターサイトで働いていますか?
次のことができます。1 horごとに更新することから始めます(たとえば)。いくつかのフィードから十分なエントリがある場合-エントリ間の平均間隔を計算します。次に、その間隔をそのフィードをフェッチするための間隔として使用します。
たとえば、サイトが過去7日間に7つの記事を公開した場合、24時間(1日)ごとにフィードを取得できます。
私はこのアルゴリズムをいくつかの変更を加えて使用します。この平均間隔を計算するときは、2で割ります(あまり頻繁にフェッチしないようにするため)。結果が60分未満の場合-間隔を1時間に設定したか、24時間よりも大きい場合は24時間に設定しました。
たとえば、次のようなものです。
public function updateRefreshInterval() {
$sql = 'select count(*) _count ' .
'from article ' .
'where created>adddate(now(), interval -7 day) and feed_id = ' . (int) $this->getId();
$array = Db::loadArray( $sql );
$count = $array[ '_count' ];
$interval = 7 * 24 * 60 * 60 / ( $count + 1 );
$interval = $interval / 2;
if( $interval < self::MIN_REFRESH_INTERVAL ) {
$interval = self::MIN_REFRESH_INTERVAL;
}
if( $interval > self::MAX_REFRESH_INTERVAL ) {
$interval = self::MAX_REFRESH_INTERVAL;
}
Db::execute( 'update feed set refresh_interval = ' . $interval . ' where id = ' . (int) $this->getId() );
}
テーブルは「feed」、「refreshed」はフィードが最後に更新されたときのタイムスタンプ、「refresh_interval」は同じフィードの2つのフェッチ間の望ましい時間間隔です。
新しい情報に基づいて、私は次のようなことをすると思います:
「最初の」クライアントが更新作業を開始し、タイムスタンプを保存します。情報を要求する他のすべてのクライアントは、その情報が古くなるまでキャッシュされた情報を取得します。クライアントからの次のヒットはキャッシュをリフレッシュし、それは次に古いものになるまですべてのクライアントによって使用されます。
更新作業を実際に開始するクライアントは、作業が完了するまで待つ必要はなく、古いキャッシュ バージョンを提供し、作業が完了するまでそれを続けます。
そうすれば、クライアントが要求していない場合は何も更新する必要がありません。
行うべき最善のことは、「親切」であり、多くの不必要なリクエストでフィードを過負荷にしないことです. 約 150 のブログの更新を監視する Web アプリケーションの 1 つの更新時間を 1 時間に設定しました。それらが最後にチェックされた時間をデータベースに保存し、それを使用していつ更新するかを決定します。フィードはランダムに追加されたため、すべてが同時に更新されるわけではありません。
私はこれを行うためにpfetchを書きました。小さいですが、非常に重要な側面がいくつかあります。
私のcronベースのフェッチャーが問題になりつつあったので、私は実際にそれを書きました。今では、インターネット上で必要なものをランダムに取得するように構成し、状況が変化するたびにスクリプトを実行して、自分の Web サイトの一部を更新しています。