solrcloud

本文收集自网络,部分内容个人编写。收集了一下网页的内容:

http://blog.csdn.net/dingzfang/article/details/42804489

   

什么是SolrCloud

SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud。当一个系统的索引数据量少的时候是不需要使用SolrCloud的,当索引量很大,搜索请求并发很高,这时需要使用SolrCloud来满足这些需求。

SolrCloud是基于Solr和Zookeeper的分布式搜索方案,它的主要思想是使用Zookeeper作为集群的配置信息中心。

SolrCloud有几个特色功能:

  1. 使用ZK进行集中配置。启动时可以指定把Solr的相关配置文件上传Zookeeper,多机器共用。这些ZK中的配置不会再拿到本地缓存,Solr直接读取ZK中的配置信息。配置文件的变动,所有机器都可以感知到。

    另外,Solr的一些任务也是通过ZK作为媒介发布的。目的是为了容错。接收到任务,但在执行任务时崩溃的机器,在重启后,或者集群选出候选者时,可以再次执行这个未完成的任务。

  2. SolrCloud对索引分片,并对每个分片创建多个Replication。每个Replication都可以对外提供服务。一个Replication挂掉不会影响索引服务。

    更强大的是,它还能自动的在其它机器上帮你把失败机器上的索引Replication重建并投入使用。

  3. 立即推送式的replication(也支持慢推送)。可以在秒内检索到新加入索引。

  4. SolrCloud索引的多个Replication可以分布在多台机器上,均衡查询压力。如果查询压力大,可以通过扩展机器,增加Replication来减缓。

  5. 发送文档到任何节点,它都会转发到正确节点。

  6. 事务日志确保更新无丢失,即使文档没有索引到磁盘。

其它值得一提的功能有:

  1. 索引的大小通常在G和几十G,上百G的很少,这样的功能或许很难实用。但是,如果你有上亿数据来建索引的话,也是可以考虑一下的。我觉得这个功能最大的好处或许就是和下面这个"通过MR批量创建索引"联合实用。

  2. 有了这个功能,你还担心创建索引慢吗?

  3. 通常你能想到的管理功能,都可以通过此API方式调用。这样写一些维护和管理脚本就方便多了。

  4. 主要信息一目了然;可以清晰的以图形化方式看到SolrCloud的部署分布;当然还有不可或缺的Debug功能。

zookeeper是个什么玩意?

顾名思义zookeeper就是动物园管理员,他是用来管hadoop(大象)、Hive(蜜蜂)、pig(小猪)的管理员, Apache Hbase和 Apache Solr 的分布式集群都用到了zookeeper;Zookeeper:是一个分布式的、开源的程序协调服务,是hadoop项目下的一个子项目。

SolrCloud架构

核心概念

 Collection:在SolrCloud集群中逻辑意义上的完整的索引它常常被划分为一个或多个Shard,它们使用相同的Config Set。如果Shard数超过一个,它就是分布式索引,SolrCloud让你通过Collection名称引用它,而不需要关心分布式检索时需要使用的和Shard相关参数。

   Config Set: Solr Core提供服务必须的一组配置文件。每个config set有一个名字。最小需要包括solrconfig.xml (SolrConfigXml)和schema.xml (SchemaXml),除此之外,依据这两个文件的配置内容,可能还需要包含其它文件。它存储在Zookeeper中。Config sets可以重新上传或者使用upconfig命令更新,使用Solr的启动参数bootstrap_confdir指定可以初始化或更新它。

     Core: 也就是Solr Core,一个Solr中包含一个或者多个SolrCore,每个Solr Core可以独立提供索引和查询功能,每个SolrCore对应一个索引或者Collection的Shard,Solr Core的提出是为了增加管理灵活性和共用资源。在SolrCloud中有个不同点是它使用的配置是在Zookeeper中的,传统的Solr core的配置文件是在磁盘上的配置目录中。

     Leader: 赢得选举的Shard replicas。每个Shard有多个Replicas,这几个Replicas需要选举来确定一个Leader。选举可以发生在任何时间,但是通常他们仅在某个Solr实例发生故障时才会触发。当索引documents时,SolrCloud会传递它们到此Shard对应的leader,leader再分发它们到全部Shard的replicas。

    Replica: Shard的一个拷贝。每个Replica存在于Solr的一个Core中。一个命名为"test"的collection以numShards=1创建,并且指定replicationFactor设置为2,这会产生2个replicas,也就是对应会有2个Core,每个在不同的机器或者Solr实例。一个会被命名为test_shard1_replica1,另一个命名为test_shard1_replica2。它们中的一个会被选举为Leader。

    Shard: Collection的逻辑分片。每个Shard被化成一个或者多个replicas,通过选举确定哪个是Leader。

    Zookeeper: Zookeeper提供分布式锁功能,对SolrCloud是必须的。它处理Leader选举。Solr可以以内嵌的Zookeeper运行,但是建议用独立的,并且最好有3个以上的主机。

   

总体架构:

内部结构

Shard架构

索引的创建

分布式索引的过程如下:

1.用户可以把创建文档索引的请求提交给任一个Replica或Leader

2.如果它不是Leader,它会把请求转交给和自己同Shard的Leader

3.Leader把文档路由给本Shard的每个Replica,各自做索引

4.如果文档基于路由规则并不属于本Shard,Leader会把它转交给该文档对应Shard的Leader

5.对应的Leader会把文档路由给本Shard的每个Replica,各自做索引

搜索

分布式搜索过程如下:

1.用户的一个查询请求,可以发送到含有该Collection的任意机器,Solr的内部处理逻辑会转到一个Replica

2.此Replica会基于查询索引的方式,启动分布式查询,基于索引的Shard个数,把查询转换为多个子查询,并把每个子查询定位到对应Shard的任意一个Replica

3.每个子查询返回查询结果

4.最初的Replica合并每个子查询的查询结果,并把最终结果返回给用户

自动shard

索引的自动shard-split过程如下:

在一个Shard中的索引文档达到阀值时,或者接收到用户的shard-split的API命令,就可以启动shard分裂过程。此时,旧的shard仍然提供服务,旧shard上的现有索引文档,会再次提取并按照路由规则,转到新的shard上再次进行索引。同时,对于新加入的索引文档,会按照如下步骤进行:

1.用户可以把创建文档索引的请求提交给任一个Replica或Leader

2.如果它不是Leader,它会把请求转交给和自己同Shard的Leader

3.Leader将索引文档路由给本Shard的每个Replica,各自做索引

4,6.在一个Shard中的索引文档达到阀值时,或者接收到用户的shard-split的API命令,就可以启动shard分裂过程。此时旧的shard的Leader会将索引文档路由给新的shard的Leader

5,7.新的shard的Leader会将索引文档路由给本Shard的每个Replica,各自做索引

在旧的索引文档重新索引完成后,系统会把分发文档的路由切换到对应的新的Leader上,旧Shard关闭

 

下面搭建一个如下图的集群:

 

 环境的安装

第一步:安装CentOS6.4。

第二步:安装java虚拟机。

第三步:安装zookeeper。

Zookeeper保证是奇数节点。最少三个节点。伪分布式的集群环境,在同一个linux下运行集群环境。

  1. tar -zxf zookeeper-3.4.6.tar.gz

  2. mkdir /usr/local/solrcloud

    1. 在conf文件夹下有一个zoo_sample.cfg文件,把复制一份命名为zoo.cfg

    initLimit=10

    # The number of ticks that can pass between

    # sending a request and getting an acknowledgement

    syncLimit=5

    # the directory where the snapshot is stored.

    # do not use /tmp for storage, /tmp here is just

    # example sakes.

    dataDir=/usr/local/solrcloud/zookeeper1/data

    # the port at which the clients will connect

    clientPort=2181

    # the maximum number of client connections.

    # increase this if you need to handle more clients

    #maxClientCnxns=60

    #

    # Be sure to read the maintenance section of the

    # administrator guide before turning on autopurge.

    #

    # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance

    #

    # The number of snapshots to retain in dataDir

    #autopurge.snapRetainCount=3

    # Purge task interval in hours

    # Set to "0" to disable auto purge feature

    #autopurge.purgeInterval=1

    server.1=192.168.25.150:2881:3881

    server.2=192.168.25.150:2882:3882

    server.3=192.168.25.150:2883:3883

    [root@bogon solrcloud]# cd zookeeper2

    [root@bogon zookeeper2]# mkdir data

    [root@bogon zookeeper2]# echo 2 >> data/myid

    [root@bogon zookeeper2]# cd conf

    [root@bogon conf]# cp zoo_sample.cfg zoo.cfg

    [root@bogon conf]# vim zoo.cfg

    Zookeeper2:

    # The number of milliseconds of each tick

    tickTime=2000

    # The number of ticks that the initial

    # synchronization phase can take

    initLimit=10

    # The number of ticks that can pass between

    # sending a request and getting an acknowledgement

    syncLimit=5

    # the directory where the snapshot is stored.

    # do not use /tmp for storage, /tmp here is just

    # example sakes.

    dataDir=/usr/local/solrcloud/zookeeper2/data

    # the port at which the clients will connect

    clientPort=2182

    # the maximum number of client connections.

    # increase this if you need to handle more clients

    #maxClientCnxns=60

    #

    # Be sure to read the maintenance section of the

    # administrator guide before turning on autopurge.

    #

    # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance

    #

    # The number of snapshots to retain in dataDir

    #autopurge.snapRetainCount=3

    # Purge task interval in hours

    # Set to "0" to disable auto purge feature

    #autopurge.purgeInterval=1

    server.1=192.168.25.150:2881:3881

    server.2=192.168.25.150:2882:3882

    server.3=192.168.25.150:2883:3883

    1. /usr/local/solrcloud/zookeeper1/bin/zkServer.sh start

      /usr/local/solrcloud/zookeeper2/bin/zkServer.sh start

      /usr/local/solrcloud/zookeeper3/bin/zkServer.sh start

  3. /usr/local/solrcloud/zookeeper1/bin/zkServer.sh status

    第四步:安装tomcat

  4. 第五步:配置solr服务

  5. 修改solr工程的web.xml文件。

    第六步:集群环境搭建

    执行下边的命令将/home/solr/conf下的配置文件上传到zookeeper(此命令为单条命令,虽然很长o(╯□╰)o)。此命令在solr-4.10.3/example/scripts/cloud-scripts/目录下:

    ./zkcli.sh -zkhost 192.168.25.150:2181,192.168.25.150:2182,192.168.25.150:2183 -cmd upconfig -confdir /usr/local/solrcloud/solrhome1/collection1/conf -confname myconf

    修改每一台solr的tomcat 的 bin目录下catalina.sh文件中加入DzkHost指定zookeeper服务器地址

    JAVA_OPTS="-DzkHost=192.168.25.150:2181,192.168.25.150:2182,192.168.25.150:2183"

    (可以使用vim的查找功能查找到JAVA_OPTS的定义的位置,然后添加)

    集群管理

    创建有两片的collection

    http://192.168.25.150:8080/solr/admin/collections?action=CREATE&name=collection2&numShards=2&replicationFactor=2

    删除collection

    http://192.168.25.150:8080/solr/admin/collections?action=DELETE&name=collection1

    配置dataimport插件

    1. 需要在每个节点都配置一下,把dataimport插件依赖的jar包添加到每个节点的collection文件夹的lib下。
    2. 修改solrconfig.xml把solrconfig.xml上传至zookeeper。

    使用单机版配置,只需要把单机版的collection1/conf目录上传至zookeeper就可以了。

    ./zkcli.sh -zkhost 192.168.25.150:2181,192.168.25.150:2182,192.168.25.150:2183 -cmd upconfig -confdir /root/solrhome/collection1/conf -confname myconf

    1. 重启tomcat集群。

     

    集群环境下SolrJ的使用

    步骤:

    第一步:创建一java工程

    第二步:导入jar包。包括solrJ的jar包solrJ依赖的jar包。Example/lib/ext下的日志相关的jar包。

    第三步:集群环境使用CloudSolrServer创建一连接。指定zookeeper的地址列表。还需要指定要连接的collection。

    第四步:创建一个查询。

    第五步:执行查询。跟单机版一样的。

    代码实现

    @Test

        public void testCloud() throws Exception {

            //创建一个连接

            String zkHost = "192.168.25.150:2181,192.168.25.150:2182,192.168.25.150:2183";

            //参数:zookeeper服务器的地址列表。

            CloudSolrServer server = new CloudSolrServer(zkHost);

            //指定默认连接的collection

            server.setDefaultCollection("collection2");

            //创建一查询对象

            SolrQuery solrQuery = new SolrQuery();

            solrQuery.setQuery("*:*");

            //执行查询

            QueryResponse queryResponse = server.query(solrQuery);

            SolrDocumentList solrDocumentList = queryResponse.getResults();

            System.out.println("查询结果总数量:" + solrDocumentList.getNumFound());

            for (SolrDocument solrDocument : solrDocumentList) {

                System.out.println(solrDocument.get("id"));

                System.out.println(solrDocument.get("product_name"));

                System.out.println(solrDocument.get("product_price"));

                System.out.println(solrDocument.get("product_picture"));

            }

        }

     

     

       

       

      

posted on 2017-08-30 00:16  张小贱1987  阅读(287)  评论(0编辑  收藏  举报

导航