出家如初,成佛有余

Solr与Mysql集成指南

Posted in 技术相关 by chuanliang on 2011/09/24

    在《企业级搜索引擎Solr使用入门指南》《企业级搜索引擎Solr交流》中对Solr的使用做了简单介绍。在数据库驱动的应用中,当时采用的方案是应用层面有数据的增删改操作时候,由应用通过调用solr的xml接口来完成solr索引的增删改操作,对批量操作采用提交csv报文的方案。但此种方案不足之处在于:需要应用在增删改业务逻辑中来调用solr接口,业务逻辑与搜索引擎建索引的逻辑混在一起,在需要对搜索引擎的策略进行调整,可能需要对每一次业务应用涉及搜索的逻辑进行修改。在处理批量导入、增量操作时候也很不方便。

    从Solr 1.3开始,Solr提供DataImportHandler工具完成对mysql数据库数据的操作。因此极大方便了Solr与Mysql的集成,因此可以借助DataImportHandler来完成Solr与Mysql的集成,基本思路如下:

      1、使用mysql的触发器trigger获取需要对应数据库表的增删改操作

      2、触发器通过mysql的用户自定义函数user-defined function (UDF) 包mysql-udf-http 调用Solr DataImportHandler对应的命令

      3、由Solr DataImportHandler完成增删改数据的索引操作。

    此种方案的优点在于将索引逻辑完全与应用的业务逻辑处理完全隔离,尤其是对批量导入、增量导入有其优势。

    下面简单介绍Solr与Mysql集成的方案。关于solr的配置及使用说明可参考《企业级搜索引擎Solr使用入门指南》《企业级搜索引擎Solr交流》 ,这里主要说明与DataImportHandler相关的安装使用。

    测试环境说明:  

   操作系统:CentOS 5

   数据库:Mysql 5 ,直接使用了rpm安装的,mysql的lib库安装在/usr/lib/mysql

  Tomcat 6:tomcat安装在/opt/tomcat

  JDK 6

一、Solr安装配置

1)、Solr的安装

wget http://www.apache.org/dist//lucene/solr/3.4.0/apache-solr-3.4.0.tgz

tar zxvf apache-solr-3.4.0.tgz

cd apache-solr-3.4.0

cp -r example/webapps/solr.war /opt/tomcat/webapps/

cp -r example/solr/ /opt/solr-tomcat

cp -r dist/  /opt/solr-tomcat/

注dist目录下中有使用dataimport所必须的jar包apache-solr-dataimporthandler

将mysql的JDBC Driver mysql-connector-java-5.1.17-bin.jar拷贝到/opt/solr-tomcat/lib/下

 设定solr.solr.home

  在当前用户的环境变量中(.bash_profile)或在/opt/tomcat/catalina.sh中添加如下环境变量

export JAVA_OPTS="$JAVA_OPTS -Dsolr.solr.home=/opt/solr-tomcat/solr"

  mkdir –p /opt/tomcat/conf/Catalina/localhost

    vi  /opt/tomcat/conf/Catalina/localhost/solr.xml ,内容如下:

      <Context docBase="/opt/tomcat/webapps/solr.war" debug="0" crossContext="true" >

                 <Environment name="solr/home" type="java.lang.String" value="/opt/solr-tomcat" override="true" />

    </Context>

注:

   为了避免在Solr管理界面测试时候出现中文乱码问题,需要做如下设置:

   /opt/tomcat/conf/server.xml 中设定URIEncoding: 

          <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"  URIEncoding="UTF-8" />

   /opt/tomcat/webapps/solr/WEB-INF/web.xml 设定过滤器

<filter>
    <filter-name>Set Character Encoding</filter-name>
    <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>ignore</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>Set Character Encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在xml请求数据中增加编码说明:

<?xml version=’1.0′ encoding=’utf-8′?>

<add>

<doc>

  <field name="id">123</field>

  <field name="name">Solr企业级搜索</field>

  <field name="manu">Apache Software Foundation</field>

  <field name="liangchuan">liangchuan’s solr "hello,world" test</field>

  <field name="url">http://www.google.com</field&gt;

</doc>

</add>

3)、配置solr

cd /opt/solr-tomcat/

vi solrconfig.xml ,增加如下内容

<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
  <lst name="defaults">
    <str name="config">/opt/solr-tomcat/conf/data-config.xml</str>
    <lst name="datasource">
       <str name="driver">com.mysql.jdbc.Driver</str>
       <str name="url">

         jdbc:mysql://localhost/test?useUnicode=true&amp;characterEncoding=utf-8

       </str>
       <str name="user">user</str>
       <str name="password">password</str>
    </lst>
  </lst>
</requestHandler>

<lib dir="/opt/solr-tomcat/lib" />
<lib dir="/opt/solr-tomcat/dist" />

这里的data-config.xml就是DataImportHandler的配置文件

vi  /opt/solr-tomcat/conf/data-config.xml,内容如下:

<dataConfig>
  <document name="documents1">
        <entity name="documents"

          query="select id,title,content,date_added from documents"
          deltaImportQuery="select  id,title,content,date_added  from documents where ID=’${dataimporter.delta.id}’"
          deltaQuery="select id  from documents where date_added &gt; ‘${dataimporter.last_index_time}’"
        >
            <field column="id" name="id" />
            <field column="title" name="title" />
            <field column="content" name="content" />
            <field column="date_added" name="date_added" />
        </entity>
    </document>
</dataConfig>

关于DataImportHandler的详细使用请参考:http://wiki.apache.org/solr/DataImportHandler

这里就常用的用法简单说明:

query语句是用于批量导入(Full Import)中获取符合条件的全部数据的SQL。

deltaQuery语句是用于增量导入(Delta Import)中获取符合增量导入标准的数据的主键的SQL,供deltaImportQuery查询使用。

deltaImportQuery语句增量导入(Delta Import)中获取需要增量索引数据(document)的字段(field)

DataImportHandler的常见命令:

    批量导入(full-import):

        http://<host&gt;:<port>/solr/dataimport?command=full-import&commit=y
    增量导入(delta-import):

        http://<host&gt;:<port>/solr/dataimport?command=delta-import&commit=y
    导入状态查询(status):

        http://<host&gt;:<port>/solr/dataimport
    重新装载配置文件(reload-config):

        http://<host&gt;:<port>/solr/dataimport?command=reload-config
    终止导入(abort):

        http://<host&gt;:<port>/solr/dataimport?command=abort

Solr执行增量导入的大致原理

    1、Solr 读取conf/dataimport.properties 文件,得到solr最后一次执行索引操作的时间戳last_index_time,以及单个实体最后一次执行索引的时间戳:entity_name.last_index_time

    2、Solr对指定的实体使用deltaImportQuery SQL查询得到insert或update时间戳大于${dataimporter.last_index_time}需要增量索引的字段,然后调用deltaQuery对符合条件需要执行增量索引的文档的字段进行索引,并更新dataimport.properties 的时间戳

 

数据库的测试表结构如下:

DROP TABLE IF EXISTS `documents`;
CREATE TABLE `documents` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `date_added` datetime NOT NULL,
  `title` varchar(255) NOT NULL,
  `content` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

4)、测试Solr配置

  在数据库中documents表中插入几条数据,然后

执行批量导入操作:

:/solr/dataimport?command=full-import&commit=y">:/solr/dataimport?command=full-import&commit=y">:/solr/dataimport?command=full-import&commit=y">:/solr/dataimport?command=full-import&commit=y">:/solr/dataimport?command=full-import&commit=y">http://<host>:<port>/solr/dataimport?command=full-import&commit=y

执行增量导入操作:
:/solr/dataimport?command=delta-import&commit=y">:/solr/dataimport?command=delta-import&commit=y">:/solr/dataimport?command=delta-import&commit=y">:/solr/dataimport?command=delta-import&commit=y">:/solr/dataimport?command=delta-import&commit=y">http://<host>:<port>/solr/dataimport?command=delta-import&commit=y

:/solr/admin">:/solr/admin">:/solr/admin">:/solr/admin">:/solr/admin">http://<host>:<port>/solr/admin执行查询操作,测试配置是否正确

二、mysql-udf-http 安装配置

wget http://mysql-udf-http.googlecode.com/files/mysql-udf-http-1.0.tar.gz

tar zxvf mysql-udf-http-1.0.tar.gz

cd mysql-udf-http-1.0/

./configure –prefix=/usr –with-mysql=/usr/bin/mysql_config

make && make install

echo "/usr/lib/mysql/plugin" >> /etc/ld.so.conf.d/mysql-i386.conf

/sbin/ldconfig

/sbin/ldconfig -v|grep mysql

  如果没有类似如下的输出

   /usr/lib/mysql/plugin:
        mysql-udf-http.so.0 -> mysql-udf-http.so
   则建立mysql-udf-http.so 的软连接(当然也可以通过修改编译Makefile脚本)

ln -s /usr/lib/mysql/plugin/mysql-udf-http.so /usr/lib/mysql/plugin/libmysql-udf-http.so

  建立软连接后再执ldconfig 命令,使用/sbin/ldconfig -v|grep mysql是否有如下内容:

/usr/lib/mysql/plugin:
        mysql-udf-http.so.0 -> libmysql-udf-http.so
原因是mysql-udf-http的Makefile中指定了动态链接库的SONAME为mysql-udf-http.so.0 ,而ldconfig缺省只处理以lib开头的动态链接库(例如libmysqlclient.so.15),因此执行ldconfig命令时候忽略了mysql-udf-http.so 。

创建mysql的用户自定义函数:

mysql >

create function http_get returns string soname ‘libmysql-udf-http.so’;
create function http_post returns string soname ‘libmysql-udf-http.so’;
create function http_put returns string soname ‘libmysql-udf-http.so’;
create function http_delete returns string soname ‘libmysql-udf-http.so’;

三、创建调用mysql-udf-http的触发器

/* INSERT插入操作的触发器 */
DELIMITER |
DROP TRIGGER IF EXISTS documents_insert;
CREATE TRIGGER documents_insert
AFTER INSERT ON documents
FOR EACH ROW BEGIN
     SET @result = (SELECT http_get(‘http://www.yeeach.com/solr/dataimport?command=delta-import&commit=yes’));
END |
DELIMITER ;

/* UPDATE更新操作的触发器 */
DELIMITER |
DROP TRIGGER IF EXISTS documents_update;
CREATE TRIGGER documents_update
AFTER UPDATE ON documents
FOR EACH ROW BEGIN
     SET @result = (SELECT http_get("http://www.yeeach.com/solr/dataimport?command=delta-import&commit=yes"));
END |
DELIMITER ;

/* DELETE删除操作的触发器 */
DELIMITER |
DROP TRIGGER IF EXISTS documents_delete;
CREATE TRIGGER documents_delete
AFTER DELETE ON documents
FOR EACH ROW BEGIN
        SET @result = (SELECT http_get(CONCAT(‘http://www.yeeach.com/solr/update/?stream.body=<delete><id>’,OLD.id,'</id></delete>&stream.contentType=text/xml;charset=utf-8&commit=true’)));
END |
DELIMITER ;

四、测试

  在数据库执行增删改操作,然后在Solr的管理界面执行查询操作,测试触发器调用mysql-udf-http是否正常。

五、参考资料

DataImportHandler文档:http://wiki.apache.org/solr/DataImportHandler

Mysql UDF的大本营:http://www.mysqludf.org/

mysql-udf-http:http://code.google.com/p/mysql-udf-http/

 

 

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: