Sphinx分布式索引会减慢索引编制速度吗?

时间:2018-12-29 09:25:17

标签: sphinx

我有一个Sphinx索引,该索引是使用单个RT索引构建的。在建立索引期间,我测量了每分钟的插入次数。每分钟大约10.000个文档的数字。

现在,我已经使用distributed索引及其下面的4 RT索引“升级”了我的Sphinx索引。但是,当我加载相同的文档时,加载时间会更长。目前,我每分钟仅加载3.000 - 6.000个文档,而由于使用了多个内核,因此我希望它能比以前更快地进行索引/处理文档?

有人可以向我澄清吗?请注意,我已经阅读了有关分布式索引的文档,该文档仅影响搜索持续时间(搜索是分布式的)。但是,我正在将文件添加到本地索引,因此处理至少应该与使用一个RT-index一样快吗?我无法解释我的情况会降低处理速度吗?

简单的解释。

  • 1个RT索引平均每分钟加载10.000个文档
  • 平均每分钟4个RT索引(所有本地索引)加载3.000-6.000个文档

请注意,两种情况都是由同一文档加载器驱动的,因此,本地索引的执行速度似乎慢于1个本地索引?

当前,这是每分钟添加到索引中的文档数量的加载速度。还请注意波动。

indexing speed

我已经验证了服务器的负载,这与一个RT索引的情况没有多大区别,该索引平均每分钟平均加载10.000个文档

1 个答案:

答案 0 :(得分:0)

您可能会遇到许多因素。

很显然,我还没有看到您的代码,因此,我写了一个小测试方案来向您展示在sphinx上为文档建立索引时特别是在RT索引上的不同限制因素。我假设您正在使用sphinxQL(据我所知,您不能使用API​​插入文档,只能对其进行更新和查询)。

让我们定义一些事情。首先,我们将制作四个包含以下内容的rt索引(rt_1rt_2rt_3rt_4

index rt_4 {
    type = rt
    path = /tmp/rt_4                
    rt_field = title
    rt_field = content
    rt_attr_uint = gid
}

分布式索引无关紧要,因为您无法直接对其进行索引-您必须指定将文档添加到的索引。

以下非常简单,非常粗糙的PHP脚本允许您将随机文档批量添加到索引中,从而可以指定批量大小和每个插入的大小。您很快就会明白原因:

<?php
function generateRandomString($length = 100) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}
function generate_document() {
  $gid = random_int(0, 6553500000);
  return "('".generateRandomString()."','".generateRandomstring()."',".$gid.",".$gid.")";
}

function index($pdo, $idx="rt_1", $doc_count=1) {
  $query = array("INSERT INTO $idx (title, content, id, gid) VALUES ");
  $docs = array();
  for ($i = 0; $i < $doc_count; $i++) {
    $docs[] = generate_document();
  }
  return $pdo->query($query[0] . implode(", ", $docs));
}
$idx = $argv[1];
$total_docs = (int)$argv[2];
$per_item = (int)$argv[3];
$runs = ceil($total_docs/$per_item);
$start = microtime(true);
$handle = new PDO("mysql:host=127.0.0.1;port=9306;", '', '');
for ($i = 0; $i < $runs; $i++) {
  echo "Run $i\n";
  index($handle, $idx, $per_item);
}
$end = microtime(true);
echo "Done in ".($end-$start)." seconds\n";

对于此测试,我在一个docker容器中运行了狮身人面像;再次,这里没有魔术。

让我们以每1k(即1000个循环)的10万个文档插入开始:

# php test.php rt_2 100000 1000
Run 0
...
Run 99
Done in 9.6652419567108 seconds

出于基准测试的目的,我们做同样的事情,一次插入1个文档:

# php test.php rt_2 100000 1
Done in 41.049964904785 seconds

由于INSERT的大小,我们刚刚浪费了300%的初始时间,最糟糕的是,大部分损失都浪费在了I / O和RTT上。它实际上与狮身人面像无关。这通常是大多数人忽略的因素-您可以在狮身人面像上批量插入。 这很可能是您的问题出处

关于RT索引,还有其他因素。例如,如果您尝试同时插入相同的索引,则由于在RT索引中插入不支持并发,因此您将很快达到饱和状态-只要您正在处理索引,就不会有其他过程还添加/修改文档。这就是为什么人们倾向于使用分布式索引并在后台对文档进行分区的原因。

这还具有其他含义。发生这种情况时,sphinx还需要跟踪哪些索引被锁定以供其他进程进行编辑。刷新时间也会影响索引编制效率,可用线程数,服务器负载,服务器上的I / O负载甚至服务器的交换能力(将其设置为0,BTW)也会影响索引效率。

例如,我以前工作过的一家公司按日期显示文件索引。因此,您将拥有201701201702等。将文档存储在这些索引之一中,并且还进行了大容量插入以使所有内容尽可能快地运行。