5

ES系列二之常见问题解决 - 木木他爹

 1 year ago
source link: https://www.cnblogs.com/darling2047/p/16928415.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

上篇ES系列一之java端API操作结束后本以为就相安无事了,但生产的问题是层出不穷的;下面我就再记录下近几周遇到的问题以及解决方案;

一 更新ES信息报错

报错信息如下:
Use ElasticsearchException.getFailedDocuments() for detailed messages [{yjZ8D0oB=ElasticsearchException[Elasticsearch exception [type=cluster_block_exception, reason=index [au_report] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];]]

分析:看报错信息大概意思就是es的写入操作被阻塞了,索引只能读、删不能修改新增了;我总结了这种错误的解决方案以及步骤,如下:

  • 1、发送请求将read_only_allow_delete属性置成false或者删除;如下:
curl --location --request PUT 'http://127.0.0.1:9200/au_report/_settings' \
--header 'Content-Type: application/json' \
--data-raw '{
"index.blocks.read_only_allow_delete": null
}'

read_only_allow_delete表示es只读和允许删除不能做修改操作,当磁盘空间达到95%时自动为true;

  • 2、如果上述请求成功后仍然报错,那么可以查看es使用磁盘的空间占用情况,调用如下:
    curl --location --request GET 'http://127.0.0.1:9200/_cat/allocation?v'
    下面贴上该请求返回的各项代表的意思:
    • shards:分片数
    • disk.indices:索引index占用的空间大小
    • disk.used:已用磁盘空间
    • disk.avail:可用磁盘空间
    • disk.total:磁盘空间总量
    • disk.percent:磁盘已使用百分比
    • host:节点主机地址
    • ip:节点ip
    • node:节点名称
  • 3、我的情况就是这里发现disk.percent磁盘已使用空间的百分比已经超过98%了,所以我的当务之急是改配置或者删数据;由于我这边的es服务并非自己搭建的,于是登录es主机进行了以下操作
    • 通过jps或者ps -ef | grep elastic查看es的进程ID
    • 通过ll /proc/进程ID/cwd 查看es安装位置
    • 通过查看es的配置文件/elasticsearch-7.6.2/config/elasticsearch.yml的配置发现并未配置es文件的落盘位置,那么默认应该是与当前安装目录在同一个磁盘;
    • 于是通过df -h [指定目录] 查看es安装目录磁盘占用情况,发现果然超过95%了,其实上面通过/_cat/allocation?v请求已经知悉磁盘空间使用情况了,这里只是做一个校验确定
  • 4、由于磁盘空间我这边无法清理,于是找运维同事在有足够磁盘空间的目录下创建data和log文件夹,然后将elasticsearch.yml里的path.data和path.log的值换成新建的data和log目录,然后重启就解决了这个报错

二、命中结果高亮展示

我使用的spring-data-elasticsearch的版本是4.3.4,其实只要在ES系列一之java端API操作;分页查询的测试方法queryPageData()基础上新增HighlightBuilder设置需要高亮的字段然后设置到返回结果去即可,下面贴上查询代码:

@Test
    public void queryPageData(){
        // 此处应是查询参数,这里单元测试没有赋值
        TestQuery query = new TestQuery();
        query.setTextKey("张三");
        PaginationModel<EsTestInfo> res = new PaginationModel<>();
        int currentPage=query.getPageIndex()-1;
        int pageSize = query.getPageSize();
        PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        BoolQueryBuilder textKeyBqb = new BoolQueryBuilder();
        if (StringUtils.isNotBlank(query.getTextKey())) {
            /**
             *  由于下面会用到must查询,所以此处用textKeyBqb再封装一个builder出来,否则
             *  和must同时查询此处会出现0匹配也返回结果的情况
             *  如果不想封装textKeyBqb,加上boolQueryBuilder.minimumShouldMatch(1)强制使es
             *  最少满足一个should子句才能返回结果也行
             */
            textKeyBqb.should(QueryBuilders.matchQuery("id", query.getTextKey()))
                    .should(QueryBuilders.matchQuery("name", query.getTextKey()))
                    .should(QueryBuilders.matchQuery("desc", query.getTextKey()));
        }
        if (Objects.nonNull(query.getStartDate()) && Objects.nonNull(query.getEndDate())) {
            RangeQueryBuilder timeRangeQuery = QueryBuilders.rangeQuery("publishDt")
                    .gte(query.getStartDate().getTime())
                    .lte(query.getEndDate().getTime());
            boolQueryBuilder.must(timeRangeQuery);
        }
        if (Objects.nonNull(query.getRptStatus())) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("rptStatus", query.getRptStatus()));
        }
        // 将上面封装的子句加入到主查询条件中
        boolQueryBuilder.must(textKeyBqb);
        log.info("<<<<<<<<<<<<<<<<<<boolQueryBuilder:{}",boolQueryBuilder);
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder).withPageable(pageRequest)
                // 设置需要高亮的字段
                .withHighlightFields(
                        new HighlightBuilder.Field("name")
                        ,new HighlightBuilder.Field("desc"))
                // 设置高亮的html格式
                .withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>")).build();
        // 解决es一次只返回10000条数据的问题
        searchQuery.setTrackTotalHits(true);
        SearchHits<EsTestInfo> search = elasticsearchRestTemplate.search(searchQuery, EsTestInfo.class);
        List<EsTestInfo> list = new ArrayList<>();
        for (SearchHit<EsTestInfo> productSearchHit : search) {
            EsTestInfo pro = productSearchHit.getContent();
            //获取高亮的字段集合
            Map<String, List<String>> highlightFields = productSearchHit.getHighlightFields();
            //将高亮的内容填充到pro中
            pro.setName(highlightFields.get("name")==null ? pro.getName():highlightFields.get("name").get(0));
            pro.setDesc(highlightFields.get("desc")==null ? pro.getDesc():highlightFields.get("desc").get(0));
            System.out.println("pro = " + pro);
            list.add(pro);
        }
        res.setList(list);
        res.setTotal(search.getTotalHits());
        res.setPageIndex(query.getPageIndex());
        res.setPageSize(query.getPageSize());
        System.out.println("res = " + res);
    }

测试结果如下:

1047153-20221126214627263-595618425.png

这次更新的问题到此结束,后续遇到新的问题会继续补充......


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK