• es的调优


    3.1、分片查询方式

    当前的图片中有5个主分片,5个副本;这对于es的集群来说,这种配置是非常常见的;

    但是问题来了,当我们的客户端做查询的时候,程序会向主分片发送请求还是副本发送请求?

    还是说直接去集群上随机找一台机器查询,还是在这个机器里面在随机的找到分片和副本查询?

    【注意】:

    默认情况下是随机查询的

    这种随机的方式其实效率并不高,

    1查询阶段

    (1):客户端发送一个检索请求给node3,此时node3会创建一个空的优先级队列并且配置好分页参数from与size

    (2):node3将检所请求发送给index中的每一个shard(primary 和 replica),每一个在本地执行检索,并将结果添加到本地的优先级队列中;

    (3):每个shard返回本地优先级序列中所记录的_id与score值,并发送node3。Node3将这些值合并到自己的本地的优先级队列中,并做全局的排序。

     

    2获取阶段

    (1):node 3获取了所有待检索数据的定位之后,发送一个mget的请求给与数据相关的shard。

    (2):每个收到node 3的get请求的shard将读取相关文档_source中的内容,并将它们返回给node 3。

    (3):当node 3获取到了所有shard返回的文档后,node 3将它们合并成一条汇总的结果,返回给客户端。

    我们通过上面的查询方式可以了解到,如果我们直接将客户端定位到指定的机器上查询,就少去了中间的来回复制的步骤,这样在检索大量数据的时候,网络的IO也得到了提升

    其实,在elasticsearch的查询阶段,我们可以做很多的优化措施,比如控制我们的分片查询方式:

    Es会将数据均衡的存储在分片中,我们可以指定es去具体的分片或节点中查询从而进一步的实现es极速查询。
    
    1:randomizeacross shards
    随机选择分片查询数据,es的默认方式
    
    2:_local
    优先在本地节点上的分片查询数据然后再去其他节点上的分片查询,本地节点可以减少跨网络的IO问题,但有可能造成负载不均问题
    
    3:_primary
    只在主分片中查询不去副本查
    
    4:_primary_first
    优先在主分片中查,如果主分片挂了则去副本查
    
    5:_only_node[已经被移除]
    只在指定id的节点中的分片中查询
    
    6:_prefer_node
    优先在指定你给节点中查询
    
    7:_shards
    在指定分片中查询
    
    8:_only_nodes
    可以自定义去指定的多个节点查询,es不提供此方式需要改源码。
      /**
         * 分片查询方式
         * */
        @Test
        public void searchType(){
            SearchRequestBuilder builder = client.prepareSearch("school").setTypes("student");
            SearchResponse searchResponse = builder.setQuery(QueryBuilders.matchQuery("name", "于谦"))
    //                .setPreference("_local")
    //                .setPreference("_primary")
    //                .setPreference("_only_nodes:*")
    //               .setPreference("_prefer_nodes:jnrN6IYURTKYPE_ZYQqFDg")
    //                .setPreference("_shards:0,1,2")//TODO 可以提高查询效率
    //                .setPreference("randomizeacross")
                    .get();//指定查询方式
            SearchHits hits = searchResponse.getHits();
            System.out.println("查询的结果数量有"+hits.getTotalHits()+"条");
            System.out.println("结果中最高分:"+hits.getMaxScore());
    
            // 遍历每条数据
            Iterator<SearchHit> iterator = hits.iterator();
            while(iterator.hasNext()){
                SearchHit searchHit = iterator.next();
                System.out.println("所有的数据JSON的数据格式:"+searchHit.getSourceAsString());
                System.out.println("每条得分:"+searchHit.getScore());
                // 获取每个字段的数据
                System.out.println("id:"+searchHit.getSource().get("id"));
                System.out.println("name:"+searchHit.getSource().get("name"));
                System.out.println("age:"+searchHit.getSource().get("age"));
                System.out.println("**********************************************");
                for(Iterator<SearchHitField> ite = searchHit.iterator(); ite.hasNext();){
                    SearchHitField next = ite.next();
                    System.out.println(next.getValues());
                }
            }
        }
  • 相关阅读:
    sublime text3 安装SublimeCodeIntel插件
    进入博客园的第一天
    .NET之Hangfire快速入门和使用
    图片相似性 d-hash算法 C#实践
    同一个Docker swarm集群中部署多版本的测试环境
    C#创建单链表,翻转单链表
    halcon例程学习 一维测量之矩形边缘
    halcon例程学习 一维测量之弧形边缘
    python 圆曲线
    python pygame黑客帝国的简单实现
  • 原文地址:https://www.cnblogs.com/niutao/p/10909342.html
Copyright © 2020-2023  润新知