ElasticSearch缓慢检索文档

时间:2019-07-11 13:55:30

标签: java performance elasticsearch bigdata java-api

我正在使用Java_API从ElasticSearch检索记录,在Java应用程序中检索100000文档(记录/行)大约需要5秒。

ElasticSearch慢吗?还是正常?

这是索引设置:

enter image description here

我试图获得更好的性能,但是没有结果,这就是我所做的:

  • 将ElasticSearch堆空间设置为3GB,原为1GB(默认)-Xms3g -Xmx3g

  • 从7200 RPM硬盘迁移SSD上的ElasticSearch

  • 仅检索一个归档文件,而不是30个

这是我的Java实现代码

private void getDocuments() {
        int counter = 1;
        try {
            lgg.info("started");
            TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
                    .addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9300));

            SearchResponse scrollResp = client.prepareSearch("ebpp_payments_union").setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                    .setQuery(QueryBuilders.matchAllQuery())                 
                    .setScroll(new TimeValue(1000))
                    .setFetchSource(new String[] { "payment_id" }, null)
                    .setSize(10000)
                    .get();

            do {
                for (SearchHit hit : scrollResp.getHits().getHits()) {
                    if (counter % 100000 == 0) {
                        lgg.info(counter + "--" + hit.getSourceAsString());
                    }
                    counter++;
                }

                scrollResp = client.prepareSearchScroll(scrollResp.getScrollId())
                        .setScroll(new TimeValue(60000))
                        .execute()
                        .actionGet();
            } while (scrollResp.getHits().getHits().length != 0);

            client.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
  

我知道TransportClient已过时,我尝试过   也RestHighLevelClient,但它不会改变任何内容。

您知道如何获得更好的性能吗?

我应该在ElasticSearch中更改某些内容还是修改我的Java代码?

2 个答案:

答案 0 :(得分:1)

在不了解所有涉及的内容的情况下,很难进行性能故障排除/调整,但这似乎并不很快。由于这是一个单节点群集,因此您将遇到一些性能问题。如果这是一个生产集群,则每个分片至少有一个副本,也可以用于读取。

您还可以做一些其他事情:

  • 根据您最常搜索的属性为您的文档编制索引-这会将具有相同属性的所有文档写入同一分片,因此ES的读取工作量会减少(由于您只有一个分片,因此对您没有帮助)< / li>
  • 添加多个副本分片,以便您可以在集群中的各个节点之间展开读取(再次,需要实际拥有集群)
  • 在数据的同一框上没有主角色-如果您有中等或大型集群,则应该是既不是主框又不是数据的框,但应用程序可以连接的框以便他们可以管理搜索的元工作,并使数据节点专注于数据。
  • 使用“ query_then_fetch”-除非您使用加权搜索,否则您应该坚持使用DFS。

答案 1 :(得分:1)

我看到了三个可能的优化轴:

1 /通过_doc键对文档进行排序:

  

滚动请求具有优化功能,可以使排序时更快   订单是_doc。如果要遍历所有文档,无论   订单,这是最有效的选择:

documentation source

2 /缩小页面大小,10000似乎是一个很高的值。您可以使用降低的值(例如5000/1000)进行差异测试吗?

3 /删除源过滤

  

.setFetchSource(new String [] {“ payment_id”},空)

进行源过滤可能很麻烦,因为弹性节点需要读取源,先转换为Object然后过滤。那么您可以尝试删除它吗?网络负载将增加,但是这是一个交易:)