# Plain indexes replication

Manticore Search（以及Sphinx）目前尚未原生支持普通索引或RT索引的复制（尽管我们正在开发此功能，**如果您想成为测试人员，请发送邮件至info@manticoresearch.com**），因此如果您需要在其他地方复制Manticore Search / Sphinx数据，必须自行实现。您可能需要它的原因：
- 可扩展性：您希望在服务器上平衡负载（例如，您可以将所有Manticore查询的一半发送到一个服务器，其余发送到另一个服务器）以提高吞吐量，降低延迟或服务器负载
- 高可用性：您希望在主Manticore存储因某些原因不可用时，立即有可用的Manticore索引副本
- 您希望将上述两者结合，并自动检测问题并在服务器之间切换（例如，当一个服务器崩溃时，另一个服务器会自动开始处理所有查询）

执行普通索引复制的最简单方法是 <span id="more-312"></span> 将您的Manticore配置复制到另一台服务器，并在该服务器上使用'indexer'重新建立索引，但这种方法的问题在于，首先重建索引需要消耗资源，其次难以提供良好的数据同步级别：Manticore普通索引将从同一源（例如您的主数据库）单独重建，最终它们应该相同，但由于某些服务器负载较重或您频繁更新源，可能会出现延迟，原因可能有很多。

我们可以采用另一种方法来确保副本100%一致且数据出现延迟最小：
1. 仅在一个地方（我们称之为MASTER）进行索引
2. 使用rsync或其他工具将索引复制到SLAVE（或从MASTER复制，如果您在从服务器上运行）
3. 告诉Manticore在所有地方使用新重建的数据

以下是一个示例：
  
  
### 主服务器上的索引

这里的技巧是创建一个全新的“伪”索引，完全继承自您的正常索引，仅修改“path”（请参见idx_new下方）：


```bash
index idx {
    path = sphinx_tmp/idx
    source = src
}

index idx_new:idx {
    path = sphinx_tmp/idx_new
}


```
“新”索引可以有不同的名称或路径，这没关系，我们只需要知道新索引将被放置在哪里。

构建“新”索引：


```bash
[snikolaev@dev01 ~]$ indexer -c sphinx_replication.conf idx_new
Manticore 2.6.1 9a706b4@180119 dev
Copyright (c) 2001-2016, Andrew Aksyonoff
Copyright (c) 2008-2016, Sphinx Technologies Inc (http://sphinxsearch.com)
Copyright (c) 2017-2018, Manticore Software LTD (http://manticoresearch.com)

using config file 'sphinx_replication.conf'...
indexing index 'idx_new'...
collected 3 docs, 0.0 MB
sorted 0.0 Mhits, 100.0% done
total 3 docs, 29 bytes
total 0.004 sec, 7045 bytes/sec, 728.86 docs/sec
total 7 reads, 0.000 sec, 13.7 kb/call avg, 0.0 msec/call avg
total 12 writes, 0.000 sec, 0.0 kb/call avg, 0.0 msec/call avg



```
完成之后，您应该在索引目录中看到类似以下内容：


```bash
[snikolaev@dev01 ~]$ ls -la sphinx_tmp/
total 460
drwxrwxr-x 2 snikolaev snikolaev 4096 Feb 26 01:09 .
drwx------+ 149 snikolaev snikolaev 405504 Feb 26 01:09 ..
-rw-r--r-- 1 snikolaev snikolaev 112 Feb 26 01:09 idx_new.spa
-rw-r--r-- 1 snikolaev snikolaev 24 Feb 26 01:09 idx_new.spd
-rw-r--r-- 1 snikolaev snikolaev 1 Feb 26 01:09 idx_new.spe
-rw-r--r-- 1 snikolaev snikolaev 363 Feb 26 01:09 idx_new.sph
-rw-r--r-- 1 snikolaev snikolaev 57 Feb 26 01:09 idx_new.spi
-rw-r--r-- 1 snikolaev snikolaev 0 Feb 26 01:09 idx_new.spk
-rw-r--r-- 1 snikolaev snikolaev 0 Feb 26 01:09 idx_new.spm
-rw-r--r-- 1 snikolaev snikolaev 8 Feb 26 01:09 idx_new.spp
-rw-r--r-- 1 snikolaev snikolaev 35 Feb 26 01:09 idx_new.sps
-rw-r--r-- 1 snikolaev snikolaev 112 Feb 26 01:07 idx.spa
-rw-r--r-- 1 snikolaev snikolaev 24 Feb 26 01:07 idx.spd
-rw-r--r-- 1 snikolaev snikolaev 1 Feb 26 01:07 idx.spe
-rw-r--r-- 1 snikolaev snikolaev 363 Feb 26 01:07 idx.sph
-rw-r--r-- 1 snikolaev snikolaev 57 Feb 26 01:07 idx.spi
-rw-r--r-- 1 snikolaev snikolaev 0 Feb 26 01:07 idx.spk
-rw------- 1 snikolaev snikolaev 0 Feb 26 01:09 idx.spl
-rw-r--r-- 1 snikolaev snikolaev 0 Feb 26 01:07 idx.spm
-rw-r--r-- 1 snikolaev snikolaev 8 Feb 26 01:07 idx.spp
-rw-r--r-- 1 snikolaev snikolaev 35 Feb 26 01:07 idx.sps



```
idx.* 是您的正常索引文件，idx_new.* 是“新”索引文件。
  
  
### 索引复制

现在您已经构建了新索引，需要将其传递到所有希望运行的地方。您可以使用任何方法：rsync、scp、ftp、samba等。


```bash
scp sphinx_tmp/idx_new.sp* SLAVE:sphinx_tmp/


```
  
  
### 索引轮换

现在您已经将索引传播到所有从服务器，剩下的就是轮换索引，使新索引生效。以前Sphinx只能通过向searchd实例发送HUP信号或重启实例来实现。从Sphinx 2.3.1和Manticore Search开始，[RELOAD INDEX](https://docs.manticoresearch.com/latest/html/sphinxql_reference/reload_index_syntax.html) 可用，允许通过SphinxQL轮换索引，更重要的是可以指定searchd应查找索引文件的路径，例如在我们的情况下：


```bash
[snikolaev@dev01 ~]$ mysql -P9314 -h0 -e "RELOAD INDEX idx FROM 'sphinx_tmp/idx_new'"


```
之后，您会看到“新”索引文件在目录中消失：


```bash
[snikolaev@dev01 ~]$ ls -la sphinx_tmp/
total 432
drwxrwxr-x 2 snikolaev snikolaev 4096 Feb 26 01:15 .
drwx------+ 149 snikolaev snikolaev 405504 Feb 26 01:09 ..
-rw-r--r-- 1 snikolaev snikolaev 112 Feb 26 01:09 idx.spa
-rw-r--r-- 1 snikolaev snikolaev 24 Feb 26 01:09 idx.spd
-rw-r--r-- 1 snikolaev snikolaev 1 Feb 26 01:09 idx.spe
-rw-r--r-- 1 snikolaev snikolaev 363 Feb 26 01:09 idx.sph
-rw-r--r-- 1 snikolaev snikolaev 57 Feb 26 01:09 idx.spi
-rw-r--r-- 1 snikolaev snikolaev 0 Feb 26 01:09 idx.spk
-rw------- 1 snikolaev snikolaev 0 Feb 26 01:15 idx.spl
-rw-r--r-- 1 snikolaev snikolaev 0 Feb 26 01:09 idx.spm
-rw-r--r-- 1 snikolaev snikolaev 8 Feb 26 01:09 idx.spp
-rw-r--r-- 1 snikolaev snikolaev 35 Feb 26 01:09 idx.sps


```
并且在searchd日志中，您会看到轮换成功（仅耗时1ms）：


```bash
[snikolaev@dev01 ~]$ tail -n 2 sphinx_replication.log
[Mon Feb 26 01:15:39.003 2018] [3346] rotating index 'idx': started
[Mon Feb 26 01:15:39.004 2018] [3346] rotating index 'idx': success


```
现在，您需要做的就是从所有目标处制作的副本中调用RELOAD INDEX命令来轮换索引，例如：


```bash
[snikolaev@dev01 ~]$ for host in SLAVE 0; do echo $host; mysql -P9314 -h$host -e "RELOAD INDEX idx FROM 'sphinx_tmp/idx_new';"; done;
SLAVE
0


```
  
  
### 注意事项
- 当您启动Manticore时，可能会看到以下警告：


```bash
WARNING: index 'idx_new': prealloc: failed to open sphinx_tmp/idx_new.sph: No such file or directory; NOT SERVING



```
此警告是可以接受的，因为我们不需要Manticore Search提供idx_new服务，我们只需要此索引作为新数据的临时存储。
- 对于大型索引，索引同步可能需要较长时间，但无论如何，数据在文件系统/网络层的同步对您的服务器来说比使用‘indexer’从头开始重建索引更容易。
- 请记住，如果您执行属性更新，也需要在所有从服务器上执行，因为如前所述，目前还没有高级别的复制功能。**如果您需要此功能并想成为测试人员，请联系我们。**
- 通常，您会有一个索引脚本，首先准备新索引，然后将其复制到所有需要的地方，然后在所有地方轮换索引。这是最简单的方法，在实际应用中，您可能还想进行索引验证，在从服务器上进行索引以提供索引高可用性，使用锁来确保不会同时在N台服务器上重建索引等。我们已经为许多客户做过这些。如果您需要这方面的支持，请发送电子邮件至 <contact@manticoresearch.com>。您可以在[这里](https://manticoresearch.com/services/)查看我们的支持计划。

总而言之，我想说的是，直到RT索引的高级复制功能出现，而许多人仍在使用普通索引时，上述方法是有意义的，并且可以轻松实现普通索引的复制。
