Solr - 主/从同步

Solr 1.4 以后,可以使用基于 http 的同步方式。之前基于 ssh/rsync 的同步方式已经停止维护。还有一种基于 SolrCloud 的方式:https://cwiki.apache.org/confluence/display/solr/SolrCloud 
这里只介绍 ReplicationHandler 基于 http 的方式。 
官方文档: http://wiki.apache.org/solr/SolrReplication

该方式的优点

  1. 不需要其它脚本
  2. 只需要在 solrconfig.xml 中进行配置
  3. Master / Slave 配置都较小
  4. 同样的配置可跨平台使用
  5. 不依赖操作系统的硬链接
  6. 提供WEB页面对结构进行查看及管理

配置方式

主从结构的配置和其它的 RequestHandler 一样。

Master 配置

编辑 solrconfig.xml

<<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler name="/replication" class="solr.ReplicationHandler" >
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst name="master">
        
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="replicateAfter">startup</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="replicateAfter">commit</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>

        
        

        
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="confFiles">schema.xml,stopwords.txt,elevate.xml</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
        
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="commitReserveDuration">00:00:10</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
    </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst>
    
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="maxNumberOfBackups">1</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler>

注意事项

  1. 如果当前的 Master 执行 commit 之类的操作很频繁, 或者网络带宽不是很好,建议把 commitReserveDuration 的值调大一点。
  2. 如果想在启动后,每次 commit / optimize 时都进行同步,则必须要在 replicateAfter 配置中加上 startup, 以及 commit / optimize. 如果只加了 startup, 同步操作在后续的 commit / optimize 都不会触发,只有在启动的时候才会发生.

Slave 配置

文件同步

在 Master 的配置文件中有一个 confFiles 项,可以进行文件的同步。这里可以按如下方式使用:

"confFiles">solrconfig_slave.xml:solrconfig.xml,x.xml,y.xml

这样,Master 上面的 solrconfig_slave.xml 会被保存为 Slave 机器上的 solrconfig.xml, 其它文件:x.xml, y.xml 保持自己原文件名不变。

因为 confFiles 可以通过 “:” 进行分隔,冒号前面是 Master 上的文件, 即复制的源文件,冒号后面的是复制到 Slave 后的文件。

配置 solrconfig.xml

<<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler name="/replication" class="solr.ReplicationHandler" >
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst name="slave">
        
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="masterUrl">http://60.124.214.234:8983/solr/main</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>

        
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="pollInterval">00:00:20</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>

        
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="compression">internal</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
        
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="httpConnTimeout">5000</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="httpReadTimeout">10000</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>

        
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="httpBasicAuthUser">username</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="httpBasicAuthPassword">password</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
     </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst>
</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler>

注意事项

如果当前的 Master 使用了 cores, Slave 配置的 url 必须加上 corename, 判断的标准就是:上面的 url 在浏览器中访问要是正常的。

中继服务器

一个 Master 可以对应多个 Slave, 但如果太多的时候,各个 Slave 同时同步 Master 会造成压力过大,而且 Master 带宽的压力也会增大。所以为了保证整个集群的使用, 可以使用 “中继服务器”,就是把其中一台或多台 Slave 做为其它 Slave 的 Master。和 MySQL 集群的里的原理一样。

注意事项

  1. 当一个服务器要配置中中继服务器时, 它的 solrconfig.xml 的 ReplicationHandler 里又要配置 Master 的内容,又要配置 Slave 的内容。(参照上面的配置)
  2. 确保在 replicateAfter 中有 ‘commit’ 配置。哪怕在 Master (中继服务器的 Master )中已经配置了 replicateAfter 的 optimize 选项。这是因为在 Slave (中继服务器也是 Slave) 上,commit 操作只会在从 Master 上下载完 index 后才会触发。Optimize 是永远不会在 Slave 机上执行的。

配置示例

<<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler name="/replication" class="solr.ReplicationHandler">
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst name="master">
      <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="replicateAfter">commit</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
      <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="confFiles">schema.xml,stopwords.txt,synonyms.txt</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
    </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst>
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst name="slave">
      <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="masterUrl">http://60.124.214.234:8983/solr/main</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
      <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="pollInterval">00:00:60</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
    </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst>
  </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler>

启用/禁用

如果要把一个 Slave 转换成 Master。或者想在 Master 和 Slave 上使用同一个配置文件,然后可方便的配置成某个角色,可以如下:

<<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler name="/replication" class="solr.ReplicationHandler" >
  <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst name="master">
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="enable">${enable.master:false}</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="replicateAfter">commit</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="confFiles">schema.xml,stopwords.txt</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
 </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst>
 <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst name="slave">
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="enable">${enable.slave:false}</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
   <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="masterUrl">http://master_host:8983/solr</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
   <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="pollInterval">00:00:60</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
 </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst>
</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler>

注意事项

  1. 一定要给 enable.master 和 enable.slave 默认设置为 false. 否则启动的时候会失败.
  2. 在启动 Solr 的时候可以通过传递参数去控制当前是作为 Master 还是 Slave, 如:-Denable.master=true 或 -Denable.slave=true
  3. 也可以将参数保存在启动的文件中, 如 solrcore.properties:

Master:

#solrcore.properties in master
enable.master=true
enable.slave=false

Slave:

#solrcore.properties in slave
enable.master=false
enable.slave=true

多核心的同步

一个 Master 可以有多个 core, 就类似一个 MySQL 服务器可以有多个库一样。 
上面的主从配置中已经介绍了 Slave 配置中要写上 Master 的地址,如果是多核心,要写具体的核心名称。也就是说,一个 replication 的 requestHandler 只能同步一个核心。 
另外,上面的配置中是在 Slave 的 solrconfig.xml 中写死了 Master 的 url, 其实这个值也可以写在外部文件中,类似上面的启动/禁用:

<<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler name="/replication" class="solr.ReplicationHandler" >
  <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst name="slave">
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="masterUrl">http://${MASTER_CORE_URL}/${solr.core.name}</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="pollInterval">${POLL_TIME}</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
  </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst>
</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">requestHandler>

变量 ${MASTER_CORE_URL} 和 ${solr.core.name} 在外部的 corename.properties 文件中定义。

查看状态

由于上面配置的是 requestHandler, 所以也可以和其它的 requestHandler 一样,通过 url 去请求,如: 
http://113.216.115.7:8983/solr/replication 
返回结果可能如下:

<<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">response>
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst name="responseHeader">
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">int name="status">0</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">int>
        <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">int name="QTime">0</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">int>
    </<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">lst>
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="status">OK</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
    <<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str name="message">No command</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">str>
</<span class="hljs-title" style="box-sizing: border-box; font-weight: bold;">response>

同步原理

索引同步

  1. 当 Master 执行 commit / optimize 时,ReplicationHandler 得到相关的一些文件。从 Lucene 中读取数据,更新到文件中。
  2. Master 是不知道 Slave 的存在的,而 Slave 会不断去探测 Master(根据 pollInterval 配置的值),带上自己的版本号。当探测到 Master 的版本号要更新时,会触发同步事件。动作的步骤是: 
    • Slave 得到一份要下载的文件列表。包括文件名,大小,更新时间等。
    • Slave 会检查该文件列表,并下载本机没有的文件。如果失败会重试 5 次。
    • 文件下载到 Slave 后存放在临时目录中。所以,在传输过程中如果任意一方崩溃,都不会对它方造成影响。只会中断此次同步,下次同步会照旧进行。
    • 下载完成后,所有的文件被移到 Slave 的索引目录。
    • Slave 会执行一个 commit 命令。新的索引会被加载进去。

文件同步

  1. 只有在 Master 配置文件中 confFiles 配置里的文件才会被同步
  2. 只有 solr 实例的 conf 目录下的文件才会被同步
  3. 文件同步是伴随着索引同步完成的,也就是说文件变更后,不会马上同步到 Slave,而是承受着下次索引的同步。要想马上同步文件,可以人为触发一次索引同步,如:commit 或 optimize 一次 Master。
  4. 索引文件是通过 timestramp 比较的,和索引文件不同 confFiles 里的文件是通过它的 checksum 判断的。
  5. 配置文件会先被保存到临时目录中。如果同步的文件有原文件,原文件会被重全名,保存在原目录中。该目录不会自动清理老文件。
  6. 如果成功下载文件,Slave 会重新加载,而不是执行 commit 命令。
展开阅读全文

没有更多推荐了,返回首页