elasticsearch源码分析之索引操作(九)

上节介绍了es的node启动如何建立集群服务的过程,这节在其基础之上介绍es索引的基本操作功能(create、exist、delete),用来进一步细化es集群是如果工作的。
客户端部分的操作就不予介绍了,详细可以参照elasticsearch源码分析之客户端(三)。这里只介绍服务端处理工作。

createIndex

1、创建索引,客户端提交索引的基本信息(索引名称、分区数、副本数),封装成CreateIndexRequest类,提交给服务端。
2、服务端接收到请求,跟actionname判断获得具体响应action,具体参照elasticsearch源码分析之服务端(四)。此处为执行TransportCreateIndexAction的masterOperation,该类继承TransportMasterNodeAction。

TransportMasterNodeAction类,master节点执行类,是所有在master节点执行的响应类的父类。主要完成master节点判断请求和处理失败重试功能。继承了HandledTransportAction类,实现了doExecute方法。新启动一个异步单线程(异步响应,不占用接收request线程),如果本节点是master节点,则启动执行masterOperation;如果不是,则发送给mastr节点执行,执行抽象方法masterOperation由子类实现;另外通过ClusterStateObserver.waitForNextChange完成了错误重试功能。

ClusterStateObserver类,集群状态监控器。一个简化集群状态处理的工具类,用于失败重试和依赖其他集群状态等。其中waitForNextChange(listener,statePredicate)方法,当①集群状态变化并且满足传入的statePredicate时候,或者②达到超时时间timeOutValue时候(借助clusterService.addTimeoutListener实现
),回调listener执行。

3、TransportCreateIndexAction.masterOperation方法将CreateIndexRequest转换为CreateIndexClusterStateUpdateRequest,调用MetaDataCreateIndexService.createIndex方法。该方法负责在clusterstate中创建新的index(onlyCreateIndex方法),并且等待指定数目的active状态的shard副本数(activeShardsObserver.waitForActiveShards方法实现),最终返回给listener。

 1. 如果在clusterstate中成功创建index,则CreateIndexClusterStateUpdateResponse#isAcknowledged()就返回true,否则为false
 2. 如果clusterstate创建成功,并且在超时时间内指定数目的active状态shard副本数返回成功,则CreateIndexClusterStateUpdateResponse#isShardsAcked()为true,否则为false

4、onlyCreateIndex方法,其内部执行clusterService.submitStateUpdateTask,提交集群状态修改任务,提交任务的执行逻辑是AckedClusterStateUpdateTask类内部的execute方法。内部逻辑为:

 1. 校验index的名字和index的settings是否合法,校验 request 的别名是否合法
 2. 查找合适的模板findTemplates信息
 3. 解析customs、mappings、templatesAliases、templateNames信息
 4. 构建indexSettings
 5. indicesService服务增加index服务,mapperService服务合并mappings(indicesService.createIndex,mapperService.merge)
 6. 构建IndexMetaData
 7. 构建并生成新的ClusterState updatedState
 8. 如果index状态open,执行allocationService.reroute对shard进行分配
 9. 最后判断如果执行异常则删除索引服务(indicesService.removeIndex)

5、修改完成clusterstate,通过submitStateUpdateTask进行集群状态修改提交(上步骤逻辑),1发布集群状态(如果是master)、2通知集群状态应用器applier(如GatewayService持久化state、IndicesClusterStateService等)、3通知集群状态监听器listener(包含gateway等)完成集群功能。其他集群接收到集群状态变化,对应启动indicesService服务(通过IndicesClusterStateService.applyClusterState完成)。

6、clusterstate修改成功,开始等待指定数目的active状态的shard副本数。ActiveShardsObserver.waitForActiveShards。核心的判断逻辑是:

Predicate shardsAllocatedPredicate = newState -> activeShardCount.enoughShardsActive(newState, indexName);

上面的Predicate判断和执行通过ClusterStateObserver.waitForNextChange方法完成。最后判断执行结果设置为ShardsAcked。

至此,es集群完成了createIndex的功能。

existIndex

索引存在操作比较简单,通过TransportIndicesExistsAction类完成,该类继承了TransportMasterNodeReadAction类,由名字可以在master节点上执行读操作。
TransportIndicesExistsAction.masterOperation中进行了indexName的解析。无需进行任何集群状态处理。

Override
    protected void masterOperation(final IndicesExistsRequest request, final ClusterState state, final ActionListener<IndicesExistsResponse> listener) {
        boolean exists;
        try {
            // Similar as the previous behaviour, but now also aliases and wildcards are supported.
            indexNameExpressionResolver.concreteIndexNames(state, request);
            exists = true;
        } catch (IndexNotFoundException e) {
            exists = false;
        }
        listener.onResponse(new IndicesExistsResponse(exists));
    }

解析的过程实质是查询clusterState.MetaData中是否存在indexName,如果没有则抛出异常,解析类IndexNameExpressionResolver.concreteIndices

        final Set<Index> concreteIndices = new HashSet<>(expressions.size());
        for (String expression : expressions) {
            AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(expression);
            if (aliasOrIndex == null) {
                if (failNoIndices) {
                    IndexNotFoundException infe = new IndexNotFoundException(expression);
                    infe.setResources("index_expression", expression);
                    throw infe;
                } else {
                    continue;
                }
            }
            ...
        }    

deleteIndex

如果理解了CreateIndex,则删除也会比较简单。服务端通过TransportDeleteIndexAction实现,同样也继承了TransportMasterNodeAction类,完成master节点执行和重试功能。
1、TransportDeleteIndexAction.masterOperation方法把request转化为DeleteIndexClusterStateUpdateRequest,执行deleteIndexService.deleteIndices方法。
2、删除索引主要是修改clusterstate元数据,删数其中的index。

for (final Index index : indices) {
     String indexName = index.getName();
     logger.info("{} deleting index", index);
     routingTableBuilder.remove(indexName);
     clusterBlocksBuilder.removeIndexBlocks(indexName);
     metaDataBuilder.remove(indexName);
}

3、allocationService.reroute,对shard进行重新分配。
4、修改生成新clusterstate,通过submitStateUpdateTask进行状态发布。此处不在赘述。

总结

elasticsearch的索引管理操作分析流程已经分析完毕。主要有三类工作:

  1. clusterstate中indexMeta的维护
  2. 集群状态clusterstate的发布和应用
  3. 索引服务indiesService、分配服务allocationService的同步处理

ElasticSearch的索引处理还是比较精妙的,各部分结构定义比较清晰,如TransportMasterNodeAction主节点操作、ClusterStateObserver集群状态监控执行器、各类Builder(clusterstate、setting)。究其原因,是集群服务认识深刻,作者厉害!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值