Solr集群架构概述及delta

Stella981
• 阅读 805

背景

由于项目原因,重新熟悉了下Solr,版本为3.6,搭建了主从Solr服务,并使用DIH从RDBMS数据源增量更新索引。

其实也没什么技术含量,就是简单做个总结,分别从部署架构和增量更新两个方面说明下。

Solr Replication

solr的主从其实是他的replication集群,从本质上说是通过ReplicationHandler来实现的,除了solr server之间可以互相同步之外,每个solr实例内部的core之间也是可以实现同步的,而能自身同步自身的实例称为Repeater,它的存在是为了分担master的同步开销,即由它来同步master里需要向外同步的core,然后所有的slave都从Repeater处同步相应的core。

Solr集群架构概述及delta

具体配置方面,master的solrconfig.xml里的requestHandler配置为:

[html] view plaincopySolr集群架构概述及deltaSolr集群架构概述及delta

  1. <requestHandler name="/replication" class="solr.ReplicationHandler">

  2. <lst name="master">

  3. <str name="replicateAfter">startup</str>

  4. <str name="replicateAfter">commit</str>

  5. <str name="backupAfter">optimize</str>

  6. <str name="confFiles">schema.xml,stopword.dic,db-data-config.xml,dataimport.properties</str>

  7. <str name="commitReserveDuration">00:01:00</str>

  8. </lst>

  9. </requestHandler>

在confFiles里可以指定在同步过程中,slave需要一并同步过去的文件。slave端 solrconfig.xml里的配置为:

[html] view plaincopySolr集群架构概述及deltaSolr集群架构概述及delta

  1. <requestHandler name="/replication" class="solr.ReplicationHandler">

  2. <lst name="slave">

  3. <str name="masterUrl">http://yf-rd-crm-cdc-db06.yf01.baidu.com:8888/solr/core0/replication</str>

  4. <str name="pollInterval">00:00:20</str>

  5. <str name="compression">internal</str>

  6. <str name="httpConnTimeout">5000</str>

  7. <str name="httpReadTimeout">10000</str>

  8. </lst>

  9. </requestHandler>

其中pollInterval是发出同步请求的间隔时间,上述配置为每20s会去sync一次。后面的http参数都是默认值。对slave和master来说,主要的配置不同就在这个handler里,其他部分可以一致。我的solr主从比较简单,大致如下。

Solr集群架构概述及delta

如果对solr的搜索还有分片和负载均衡的要求,可以参考下solr4.0之后支持的SolrCloud,适合 high scale, fault tolerant, distributed indexing and search capabilities。我没有选择SolrCloud,主要原因是数据量也不是很大,不需要分片。本来想参考SolrCloud,看能不能为请求的负载均衡提供些什么优势,后来还是放弃了,负载这块在solrj的搜索服务里简单做了下轮训。网上看到也有人用Nginx为多个Tomcat容器做负载均衡,不过这个出发点和架构上的层次又有些不一样。

Solr DataImportHandler

DataImportHandler可以为solr的索引配置数据源,我的数据源是mysql,基本配置可以参考SolrDoc里的内容。不重复。

主要的坑在需要在web.xml里添加下面这个配置

[html] view plaincopySolr集群架构概述及deltaSolr集群架构概述及delta

  1. <listener>

  2. <listener-class>org.apache.solr.handler.dataimport.scheduler.ApplicationListener</listener-class>

  3. </listener>

但是这个类并不存在于solr的主要几个包里,需要额外导入,包下载链接在这里。需要在webapps/solr.war下的WEB-INF/lib里添加这个包,还要添加下dist下的两个dataimporthandler有关的两个jar。此外把上面的listener配置添加到WEB-INF/web.xml内。特别注意的是,需要jdk7才能正常启动,否则会报错。

具体DIH相关的配置再详细列一下,首先在solrconfig.xml里配置Handler:

[html] view plaincopySolr集群架构概述及deltaSolr集群架构概述及delta

  1. <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">

  2. <lst name="defaults">

  3. <str name="config">db-data-config.xml</str>

  4. </lst>

  5. </requestHandler>

具体db-data-config.xml里是sql逻辑和映射field,放在core/conf内,

[html] view plaincopySolr集群架构概述及deltaSolr集群架构概述及delta

  1. <dataConfig>

  2. <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver"

  3. url="jdbc:mysql://ip:port/db_name"

  4. user="root" password="root" />

  5. <document name="tb_core">

  6. <entity name="tb_core_table" pk="table_id"

  7. query="select table_id, code, name, description, freq_id, bytes, first_date, owner, secret_level, charset_id, field_term,

  8. line_term, null_format, subj_id, gmt_modify from tb_core_table"

  9. deltaQuery="select table_id, code, name, description, freq_id, bytes, first_date, owner, secret_level, charset_id, field_term,

  10. line_term, null_format, subj_id, gmt_modify from tb_core_table where gmt_modify > '${dataimporter.last_index_time}'">

  11. <field column="table_id" name="table_id" />

  12. <field column="code" name="code" />

  13. <field column="name" name="name" />

  14. <field column="description" name="description" />

  15. <field column="description" name="subject_path" />

  16. <field column="freq_id" name="freq_id" />

  17. <field column="bytes" name="bytes" />

  18. <field column="first_date" name="first_date" />

  19. <field column="owner" name="owner" />

  20. <field column="secret_level" name="secret_level" />

  21. <field column="charset_id" name="charset_id" />

  22. <field column="field_term" name="field_term" />

  23. <field column="line_term" name="line_term" />

  24. <field column="null_format" name="null_format" />

  25. <field column="subj_id" name="subj_id" />

  26. <field column="gmt_modify" name="entity_modify" />

  27. <entity name="tb_core_column" pk="col_id"

  28. query="select col_id, table_id, code, name, description, gmt_modify from tb_core_column where table_id='${tb_core_table.table_id}'"

  29. deltaQuery="select col_id, table_id, code, name, description, gmt_modify from tb_core_column where gmt_modify > '${dataimporter.last_index_time}'"

  30. parentDeltaQuery="select table_id, code, name, description, freq_id, bytes, first_date, owner, secret_level, charset_id, field_term,

  31. line_term, null_format, subj_id, gmt_modify from tb_core_table where table_id = ${tb_core_column.table_id}">

  32. <field column="col_id" name="column_id" />

  33. <field column="code" name="column_code" />

  34. <field column="name" name="column_name" />

  35. <field column="description" name="column_description" />

  36. <field column="gmt_modify" name="column_modify" />

  37. </entity>

  38. </entity>

  39. </document>

  40. </dataConfig>

上面的逻辑里,table和column是一对多的关系,而两个table内都有最近更新时间字段(gmt_modify),任何一方的更新都要触发整个索引的增量更新,所以这是一个嵌套的例子。在SolrDoc里也有类似的嵌套写法,相对而言属于delta-import稍微高级些的写法。大家可以参考下。

[html] view plaincopySolr集群架构概述及deltaSolr集群架构概述及delta

  1. <dataConfig>

  2. <dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:/temp/example/ex" user="sa" />

  3. <document>

  4. <entity name="item" pk="ID" query="select * from item"

  5. deltaImportQuery="select * from item where ID=='${dih.delta.id}'"

  6. deltaQuery="select id from item where last_modified > '${dih.last_index_time}'">

  7. <entity name="feature" pk="ITEM_ID"

  8. query="select DESCRIPTION as features from FEATURE where ITEM_ID='${item.ID}'"

  9. deltaQuery="select ITEM_ID from FEATURE where last_modified > '${dih.last_index_time}'"

  10. parentDeltaQuery="select ID from item where ID=${feature.ITEM_ID}"/>

  11. <entity name="item_category" pk="ITEM_ID, CATEGORY_ID"

  12. query="select CATEGORY_ID from item_category where ITEM_ID='${item.ID}'"

  13. deltaQuery="select ITEM_ID, CATEGORY_ID from item_category where last_modified > '${dih.last_index_time}'"

  14. parentDeltaQuery="select ID from item where ID=${item_category.ITEM_ID}">

  15. <entity name="category" pk="ID"

  16. query="select DESCRIPTION as cat from category where ID = '${item_category.CATEGORY_ID}'"

  17. deltaQuery="select ID from category where last_modified > '${dih.last_index_time}'"

  18. parentDeltaQuery="select ITEM_ID, CATEGORY_ID from item_category where CATEGORY_ID=${category.ID}"/>

  19. </entity>

  20. </entity>

  21. </document>

  22. </dataConfig>

最重要的是,在solr_home/conf内需要一个负责调度的文件:dataimport.properties(不同于core/conf下的dataimport.properties,那个dataimport.properties会自动生成,记录的是最近一次更新的时间)

[html] view plaincopySolr集群架构概述及deltaSolr集群架构概述及delta

  1. #################################################

  2. dataimport scheduler properties         #

  3. #################################################

  4. 是否同步功能

  5. 1 - 开启 ; 否则不开启

  6. syncEnabled=1

  7. 需要同步的solr core

  8. syncCores=core0

  9. solr server名称或ip地址

  10. 默认为localhost

  11. server=localhost

  12. solr server端口

  13. 默认80

  14. port=8888

  15. webapp name

  16. webapp=solr

  17. application context

  18. webapp=metadata-search

  19. 同步URL参数

  20. params=/dataimport?command=delta-import&clean=false&commit=true

  21. 调度区间

  22. 默认30分钟

  23. interval=1

这部分就需要开头讲的

[html] view plaincopySolr集群架构概述及deltaSolr集群架构概述及delta

  1. org.apache.solr.handler.dataimport.scheduler.ApplicationListener

的配置,否则启动后,之前的xml是不生效的。

Solr Server服务架构

结合Solr更新、主从和内部的一些主要模块,画了一个服务架构图如下。

Solr集群架构概述及delta

(全文完)

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这