合并完成后如何运行Sphinx索引器?

时间:2012-10-15 23:51:10

标签: sphinx

我已经设置了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 个答案:

答案 0 :(得分:2)

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

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

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

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

(同样使用pgrep,这也意味着两个增量更新中的第二个首先是不合适的,第一个将始终刚刚开始)

也改为说

34 23 * ...

即而不是“30”,这意味着发生与三角洲完全相同的时间。三角洲已经开始了,意味着永远不会得到合并。

答案 1 :(得分:1)

创建一个

的小shell脚本
  1. 索引delta
  2. 将delta合并回主
  3. 更新数据库以更新计数器标志(主要已更改,因此增量需要使用新计数器)
  4. 再次重新索引delta
  5. 作为shell脚本可确保它们按顺序运行。

    技术上也可能会错过1)因为其他* / 5最近总是会运行。

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

答案 2 :(得分: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或用户表是否有更新。如果没有,甚至不打扰运行索引器。

答案 3 :(得分:1)

对于任何定期任务,我建议在脚本的开头创建一个锁文件,以避免重新进入并检查它是否存在于脚本开头。

脚本包装器示例(也可用于定期MySQL备份)在这里:http://astellar.com/2012/10/backups-running-at-the-same-time/