Elasticsearch PHP批量索引性能与单个索引性能的比较

3

我使用elasticsearch-php对elasticsearch进行了基准测试。我比较了逐一索引10,000个文档所需的时间与批量索引1,000个文档共10,000个文档所需的时间。

在我的VPN服务器上,配置是3个内核和2GB内存,无论是否使用批量索引,性能都相当。

我的PHP代码(灵感来自一个帖子):

<?php
set_time_limit(0);  //  no timeout
require 'vendor/autoload.php';
$es = new Elasticsearch\Client([
    'hosts'=>['127.0.0.1:9200']
]);
$max = 10000;

// ELASTICSEARCH BULK INDEX
$temps_debut = microtime(true);
for ($i = 0; $i <=  $max; $i++) {
    $params['body'][] = array(
        'index' => array(
            '_index' => 'articles',
            '_type' => 'article',
            '_id' => 'cle' . $i
        )
    );
    $params['body'][] = array(
        'my_field' => 'my_value' . $i
    );
    if ($i % 1000) {   // Every 1000 documents stop and send the bulk request
        $responses = $es->bulk($params);
        $params = array();  // erase the old bulk request    
        unset($responses); // unset  to save memory
    }
}
$temps_fin = microtime(true);
echo 'Elasticsearch bulk: ' . round($i / round($temps_fin - $temps_debut, 4)) . ' per sec <br>';

// ELASTICSEARCH WITHOUT BULK INDEX
$temps_debut = microtime(true);
        for ($i = 1; $i <= $max; $i++) {    
            $params = array();
            $params['index'] = 'my_index';
            $params['type']  = 'my_type';
            $params['id']    = "key".$i;
            $params['body']  = array('testField' => 'valeur'.$i);
            $ret = $es->index($params);
        }
$temps_fin = microtime(true);
echo 'Elasticsearch One by one : ' . round($i / round($temps_fin - $temps_debut, 4)) . 'per sec <br>';
?>

Elasticsearch批量插入:每秒1209个 Elasticsearch逐一插入:每秒1197个

我的批量索引有什么问题可以提高性能吗?

谢谢


我认为问题是因为您将 $es->bulk($params) 放在循环内部,让我们尝试将它们放在循环外面。 - Alank_Ilalank
如果你需要通过网络发送数据,速度差异真的很明显。如果你使用cURL逐个发送数据,你不可能达到每秒1000个的速度。 - Caedmon
1个回答

4

替换:

if ($i % 1000) {   // Every 1000 documents stop and send the bulk request

使用:

if (($i + 1) % 1000 === 0) {   // Every 1000 documents stop and send the bulk request

否则你将查询每个非0值(即1000中的999)...显然,这仅在$max是1000的倍数时才有效。

此外,修正此错误:

for ($i = 0; $i <=  $max; $i++) {

将迭代 $max + 1 个项目。请将其替换为:

for ($i = 0; $i < $max; $i++) {

你初始化 $params 的方式可能有问题。难道你不应该在循环外设置它,并且只在每个 ->bulk() 后清理 $params['body']?当你使用 $params = array(); 时,会将所有内容都清空。

此外,请记住,ES 可能分布在群集上。批量操作可以分配到工作负载相同的节点上。因此,在单个物理节点上不可见的一些性能缩放可能是可行的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接