`
wbj0110
  • 浏览: 1636952 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

分布式搜索elasticsearch的5种分片查询优先级

阅读更多
elasticsearch可以使用preference参数来指定分片查询的优先级,使用时就是在请求url上加上preference参数,如:http://ip:host/index/_search?preference=_primary
java的调用接口翻译为:client.prepareSearch("index").setPreference("_primary")。
 
默认情况下es有5种查询优先级:
_primary: 指查询只在主分片中查询
_primary_first: 指查询会先在主分片中查询,如果主分片找不到(挂了),就会在副本中查询。
_local: 指查询操作会优先在本地节点有的分片中查询,没有的话再在其它节点查询。
_only_node:指在指定id的节点里面进行查询,如果该节点只有要查询索引的部分分片,就只在这部分分片中查找,所以查询结果可能不完整。如_only_node:123在节点id为123的节点中查询。
Custom (string) value:用户自定义值,指在参数cluster.routing.allocation.awareness.attributes指定的值,如这个值设置为了zone,那么preference=zone的话就在awareness.attributes=zone*这样的节点搜索,如zone1、zone2。关于这个值作用可以参考下面文章。
 
虽然es有提供这5种优先级,但感觉还是不能满足我的需求,我是想能指定在某一个或多个节点中查询,比如node1和node2里面的分片能组成一个完整的索引,那我可以只在node1和node2中搜索就行了。看来只能改源码解决,改源码也非常简单。
 
首先找到org.elasticsearch.cluster.routing.operation.plain.PlainOperationRouting这个类,es搜索时获取分片信息是通过这个类的。它的preferenceActiveShardIterator()方法就是根据条件来找出响应的分片。看源码可知其主要是根据preference这个参数来决定取出的分片的。如果没有指定该参数,就随机抽取分片进行搜索。如果参数以_shards开头,则表示只查询指定的分片。注意,这个功能官网的文档中没有写到。
然后下面就是判断我上面说的5种优先级情况。我们现在要加个多节点分片查询的功能,仿照单个节点分片查询(指_only_node)就行了,在
if (preference.startsWith("_only_node:")) {
    return indexShard.onlyNodeActiveShardsIt(preference.substring("_only_node:".length()));
}
后面加上
if (preference.startsWith("_only_nodes:"))  {
    return indexShard.onlyNodesActiveShardsIt(preference.substring("_only_nodes:".length()));
}
onlyNodesActiveShardsIt这个方法在org.elasticsearch.cluster.routing.IndexShardRoutingTable中是没有的,要自己写。加上
/**
     * Prefers execution on the provided nodes if applicable.
     */
    public ShardIterator onlyNodesActiveShardsIt(String nodeIds) {
        String[] ids = nodeIds.split(",");
        ArrayList<ShardRouting> ordered = new ArrayList<ShardRouting>(shards.size());
        // fill it in a randomized fashion
        for (int i = 0; i < shards.size(); i++) {
            ShardRouting shardRouting = shards.get(i);
            for(String nodeId:ids){
              if (nodeId.equals(shardRouting.currentNodeId())) {
                ordered.add(shardRouting);
              }
            }
        }
        return new PlainShardIterator(shardId, ordered);
    }
 
重新编译源码就行了。查询时加上?preference=_only_nodes:node1id,node2id 就可以指定在node1和node2中搜索
分享到:
评论

相关推荐

    掌控数据流:如何管理 Elasticsearch 的副本

    在 Elasticsearch 中,数据被分割成多个分片,每个分片又可以拥有一个或多个副本。这种设计确保即使某个节点出现故障,数据依然可以保持高可用性,并且通过并行处理查询请求来提高搜索性能。 - **主分片**:原始...

    大规模分布式应用

    5. **分布式数据库**:通过分布式部署数据库,如分片、分区等,可横向扩展存储和处理能力。 6. **服务分离**:应用服务和数据服务的分离,有利于系统解耦和负载均衡。 7. **搜索引擎集成**:通过搜索引擎(如...

    2024年java面试题-ElasticSearch面试题集

    - **实际应用**:通过使用倒排索引,Elasticsearch 能够在海量数据中迅速找到与查询条件匹配的结果,大大提升了搜索效率。 #### 3. 大规模数据下的 Elasticsearch 索引管理和调优 - **面试官意图**:考察应聘者在...

    2021Java高级架构面试知识点整理V1.0

    - 读取数据和搜索数据则涉及查询执行计划、分片查询和结果合并等过程。 9. Elasticsearch性能优化 - 性能优化可通过缓存、数据预热、冷热分离、查询分页优化等手段实现。 10. Elasticsearch生产集群的部署架构 ...

    淘宝2017校园招聘清华笔试试题(1).pdf

    设计时,可以考虑使用NoSQL数据库或搜索引擎技术如Elasticsearch,通过分区、分片、并行处理等方式提高查询效率。 四、综合题 - 海量网页内容中查找关键词,可以采用倒排索引技术,将关键词作为索引,网页ID作为值...

    百亿级日志系统架构设计及优化

    - 针对数据访问的热点,采用分区、分片等策略,确保数据分布均匀,减轻单点压力。 在上述优化过程中,ELK(Elasticsearch、Logstash、Kibana)作为常见的开源日志解决方案,被广泛采用。其中,Elasticsearch负责...

Global site tag (gtag.js) - Google Analytics