0

我已经设置了 4 个 CRON 作业来自动重新索引我的 Sphinx 索引,如下所示:

*/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,我希望在每个实例中都使用它来检查索引器是否已经在运行。我的目的是防止任何潜在的资源匮乏重叠。

前两个 Cron 作业每 5 分钟运行一次,并为我的两个主要索引更新 Delta 索引。

后两个每天运行一次(一个在晚上 11:30,另一个在上午 12 点),并将 delta 索引合并到它们的主要对应物中。

我的理解是,在这些索引合并之后,我需要在 delta 上重新运行索引,以便删除所有先前合并的数据,并基本上清理它们以准备第二天的索引。

如何确保合并完成后自动发生这种情况?显然,我可以再添加两个 cron 作业,但我需要在相关合并完成后立即执行它们。

提前致谢。

4

4 回答 4

2

另一个相关的问题,你应该做

*/6 ... indexer --rotate users_delta 涟漪_delta

即在一个命令中更新两者。然后 indexer 建立两个索引,然后执行旋转。

通过两个并行过程,两个旋转最终可能会相互踩踏。

(同样对于 pgrep,这也意味着两个增量更新中的第二个不太可能是第一个,第一个总是刚刚开始)

也改说

34 23 * ...

即而不是“30”,这意味着与增量完全相同的时间发生。并且增量很可能已经开始,这意味着永远不会得到合并。

于 2012-10-16T10:01:16.433 回答
1

创建一个小的 shell 脚本

  1. 索引 delta
  2. 将 delta 合并回主
  3. 更新数据库以更新计数器标志(主要已更改,因此增量需要使用新计数器)
  4. 再次重新索引 delta

作为一个 shell 脚本可以确保它们按顺序运行。

从技术上讲,也可能会错过 1),因为另一个 */5 无论如何都会在最近运行。

无论如何,您还需要运行脚本来运行步骤 3)。斯芬克斯不能为你做到这一点。http://sphinxsearch.com/bugs/view.php?id=517

于 2012-10-16T09:32:18.603 回答
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 之类的)。

它将确保一次只运行一个进程。照顾好所有的动作。如果索引需要更长的时间,那么它只会保持 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 回答