简体   繁体   English

在后台重新编制索引时,应在何处放置重新编制索引的别名?

[英]Where to put index-re-aliasing when re-indexing in the background?

I try to re-index an ES index with Java: 我尝试用Java重新索引ES索引:

// reindex all documents from the old into the new index
QueryBuilder qb = QueryBuilders.matchAllQuery();
SearchResponse scrollResp = client.prepareSearch("my_index").setSearchType(SearchType.SCAN).setScroll(new TimeValue(600000)).setQuery(qb).setSize(100).execute().actionGet();
while (true) {
    scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet();

    final int documentFoundCount = scrollResp.getHits().getHits().length;

    // Break condition: No hits are returned
    if (documentFoundCount == 0) {
        break;
    }

    // otherwise add all documents which are found (in this scroll-search) to a bulk operation for reindexing.
    logger.info("Found {} documents in the scroll search, re-indexing them via bulk now.", documentFoundCount);
    BulkRequestBuilder bulk = client.prepareBulk();
    for (SearchHit hit : scrollResp.getHits()) {
        bulk.add(new IndexRequest(newIndexName, hit.getType()).source(hit.getSource()));
    }

    bulk.execute(new ActionListener<BulkResponse>() {
        @Override public void onResponse(BulkResponse bulkItemResponses) {
            logger.info("Reindexed {} documents from '{}' to '{}'.", bulkItemResponses.getItems().length, currentIndexName, newIndexName);
        }

        @Override public void onFailure(Throwable e) {
            logger.error("Could not complete the index re-aliasing.", e);
        }
    });
}

// these following lines should only be executed if the re-indexing was successful for _all_ documents.
logger.info("Finished re-indexing all documents, now setting the aliases from the old to the new index.");
try {
    client.admin().indices().aliases(new IndicesAliasesRequest().removeAlias(currentIndexName, "my_index").addAlias("my_index", newIndexName)).get();
    // finally, delete the old index
    client.admin().indices().delete(new DeleteIndexRequest(currentIndexName)).actionGet();
} catch (InterruptedException | ExecutionException e) {
    logger.error("Could not complete the index re-aliasing.", e);
}

In general, this works, but the approach has one problem: 通常,这可行,但是该方法存在一个问题:

If there is a failure during re-indexing, eg it takes too long and is stopped by some transaction watch (it runs during EJB startup), the alias is re-set and the old index is nevertheless removed. 如果在重新索引期间发生故障,例如,花费的时间太长并且被某些事务监视阻止(它在EJB启动期间运行),则将重设别名并删除旧索引。

How can I do that alias-re-setting if and only if all bulk requests were successful? 当且仅当所有批量请求均成功时,如何才能重新设置别名?

You're not waiting until the bulk request finishes. 您无需等待批量请求完成。 If you call execute() without actionGet(), you end up running asynchronously. 如果不带actionGet()调用execute(),则最终将异步运行。 Which means you will start changing aliases and deleting indexes before the new index is completely built. 这意味着您将在完全构建新索引之前开始更改别名并删除索引。

Also: 也:

client.admin().indices().aliases(new IndicesAliasesRequest().removeAlias(currentIndexName, "my_index").addAlias("my_index", newIndexName)).get();

This should be ended with execute().actionGet() and not get(). 这应该以execute()。actionGet()而不是get()结尾。 that is probably why your alias is not getting set 这可能就是为什么未设置别名的原因

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM