1. 数据导入方案比较
- 使用dataimportscheduler扩展包
- 使用HttpClient包自己动手发送delta-import请求(post)solr服务
- 使用GenericSolrRequest发送delta-import请求
-
由于dataimportscheduler扩展包的配置文件位于solrHome目录下,而不是solrCore目录下,在solr集群下该如何处理,并没有尝试过,所以略过
-
HttpClient在单机环境下,可以这么使用(单机环境下,host很明确),但是在solr集群环境该如何确定访问地址?
-
SolrJ的GenericSolrRequest发送请求是有个参数SolrClient,在这种情况下我们可以很容易在solr单机和集群下完成切换(只需要构建对应的SolrClient即可)。所以最终确定采用这种方法
2. 配置dataimportHandler
-
拷贝solr安装目录的dist/solr-dataimporthandler-5.5.4.jar到tomcat/webapps/solr/WEB-INF/lib目录下;拷贝一个数据库驱动包到lib目录下(比如mysql就用mysql-mysql-connector-java-5.xx.xx.jar咯)
-
修改solrCore/conf目录下的solrconfig.xml文件,配置DataImportHandler请求处理器。如下,data-config.xml名称任意
<requestHandler name="/dataimport" class="solr.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
- 在solrCore/conf目录下创建data-config.xml文件,该配置文件就第二步定义的,这是一个相对路径,故放置在这里。同时这里我默认你已经在schema.xml文件配置下面文件中用的filed(product_name,product-catalog,product-catalog-name、、、),没有的话,自己去配好
- dataSource:不用说,肯定是连接数据库的了
- entity:一个entity就对应一个索引的document,通常也是一张表,配置多个entity是方便在solr集群环境下,多个collection共用一份配置文件
- pk:数据库主键id,我这里数据库本身主键是pid,但是在查询时我都是用了as重命名为id,特别注意${dih.delta.id}最后的id,要和这里保持一致
- query:初始全量导入到数据库时使用的语句
- deltaImportQuery,deletedPkQuery:两个语句只查了主键,作用是查询出这一段时间(当前时间到上一次更新索引的时间${dataimporter.last_index-time})内数据库数据发生的变动的记录(新增、修改以及被删除的)
- deltaImportQuery:将deltaImportQuery,deletedPkQuery查询出来的记录同步到索引库中(增加索引,更新索引和删除索引)
- 注意增量同步是需要在对数据库进行处理的,比如增加、更新需要记录数据添加的时间和更新时间(我这里使用了update_time字段记录,timestamp类型,默认CURRENT_TIMESTAMP,并勾选根据当前时间戳更新)
- 增量更新中的索引操作,也必须是数据库做软删除(is_deleted字段值为1),solr索引库同步删除该记录后,数据库对应的记录才能删除。
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/taotao" user="root" password="123456"/>
<document name="products_DOC">
<entity name="products" pk="id"
query="SELECT pid AS id,name,catalog,catalog_name,price,description,pricture FROM products WHERE is_deleted=0"
deltaImportQuery="SELECT pid AS id,name,catalog,catalog_name,price,description,pricture FROM products WHERE pid='${dih.delta.id}'"
deltaQuery="SELECT pid AS id FROM products WHERE update_time> '${dataimporter.last_index_time}' and is_deleted=0"
deletedPkQuery="SELECT pid AS id FROM products WHERE is_deleted=1" >
<field name="id" column="id" />
<field name="product_name" column="name" />
<field name="product_catalog" column="catalog" />
<field name="product_catalog_name" column="catalog_name" />
<field name="product_price" column="price" />
<field name="product_description" column="description" />
<field name="product_pricture" column="pricture" />
</entity>
<entity name="products2" pk="id"
query="SELECT pid AS id,name,catalog_name,description,pricture FROM products WHERE is_deleted=0"
deltaImportQuery="SELECT pid AS id,name,catalog_name,description,pricture FROM products WHERE pid='${dih.delta.id}'"
deltaQuery="SELECT pid AS id FROM products WHERE update_time> '${dataimporter.last_index_time}' and is_deleted=0"
deletedPkQuery="SELECT pid AS id FROM products WHERE is_deleted=1" >
<field name="id" column="id" />
<field name="product_name" column="name" />
<field name="product_catalog_name" column="catalog_name" />
<field name="product_description" column="description" />
<field name="product_pricture" column="pricture" />
</entity>
</document>
</dataConfig>
- 上传配置到solr集群(单机版跳过这一步)
//windows下命令如下
java -classpath E:\S-soft\tomcat8\apache-tomcat-8.0.33-solrCloud01\apache-tomcat-8.0.33\webapps\solr\WEB-INF\lib/* org.apache.solr.cloud.ZkCLI -zkhost 192.168.4.41:2181,192.168.4.41:2281,192.168.4.41:2381 -cmd upconfig -confdir E:\S-soft\Solr5_resp\solrHome\solr_01\_BlankCore\conf -confname mySolrCloudCon
//linux下命令如下(注意在-classpath下稍微有点区别):
java -classpath .:/opt/tomcat/apache-tomcat-8.0.23/webapps/solr/WEB-INF/lib/* org.apache.solr.cloud.ZkCLI -zkhost 192.168.102.102:2181,192.168.102.103:2181,192.168.102.104:2181 -cmd upconfig -confdir /var/solrData/solr/SolrHome/collection1/conf -confname mySolrCloudCon
- 重启tomcat:能看到如下页面就算成功了,可以看到我们配置的data-config.xml的内容。可以在这里进行一些尝试,比如全量导入后(点击Execute按钮后,记得Refresh Status按钮),手动更新数据内容,删除内容(将is_deleted改成1),然后使用增量导入试试。
- Command:有两个选项full-import和delta-import,分别表示全量导入和增量导入
- Clean:表示是否清空再导入,全量导入可以勾选这个选项,增量千万不勾了,
- Commit:是否提交
- Entity:我们在配置文件中配置了products,products2两个
3. 使用solrJ完成增量导入
- GenericSolrRequest需要在process时需要一个SolrClient作为参数,所以我们就很容在单机版和集群版中完成切换
- 参数:仍旧是上面提到的几个参数command、entity、clean、commit等几个参数
public static void main(String[] args) {
System.err.println("增量更新开始---->");
bySolrRequest();
System.err.println("增量更新结束<-----");
}
public static void bySolrRequest() {
//zkHost列表
// final String ZK_HOST = "192.168.4.41:2181,192.168.4.41:2281,192.168.4.41:2381";
// CloudSolrClient cloudSolrClient = new CloudSolrClient(ZK_HOST);
// cloudSolrClient.setDefaultCollection("shardCollection01");
final String SOLR_HOST = "http://127.0.0.1:8080/solr/shardCollection01";
HttpSolrClient httpSolrClient = new HttpSolrClient(SOLR_HOST);
Map<String,String> params = new HashMap<String, String>();
params.put("command", "delta-import");
params.put("entity", "products2");
params.put("clean", "false");
params.put("commit", "true");
MapSolrParams solrParams = new MapSolrParams(params);
GenericSolrRequest solrRequest = new GenericSolrRequest(SolrRequest.METHOD.POST,"/dataimport",solrParams);
try {
// SolrClient solrClient = cloudSolrClient;
SolrClient solrClient = httpSolrClient;
SimpleSolrResponse solrResponse = solrRequest.process(solrClient);
System.out.println(solrResponse);
NamedList<Object> response = solrResponse.getResponse();
Object responseHeader = response.get("responseHeader");
Object initArgs = response.get("initArgs");
Object command = response.get("command");
Object status = response.get("status");
Object statusMessages = response.get("statusMessages");
System.out.println("responseHeader:"+responseHeader);
System.out.println("initArgs:"+initArgs);
System.out.println("command:"+command);
System.out.println("status:"+status);
System.out.println("statusMessages:"+statusMessages);
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}