0

以下のように、Sphinx インデックスを自動的に再インデックスする 4 つの CRON ジョブを設定しました。

*/5 * * * /usr/bin/pgrep indexer || time /usr/local/sphinx/bin/indexer --rotate --config /usr/local/sphinx/etc/sphinx.conf ripples_delta
*/5 * * * /usr/bin/pgrep indexer || time /usr/local/sphinx/bin/indexer --rotate --config /usr/local/sphinx/etc/sphinx.conf users_delta
30 23 * * * /usr/bin/pgrep indexer || time /usr/local/sphinx/bin/indexer --config /usr/local/sphinx/etc/sphinx.conf --merge users users_delta --merge-dst-range deleted 0 0 --rotate
0 0 * * * /usr/bin/pgrep indexer || time /usr/local/sphinx/bin/indexer --config /usr/local/sphinx/etc/sphinx.conf --merge ripples ripples_delta --merge-dst-range deleted 0 0 --rotate

上記はpgrepを示しています。これは、インデクサーがすでに実行されているかどうかを確認するためにすべてのインスタンスで使用されていることを願っています. ここでの私の意図は、リソースを大量に消費する可能性のあるオーバーラップを防ぐことです。

最初の 2 つの Cron ジョブは 5 分ごとに実行され、2 つのメイン インデックスのデルタ インデックスを更新します。

2 番目の 2 つは 1 日に 1 回実行され (1 つは午後 11 時 30 分、もう 1 つは午前 12 時)、デルタ インデックスを対応する主要インデックスにマージします。

私の理解では、これらのインデックス マージに続いて、以前にマージされたデータをすべて削除し、翌日のインデックス作成に備えて基本的にそれらをクリーンアップするために、デルタでインデックスを再実行する必要があるということです。

マージの完了時にこれが自動的に行われるようにするにはどうすればよいですか? もちろん、あと 2 つの cron ジョブを追加することもできますが、関連するマージが完了した直後に実行する必要があります。

前もって感謝します。

4

4 に答える 4

2

別の関連する問題、あなたがすべきこと

*/6 ... indexer --rotate users_delta ripples_delta

つまり、1 つのコマンドで両方を更新します。次に、インデクサーは両方のインデックスを構築し、ローテーションを実行します。

2 つの並列プロセスでは、2 つのローテーションが相互に影響を与える可能性があります。

(また、pgrep を使用すると、2 つのデルタ更新の 2 番目が最初に実行される可能性が低く、最初の更新は常に開始されたばかりであることも意味します)

という言い方にも変わります

34 23 * ...

つまり、「30」ではなく、デルタとまったく同じ時間に発生することを意味します。また、デルタはすでに開始されている可能性が高く、つまり、マージが行われることはありません。

于 2012-10-16T10:01:16.433 に答える
1

おそらく、さらに良い方法は、小さな「インデックス作成」デーモンを作成することです。

例えば

<?php

while (1) {
    if (filemtime('path_to_/ripples.sph') < time()-(24*3600)) {
        `indexer --rotate ripples_delta`;
        sleep(10);
        `indexer  --merge ripples ripples_delta --rotate`;
        mysql_query("UPDATE sph_counter ... ");
        `indexer --rotate ripples_delta`;

    } elseif (filemtime('path_to_/users.sph') < time()-(24*3600)) {
        `indexer --rotate users_delta`;
        sleep(10);
        `indexer  --merge users users_delta --rotate`;
        mysql_query("UPDATE sph_counter ... ");
        `indexer --rotate users_delta`;

    } else {
        `indexer --rotate ripples_delta users_delta`;
    }

    sleep(5*60);
    clearstatcache();
} 

このようにすると、このスクリプトを無期限に実行したままにします(これには使用screenしましたが、より堅牢なソリューションはmonitのようなものです)。

一度に1つのプロセスのみが実行されていることを確認します。すべての行動に注意してください。また、インデックス作成に時間がかかる場合は、5分のギャップが維持されます。

本当に賢くするには、mysqlクエリを実行して、rippesまたはユーザーテーブルに更新があるかどうかを確認できます。そして、そうでない場合でも、インデクサーを実行することさえ気にしないでください。

于 2012-10-16T10:12:59.083 に答える
1

定期的なタスクについては、スクリプトの開始時にロック ファイルを作成して再入を回避し、スクリプトの開始時に存在するかどうかを確認することをお勧めします。

スクリプト ラッパーのサンプル (定期的な MySQL バックアップにも使用できます) はこちら: http://astellar.com/2012/10/backups-running-at-the-same-time/

于 2012-10-16T10:29:52.223 に答える
1

小さなシェル スクリプトを作成します。

  1. デルタにインデックスを付けます
  2. デルタをメインにマージします
  3. データベースを更新してカウンターフラグを更新します (メインが変更されたため、デルタは新しいカウンターを使用する必要があります)
  4. デルタを再度インデックス付けします

シェルスクリプトであるため、順番に実行されます。

技術的には、1) を見逃す可能性もあります。他の */5 は常に最近実行されているからです。

いずれにせよ、ステップ 3) を実行するスクリプトを実行する必要もあります。スフィンクスはあなたのためにそれを行うことはできません. http://sphinxsearch.com/bugs/view.php?id=517

于 2012-10-16T09:32:18.603 に答える