dock的elsticsearch集群增删改和高亮

索引:相当于数据库,es可以把缩影放到一台服务器上,一个索引可以有一个或者多个分片,每个分片有多个副本。索引只是把一个或者多个分片组在一起的逻辑空间,文档存储在索引中。

索引类型:相当于数据库中的表,每个索引类型有不同的结构。

一个lucene实例,会xi

 

消耗相应的cpu,io,内存,文件描述

通常情况下很多场景在50GB大小以内,我们将平均大小控制在20GB到40GB之间

文档:每个文档,相当于数据库中一条记录,每个文档由多个字段构成,每个文档有不同的字段,并且有唯一标识符

映射:es默认创建索引和索引类型的mappi

一个文档不只有数据,还包含了元数据,相当于文档信息,三个必须的元数据节点

_index:文档存储的地方

_type:代表对象类

_id:文档唯一标识,id仅仅是一个字符串,他与_index和_type组合时,就是唯一标识文档,文档一个文档,可以定义一个id,也可以让elasticserach生成

分片大小:一般建议50G,太小多线程查询,多个并发,会降低查询吞吐量,非常大的分片,会使集权从故障中恢复能力产生负面影响

分片过多会导致检索时打开比较多的文件,也会导致多台服务器之前通讯,而分片数量过少,会导致分片过大,所以检索速度慢,一个索引会分成多个分分片数量在索引建立后不可更改。

性能调优:

1.关闭data节点的httpgong功能http.enabled: false。Head,bigdesk,marvel等监控插件,数据节点只需处理创建/更新/删除/查询索引数据操作

2.最小主节点防止脑裂

当集群异常,出现重选主节点,会出现多个主节点,称为脑裂。可she'设置最少ke'g可工作候选主节点个数,建议设置为(候选主节点/2)+1

discovery.zen.minimum_master_nodes

候选主节点设置为node.mater为true

3.指定集群及节点的名字

防止其他不小心加入集群

4.一台机器最好只部署一个node,但是一台服务器的cpu,内存,磁盘毕竟有限,不建议一个上面启动多个node

5.多个path.data,提高io性能

6.集群恢复配置

gateway.recover_after_nodes: 8。这个参数可以让es直到有足够的node都上线之后,再开始shard recovery的过程。

gateway.expected_nodes: 10,gateway.recover_after_time: 5m。经过上面的配置之后,es集群的行为会变成下面这样,等待至少8个节点在线,然后等待最多5分钟,或者10个节点都在线,开始shard recovery的过程

7.预留一般内存给luncene使用

8.es默认的堆内存是1.9G,不够用。建议分配物理机器的内存的一半,最大不超过32G

关闭linux的swap功能

9.分片数和备份数

创建索引的时候,最好指定相关的shards,配置total_shards_per_node参数,限制每个index每个节点最多分配多少个

副本数于索引的稳定性有比较大的关系,如果node挂了,会导致分片丢失,为保证数据的完整性,可以通过副本来解决这个问题,建议在建完索引后,执行optimize后。副本立马调整过来

10设置合理刷新时间

建立索引,不会立马查到,里面配置了index.refresh_interval参数,默认是1s。

这迫使集群每秒创建一个新的segment,可以设置30,60允许更大的的segment写入,减压以后,segment合并压力

这些内存里的segment就是可以被搜索shu数据,默认是1s生成一个segment,然后随着时间的流逝,内存里面的segment越来

越多。es还提供一个功能,叫做segment合并。

segment被检测满足合并策略,它会在内存里面被合并,随着时间的流逝,直到内存的segment达到了上限,这些数据会被刷新到磁盘上。

断电虽然segment中数据会没有,但是tranlog中记录数据,只有数据进入磁盘,tranlog数据才会被删除

11.根据业务设置合理的字段类型

文档值是存储在磁盘上的数据结构,在索引时,根据文档的原始值创建,文档值是一个列式存储风格的数据结构,非常适合执行存储喝聚合操作,除了字符类型分析字外,如果字段要对执行排序或者聚合操作,可以禁用文档值,节省磁盘空间。

 

 

 

 

 

<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<!-- <version>7.9.2</version>-->
</dependency>

 

 

 

version版本要去掉,否则报错

Factory method 'elasticsearchRestHighLevelClient' threw exception; nested exception is java.lang.NoSuchFieldError: IGNORE_DEPRECATIONS

//批量插入
@GetMapping("/bulk")
public void bulk() throws IOException {
    RestHighLevelClient client=new RestHighLevelClient(RestClient.builder(
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9200,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9201,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9202,"http")));

    BulkRequest request=new BulkRequest();
    request.add(new IndexRequest("peiyajie-2020","doc").
            source(XContentType.JSON,"address","address1"));

    request.add(new IndexRequest("peiyajie-2020","doc").
            source(XContentType.JSON,"address","address2"));
    request.add(new IndexRequest("peiyajie-2020","doc").
            source(XContentType.JSON,"address","address3"));
    request.add(new IndexRequest("peiyajie-2020","doc").
            source(XContentType.JSON,"address","address4"));

    //new DeleteRequest("peiyajie-2020","20")
 //   new UpdateRequest("peiyajie-2020","20").doc(XContentType.JSON,"other","foo3")
    request.timeout(TimeValue.timeValueMinutes(2));
    request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
    request.waitForActiveShards(ActiveShardCount.ALL);
    BulkResponse bulkResponse=client.bulk(request,RequestOptions.DEFAULT);
     for(BulkItemResponse bulkItemResponse:bulkResponse)  {
         if(bulkItemResponse.isFailed()){
             BulkItemResponse.Failure failure=bulkItemResponse.getFailure();
             logger.info("failure.getMessage():"+failure.getMessage());
         }
         DocWriteResponse docWriteResponse=bulkItemResponse.getResponse();
         switch (bulkItemResponse.getOpType()){
             case INDEX:
             case CREATE:
                 IndexResponse indexResponse=(IndexResponse)docWriteResponse;
                 logger.info("CREATE:");
                 break;
             case UPDATE:
                 UpdateResponse updateResponse=(UpdateResponse)docWriteResponse;
                 logger.info("UPDATE:");
                 break;
             case DELETE:
                 DeleteResponse deleteResponse=(DeleteResponse)docWriteResponse;
                 logger.info("DELETE:");
         }
     }
}
//高亮查询
@GetMapping("/highQuery")
public void highQuery(String address) throws IOException {
    RestHighLevelClient client=new RestHighLevelClient(RestClient.builder(
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9200,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9201,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9202,"http")));
   //定义索引库
    SearchRequest searchRequest=new SearchRequest("peiyajie-2020");
    SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
    //定义query查询
    QueryBuilder queryBuilder = QueryBuilders.matchQuery("address", address);
    //定义高亮查询
    HighlightBuilder highlightBuilder=new HighlightBuilder();//高亮查询器
    highlightBuilder.field("address");//高亮查询字段
    highlightBuilder.requireFieldMatch(false);//如果要多个字段高亮,这项为false
    highlightBuilder.preTags("<span style=\"color:red\">");//高亮设置
    highlightBuilder.postTags("</span>");
    //下面这两项,如果你要把高亮如文字内容等很多字段,必须配置,不然会导致高亮不全,文章内容缺失等
    highlightBuilder.fragmentSize(800000);//最大高亮分片数
    highlightBuilder.numOfFragments(0);//从第一个分片获取高亮片段
    searchSourceBuilder.query(queryBuilder);
    searchSourceBuilder.highlighter(highlightBuilder);
    searchRequest.source(searchSourceBuilder);
    SearchResponse  searchResponse=client.search(searchRequest,RequestOptions.DEFAULT);
    List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
    //遍历高亮结果
    for(SearchHit hit:searchResponse.getHits().getHits()){
     Map<String, HighlightField> highlightFields=hit.getHighlightFields();
     HighlightField nameHighlight=highlightFields.get("address");
     Map<String,Object> sourceAsMap=hit.getSourceAsMap();
     if(nameHighlight!=null){
         Text[] fragments=nameHighlight.getFragments();
         String _address="";
         for(Text text:fragments){
             _address+=text;
         }
         sourceAsMap.put("address",_address);
         list.add(sourceAsMap);
     }
    }
}
//删除
@GetMapping("/delete")
public void delete() throws IOException {
    RestHighLevelClient client=new RestHighLevelClient(RestClient.builder(
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9200,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9201,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9202,"http")));
   try {
       DeleteRequest deleteRequest = new DeleteRequest("peiyajie-2020", "doc", "20");
       //等待主分片可用的超时时间
       deleteRequest.timeout(TimeValue.timeValueMinutes(10));
       //一直保持请求连接中,直接当所做的更改对于搜索查询可见时的刷新发生后,再将结果返回
       deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);

       DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
       if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {//判断删除文档是否存在
           logger.info("要删除的文档不存在");
           return;
       }
       String index = deleteResponse.getIndex();
       String type = deleteResponse.getType();
       String id = deleteResponse.getId();
       long version = deleteResponse.getVersion();
       logger.info("index:" + index + ";type:" + type + ";id:" + id + ";version:" + version);

       //查询分片执行的情况
       ReplicationResponse.ShardInfo shardInfo = deleteResponse.getShardInfo();
       if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
           logger.info("未完全执行所有分片,总分片数为:" + shardInfo.getTotal() + ",执行的分片数:" + shardInfo.getSuccessful());
           return;
       }
       if (shardInfo.getFailed() > 0) {
           for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
               String reason = failure.reason();
               logger.info("失败原因:" + reason);
               return;
           }
       }
   }catch (ElasticsearchException e){
       if(e.status()==RestStatus.CONFLICT){
           logger.info("需要删除文档版本与现在文档冲突!");
       }
   }catch (Exception e){
       e.printStackTrace();
   }
}
//异步删除方法
//删除
@GetMapping("/deleteASyn")
public void deleteASyn() throws IOException {
    RestHighLevelClient client=new RestHighLevelClient(RestClient.builder(
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9200,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9201,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9202,"http")));
    DeleteRequest deleteRequest = new DeleteRequest("posts4", "doc", "1");
     //   DeleteRequest deleteRequest = new DeleteRequest("peiyajie-2020", "doc", "20").version(2);
   // 注意:如果对一个文档添加版本条件(如id为2,版本为2)进行删除(删除后文档version变为3),再次删除时,
        //等待主分片可用的超时时间
        deleteRequest.timeout(TimeValue.timeValueMinutes(10));
        //一直保持请求连接中,直接当所做的更改对于搜索查询可见时的刷新发生后,再将结果返回
        deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
        //异步回调对象
        ActionListener<DeleteResponse> listener = new ActionListener<DeleteResponse>() {
            @Override
            public void onResponse(DeleteResponse deleteResponse) {
                if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
                    logger.info("未找到需要删除的文档!");
                    return;
                }
                String index = deleteResponse.getIndex();
                String type = deleteResponse.getType();
                String id = deleteResponse.getId();
                long version = deleteResponse.getVersion();
                logger.info("index:" + index + ";type:" + type + ";id:" + id + ";version:" + version);

                //查询分片执行的情况
                ReplicationResponse.ShardInfo shardInfo = deleteResponse.getShardInfo();
                if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
                    logger.info("未完全执行所有分片,总分片数为:" + shardInfo.getTotal() + ",执行的分片数:" + shardInfo.getSuccessful());
                    return;
                }
                if (shardInfo.getFailed() > 0) {
                    for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
                        String reason = failure.reason();
                        logger.info("失败原因:" + reason);
                        return;
                    }
                }
            }

            @Override
            public void onFailure(Exception e) {
            }
        };

     client.deleteAsync(deleteRequest, RequestOptions.DEFAULT,listener);
     //所有异步操作,一定不要将client关闭太早,否则操作还没执行程序就被中止了
    //所以同步方法创作对象可以放在try中,执行完自动关闭,而异步方法不可以
}

//同步新增方法
@GetMapping("/index")
public void index() throws IOException {
    RestHighLevelClient client=new RestHighLevelClient(RestClient.builder(
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9200,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9201,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9202,"http")));
     XContentBuilder builder=XContentFactory.jsonBuilder();
     builder.startObject();
    {
        builder.field("user","kimchy");
        builder.timeField("postDate",new Date());
        builder.field("message","trying out Elasticsearch");
    }
    builder.endObject();
    IndexRequest indexRequest=new IndexRequest("peiyajie-2020","doc","20").source(builder);
    indexRequest.timeout(TimeValue.timeValueSeconds(5));
    //DocWriteRequest.OpType.INDEX如果文档存在,则更新文档。文档不存在,则创建文档
    //DocWriteRequest.OpType.CREATE。如果文档存在,则报错,根据id来判断
    indexRequest.opType(DocWriteRequest.OpType.INDEX);
    try{
       IndexResponse indexResponse=client.index(indexRequest,RequestOptions.DEFAULT);
        String index=indexResponse.getIndex();
        String type=indexResponse.getType();
        String id=indexResponse.getId();
        long version=indexResponse.getVersion();
        if(indexResponse.getResult()== DocWriteResponse.Result.CREATED){
            //处理(如果需要)第一次创建文档的情况
            logger.info("添加成功");
            logger.info("index:"+index);
            logger.info("type:"+type);
            logger.info("id:"+id);
            logger.info("version:"+version);
            logger.info("key-pairs形式的注入处理(如果需要)第一次创建文档的情况");
        }else if (indexResponse.getResult()== DocWriteResponse.Result.UPDATED){
            //处理(如果需要)文档被重写的情况
            logger.info("更新成功");
            logger.info("index:"+index);
            logger.info("type:"+type);
            logger.info("id:"+id);
            logger.info("version:"+version);
            logger.info("key-pairs形式的注入处理(如果需要)文档被重写的情况");

        }
    }catch(ElasticsearchException e){
        if(e.status()==RestStatus.CONFLICT){
            logger.info("创建的文档与已存在的发生冲突");
        }
    }
    client.close();
}

//异步新增
@GetMapping("/indexAsync")
public void indexAsync() throws IOException {
    RestHighLevelClient client=new RestHighLevelClient(RestClient.builder(
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9200,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9201,"http"),
            new HttpHost("p43148v.hulk.shbt.qihoo.net",9202,"http")));
    XContentBuilder builder=XContentFactory.jsonBuilder();
    builder.startObject();
    {
        builder.field("user","kimchy");
        builder.timeField("postDate",new Date());
        builder.field("message","trying out Elasticsearchpeiyajie");
    }
    builder.endObject();
    //id为null的话,会创建一个自动生成的id
    IndexRequest indexRequest=new IndexRequest("posts4","doc","20").source(builder);
    indexRequest.timeout(TimeValue.timeValueSeconds(5));
    //DocWriteRequest.OpType.INDEX如果文档存在,则更新文档。文档不存在,则创建文档
    //DocWriteRequest.OpType.CREATE。如果文档存在,则报错,根据id来判断
    indexRequest.opType(DocWriteRequest.OpType.INDEX);
    ActionListener<IndexResponse> listener=new ActionListener<IndexResponse>(){
        @Override
        public void onResponse(IndexResponse indexResponse) {
            String index=indexResponse.getIndex();
            String type=indexResponse.getType();
            String id=indexResponse.getId();
            long version=indexResponse.getVersion();
            if(indexResponse.getResult()== DocWriteResponse.Result.CREATED){
                //处理(如果需要)第一次创建文档的情况
                logger.info("添加成功");
                logger.info("index:"+index);
                logger.info("type:"+type);
                logger.info("id:"+id);
                logger.info("version:"+version);
                logger.info("key-pairs形式的注入处理(如果需要)第一次创建文档的情况");
            }else if (indexResponse.getResult()== DocWriteResponse.Result.UPDATED){
                //处理(如果需要)文档被重写的情况
                logger.info("更新成功");
                logger.info("index:"+index);
                logger.info("type:"+type);
                logger.info("id:"+id);
                logger.info("version:"+version);
                logger.info("key-pairs形式的注入处理(如果需要)文档被重写的情况");

            }
        }

        @Override
        public void onFailure(Exception e) {
            ElasticsearchException elasticsearchException=(ElasticsearchException) e;
            if(elasticsearchException.status()==RestStatus.CONFLICT){
                logger.info("创建文档已存在");
            }

        }
    };
    client.indexAsync(indexRequest,RequestOptions.DEFAULT,listener);
   // client.close();如果不被注释掉,可能还没有将请求发送出去,连接就会被关闭,从而创建或者更新失败

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值