简体   繁体   中英

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

I try to re-index an ES index with Java:

// 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.

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. 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(). that is probably why your alias is not getting set

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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