【ES】--Elasticsearch的索引别名和主副分片

一、ES的别名

为什么使用ES别名?
灵活的扩容。
动态的滚动查询。 例如“在不同的索引创建窗口”。
进行索引分组。
使用别名过滤器来屏蔽文档,他们可以对正在执行的查询自动地实施过滤。
结合别名和路由,在查询或索引的时候自动地使用路由值。

二、ES的分片

分片作用:
(1)、更好的分布式存储、扩展。
(2)、高效地平行查询。
副本的作用:
(1)、保证数据完整性,节点出现异常时,充当主分片。
(2)、优化查询效率,副本的数据和主分片一致,可以充分发挥查询时的效率。

集群索引出现创建、搜索慢,如何解决?
硬件上进行节点的增加;
重建索引,重新划分主副节点数量【可以使用别名来平滑的操作】;

三、ES的别名的增删改查

插入数据
插入数据时,按照“具体index”来插入数据,同时可以设置别名。

查询数据
根据id/其他属性去搜索“具体index”。—可以查询
根据“别名”来查询所有索引的数据。—可以查询

删除数据
根据“具体index”删除,deleteByQuery方式删除;—可以删除
根据“别名”删除,deleteByQuery方式删除;—可以删除
【----原因:根据条件查询到具体索引的记录,然后对查询到的数据按照“具体index”进行删除。】
根据“具体index”及主键id,先查询数据,然后“具体index”删除。—可以删除
根据“别名”及主键id,先查询数据,然后“具体index”删除。—可以删除

3.1、创建别名/分片的代码示例


    public String getIndexName(String index, String type) {
        if ("month".equals(type)) {
            String yyyyMM = new SimpleDateFormat("yyyyMM").format(new Date());
            return index + "-" + yyyyMM;
        }
        if ("quarter".equals(type)) {
            return getQuarterFirstMonth(index);
        }
        if ("year".equals(type)) {
            String yyyy = new SimpleDateFormat("yyyy").format(new Date());
            return index + "-" + yyyy;
        }
        return "";
    }
    
    
  public String insert(T entity) throws Exception {
        //确定当前ES的索引是否需要  按时间生成新的
        String newIndexName = getIndexName(entity.getIndex(),"year"); //默认生成 todo
        entity.setIndex(newIndexName);
        //生成 n个分片+副分片、并生成别名
             //例如 Index为test_file-2023,别名是test_file
        String alias = entity.getIndex().substring(0,entity.getIndex().lastIndexOf("-"));
        if(!checkIndexExist(newIndexName)){ //校验具体索引是否已经创建
            createIndexWithAlias(newIndexName,alias); //创建有别名的索引,并进行分片
        }
        IndexRequest request = new IndexRequest(newIndexName);
        request.id(entity.getId())
                .source(JSONObject.toJSONString(entity), XContentType.JSON)
                .create(false);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        String name = response == null ? null : response.getResult().name();
        log.info("ES执行插入:index:{},type:{},id:{}", newIndexName, request.type(), request.id());
        return name;
    }

校验索引是否已经创建

   public boolean checkIndexExist(String index) throws Exception {
        GetIndexRequest getIndexRequest = new GetIndexRequest(index);
        boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        if (exists) {
            return true;
        }
        return false;
    }

创建别名/分片。

 public boolean createIndexWithAlias(String index,String alias) throws IOException {
        CreateIndexRequest indexRequest = new CreateIndexRequest(index);
        indexRequest.settings(Settings.builder()
                .put("index.number_of_shards", 2)
                .put("index.number_of_replicas", 1));
        if(StringUtils.isNotBlank(alias)){
            indexRequest.alias(new Alias(alias));
        }
        CreateIndexResponse response = client.indices().create(indexRequest, RequestOptions.DEFAULT);
        return response.isAcknowledged();
    }

3.2、CRUD代码示例

    public Object testTransfer( Map<String, Object> itemMap){
        List<String> dmcIds = (List<String>)itemMap.get("dmc_ids");
        String scene = (String)itemMap.get("scene");
        List<String> ids = (List<String>)itemMap.get("ids");
        JSONObject testDoc = (JSONObject)itemMap.get("file_transfer");
        TransferEsDo transferDoc = JSONObject.parseObject(JSON.toJSONString(testDoc),TransferEsDo.class);

        /**
         * 事先有别名  file_transfer_wwy  ,索引有 file_transfer_wwy-2022、file_transfer_wwy-2023
         */
        //ES分片的插入数据
        if("1".equals(scene)){
            try{
                transferElasticRepository.insert(transferDoc);
            }catch (Exception e){
                log.error("testTransfer scene=1 ");
            }
        }
        //从ES查询记录
        if("2".equals(scene)){//根据实际Index查询或别名查询
            BoolQueryBuilder boolBuilder = new BoolQueryBuilder();
            if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(ids)){
                BoolQueryBuilder idBuilder = new BoolQueryBuilder()
                        .must(QueryBuilders.termsQuery("_id",ids));
                boolBuilder.should(idBuilder);
            }
            if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(dmcIds)){
                BoolQueryBuilder fileIdBuilder = new BoolQueryBuilder()
                        .must(QueryBuilders.termsQuery("file_id.keyword",dmcIds));
                boolBuilder.should(fileIdBuilder);
            }
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(boolBuilder);
            searchSourceBuilder.from(0);
            searchSourceBuilder.size(100);
            SearchRequest searchRequest = new SearchRequest(transferDoc.getIndex());
            searchRequest.source(searchSourceBuilder);
            List<TransferEsDo> transferReList = new ArrayList<>();
            try {
                SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                for (SearchHit searchHit : searchResponse.getHits()) {
                    transferReList.add(JSON.parseObject(searchHit.getSourceAsString(), TransferEsDo.class));
                }
            } catch  (Exception e){
                log.error("testTransfer dmcIds:{},ex:{}", JSON.toJSONString(dmcIds),e.getMessage());
            }

        }

        if("3".equals(scene)){ //根据别名或实际index删除
            DeleteByQueryRequest request = new DeleteByQueryRequest(transferDoc.getIndex());
            request.setQuery(QueryBuilders.termsQuery("file_id.keyword",transferDoc.getFileId()));
            try{
                restHighLevelClient.deleteByQuery(request, RequestOptions.DEFAULT);
            }catch (Exception e){
                log.error("testTransfer fileId deleteByQuery ex:{}",e.getMessage());
                return false;
            }
        }

        if("4".equals(scene)){ //根据别名或实际index删除
            try{
                //还是根据id,index或别名获取到记录,然后按照实际的indexName和id进行删除
                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                sourceBuilder.query(QueryBuilders.termsQuery("id", Arrays.asList(transferDoc.getId())));
                sourceBuilder.size(10000);
                SearchRequest searchRequest = new SearchRequest(transferDoc.getIndex());
                searchRequest.source(sourceBuilder);
                SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                SearchHits hits = searchResponse.getHits();
                List<TransferEsDo> result = new ArrayList<>();
                for (SearchHit hit : hits.getHits()) {
                    result.add(JSON.parseObject(JSON.toJSONString(hit.getSourceAsMap()), TransferEsDo.class));
                }

                DeleteRequest request = new DeleteRequest(result.get(0).getIndex(), result.get(0).getId());
                DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);

            }catch (Exception e){
                log.error("testTransfer fileId deleteByQuery ex:{}",e.getMessage());
                return false;
            }
        }
        return false;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamBoy_W.W.Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值