php-Sphinx即使没有更长时间的活动,我如何保持连接的有效性?

我在使用 PHP和禁用AUTOCOMIT在RealTime Index中进行批量插入,
例如
// sphinx connection
$sphinxql = MysqLi_connect($sphinxql_host.':'.$sphinxql_port,'',''); 

//do some other time consuming work

//sphinx start transaction
MysqLi_begin_transaction($sphinxql);

//do 50k updates or inserts

// Commit transaction
MysqLi_commit($sphinxql);

并保持脚本运行一夜之间,我早上看到

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate
212334 bytes) in

所以当我仔细检查nohup.out文件的时候,我注意到这些行,

PHP Warning: MysqLi_query(): MysqL server has gone away in /home/script.PHP on line 502
Warning: MysqLi_query(): MysqL server has gone away in /home/script.PHP on line 502

这些行之前的内存使用情况是正常的,但这些行开始增加后的内存使用量,并且它触发了PHP mem_limit并给出了PHP致命错误并且死了.

in script.PHP,line 502 is

MysqLi_query($sphinxql,$update_query_sphinx);

所以我的猜测是,狮身人面像服务器关闭/死亡几个小时/分钟后不活动.

我已经尝试在sphinx.conf中设置

client_timeout = 3600

重新启动searchd

systemctl restart searchd

我仍然面临同样的问题.

那么如果没有长时间的活动存在,我怎么不能让狮身人面像服务器死在我身上呢?

更多信息添加

我一次从50k块的MysqL获取数据,并在while循环中获取每行并在sphinx RT索引中进行更新.喜欢这个

//6mil rows update in MysqL,so it takes around 18-20 minutes to complete this then comes this following part.

$subset_count = 50000 ;

$total_count_query = "SELECT COUNT(*) as total_count FROM content WHERE enabled = '1'" ;
$total_count = MysqLi_query ($conn,$total_count_query);
$total_count = MysqLi_fetch_assoc($total_count);
$total_count = $total_count['total_count'];

$current_count = 0;

while ($current_count <= $total_count){

$get_MysqL_data_query = "SELECT record_num,views,comments,Votes FROM content WHERE enabled = 1  ORDER BY record_num ASC LIMIT $current_count,$subset_count ";

//sphinx start transaction
MysqLi_begin_transaction($sphinxql);

if ($result = MysqLi_query($conn,$get_MysqL_data_query)) {

    /* fetch associative array */
    while ($row = MysqLi_fetch_assoc($result)) {

    //sphinx escape whole array
    $escaped_sphinx = MysqLi_real_escape_array($sphinxql,$row);

    //update data in sphinx index
    $update_query_sphinx = "UPDATE $sphinx_index  
    SET 
        views       = ".$escaped_sphinx['views'].",comments    = ".$escaped_sphinx['comments'].",Votes   = ".$escaped_sphinx['Votes']." 
    WHERE 
        id          = ".$escaped_sphinx['record_num']." ";  

    MysqLi_query ($sphinxql,$update_query_sphinx);

    }

    /* free result set */
    MysqLi_free_result($result);
}
// Commit transaction
MysqLi_commit($sphinxql);

$current_count = $current_count + $subset_count ;
}
所以这里有几个问题,都涉及到运行大流程.

> MysqL服务器已经消失 – 这通常意味着MysqL已经超时,但也可能意味着MysqL进程因内存不足而崩溃.简而言之,这意味着MysqL已经停止响应,并没有告诉客户端为什么(即没有直接的查询错误).看到你说你在一个事务中运行了50k的更新,很可能MysqL刚刚跑出内存.
>允许的内存大小为134217728字节耗尽 – 意味着PHP内存不足.这也导致了MysqL失去记忆的想法.

那么该怎么办呢?

最初的间接解决方案是增加PHPMysqL的内存限制.这不是真正解决根本原因,并且取决于您拥有的部署堆栈的控制量(和知识),这可能是不可能的.

正如少数人提到的,批处理过程可能会有所帮助.在不知道您正在解决的实际问题的情况下,很难说出最好的方法.如果可以计算出1000000或20000个记录,一批50000个可能会解决您的问题.如果在一个过程中花费的时间太长,您还可以查看使用消息队列(RabbitMQ一个很好的项目,我已经在许多项目中使用),以便您可以同时运行多个进程处理较小的批次.

如果您正在做一些需要所有600万条记录的知识来执行计算的内容,那么您可能会将该过程分解成若干较小的步骤,将完成的工作“缓存”至此为止“(如此),然后选择下一步的下一步.如何干净地做到这一点很困难(再次,像RabbitMQ这样的事情可以通过在每个进程完成时触发一个事件来简化,以便下一个可以启动).

那么简而言之就是你最好的两个选择:

>可以在任何地方的问题上投入更多的资源/内存将问题分解成较小的自给自足的大块.

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...