【Elasticsearch】一次响应缓慢的情况解决过程

调用es接口等待时间过长

查询es集群状态:curl -XGET http://192.168.0.12:9200/_cluster/health?pretty   
发现集群状态为red  "status" : "red"
查看每个索引的状态:curl -XGET http://192.168.0.12:9200/_cat/indices?v  
发现有许多之前安装X-Pack时候自带的无用索引(X-Pack是kibana开启系统监控必须集成的组件,用了一段时间后面过期了需要证书,就把X-Pack给下了)
删除无用索引(带通配符):curl -XDELETE "http://192.168.0.12:9200/.monitoring-*"
查看所以索引分配方式:curl -s "http://192.168.0.12:9200/_cat/shards" 
过滤查看所有未分配索引的方式:curl -s "http://192.168.0.12:9200/_cat/shards" | grep UNASSIGNED
发现有3个索引的状态是UNASSIGNED(每个索引原先4个primary,但是集群仅有3个节点,有一个主分片没有被分配)
自动分配分片(没试成功):curl -XPOST http://192.168.0.12:9200/_cluster/reroute?retry_failed  
手动移动分片(没试成功):

curl -XPOST 'http://192.168.0.12:9200/_cluster/reroute?pretty' -d '

{

    "commands" : [ {

        "allocate_stale_primary" : {

            "index" : "imei",

            "shard" :0,

            "node" : "hadoop2",

            "accept_data_loss" : true

        }

    }]

}'

想尝试动态修改分片数量(痴心妄想,只能动态修改副本数):curl -XPUT 'http://192.168.0.12:9200/users/_settings' -d '{"number_of_shards": 3}'
没法之后尝试重建索引,将分片数量设为3,感觉用命令太麻烦了,直接上java方法比较方便:

 /*索引重建迁移大法*/
    private static void indexMigration() throws UnknownHostException {
        String node = "192.168.0.12";
        int port = 9300;
        String cn = "my-application";
​
        Settings settings = Settings.builder()
                .put("cluster.name", cn)//设置ES实例的名称
                .put("client.transport.sniff", true)// 自动嗅探发现集群节点
                .build();
​
        TransportClient client = new PreBuiltTransportClient(settings);
        client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(node), port));
        log.info("初始化客户端成功");
​
​
        List<Map<String, Object>> addList = new ArrayList<>();
        //指定一个index和type
        SearchRequestBuilder search = client.prepareSearch("users2").setTypes("type");
        //使用原生排序优化性能
        //search.addSort("_doc", SortOrder.ASC);
        search.addSort("_doc", SortOrder.ASC);
        //设置每批读取的数据量
        search.setSize(100);
        //默认是查询所有
        search.setQuery(QueryBuilders.queryStringQuery("*:*"));
        //设置 search context 维护1分钟的有效期
        search.setScroll(TimeValue.timeValueMinutes(1));
        //获得首次的查询结果
        SearchResponse scrollResp = search.get();
        //打印命中数量、
        log.info("命中总数量:" + scrollResp.getHits().getTotalHits());
        int count = 1;
        do {
            log.info("第" + count + "次打印数据:");
            for (SearchHit hit : scrollResp.getHits().getHits()) {
                addList.add(hit.getSource());
            }
            count++;
            //将scorllId循环传递
            scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(TimeValue.timeValueMinutes(1)).execute().actionGet();
​
        } while (scrollResp.getHits().
​
                getHits().length != 0);
        //当searchHits的数组为空的时候结束循环,至此数据全部读取完毕
        BulkRequestBuilder bulkRequest = client.prepareBulk();
        for (
                int i = 0; i < addList.size(); i++)
​
        {
            bulkRequest.add(client.prepareIndex("users", "type").setSource(addList.get(i)));
            // 每1000条提交一次
            if (i % 1000 == 0) {
                bulkRequest.execute().actionGet();
                bulkRequest = client.prepareBulk();
            }
        }
        bulkRequest.execute().
​
                actionGet();
    }
​
​
    public static void main(String[] args) throws UnknownHostException {
        indexMigration();
    }

最后通过新建合适的索引,把原先的数据迁移过来,再重构旧索引,将数据导入回去后,集群状态恢复正常。

测试api的时候发现这样做的话貌似_id被系统设为自动生成(起初将某些字段同样给_id赋值,本来是想省一个字段,但是留个心眼在结构里都把字段写上了),不过还好当时所有有需要的字段都预留下来了,修改一下方法里查询的字段名即可。

重新测试调用api,稳妥的一匹

挺好的shard问题解决方案:

How to Resolve Unassigned Shards in Elasticsearch | Datadog

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我的浪漫与极端

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

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

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

打赏作者

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

抵扣说明:

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

余额充值