阻塞只读操作的索引,使 elasticsearch 处于不一致状态

Blocking an index for readonly operations, makes elasticsearch left in an inconsistent state

如果我必须对该索引进行重新索引处理,我想阻止该索引的写入操作。
这两个帖子(elasticsearch migrations with c and nest & NEST Elasticsearch Reindex examples) were very helpful, but as suggested by this third one,您可能会在此过程中丢失更新和删除。
我曾尝试使用 elasticsearch 中的设置阻止索引的写入操作,但我在尝试此操作时发现了一些问题。
我使用 Nest 的 UpdateSettings api 更改设置 blocks.read_onlyblocks.metadatablocks.readblocks.write

var client = CreateElasticClient(); // A wrapper method of ElasticClient()
var response = client.UpdateSettings(r => r
                    .Index(IndexName)
                    .BlockReadonly()
                    .BlocksMetadata()
                    .BlocksRead()
                    .BlocksWrite()
                    );

如果我将设置blocks.read_onlyblocks.metadatablocks.read设置为true(默认设置的值),那么索引将不接受写操作,但也接受读操作也不行,准确的说,我今天重装了3次elasticsearch,因为改了这些设置后就没法用了。
设置blocks.write为true不会有任何影响,我可以读取索引,但也可以写入它。
问题
所以,我的问题是,我应该怎么做(在重建索引时阻止索引的写入操作)?

随着数据的增长,重建索引可能会成为一个耗时的过程。即使有办法阻止写入,您打算如何重新应用丢失的写入? (如果它们是重新索引未捕获的新文档)

Elasticsearch 支持可用于此目的的别名。见 Aliases. As you rebuild the index you could still capture all the writes and still support read operations using these. Here is an useful link which details some of the approaches. Reindex options

我准备了简单的例子。也许它会阐明您的问题。

internal class Program
{
    private static void Main(string[] args)
    {
        var indexName = "indexname";
        var indexName2 = "indexname2";

        var uri = new Uri("http://localhost:9200");
        var settings = new ConnectionSettings(uri).SetDefaultIndex(indexName).EnableTrace();
        var client = new ElasticClient(settings);

        var indicesResponse = client.DeleteIndex(descriptor => descriptor.Index(indexName));
        var indicesResponse2 = client.DeleteIndex(descriptor => descriptor.Index(indexName2));

        client.CreateIndex(descriptor => descriptor.Index(indexName).AddMapping<Document>(m => m.MapFromAttributes()));

        client.Index(new Document {Id = 1});

        client.Refresh();

        var acknowledgedResponse = client.UpdateSettings(descriptor => descriptor.Index(indexName).BlocksWrite());

        var observable = client.Reindex<Document>(descriptor => descriptor.FromIndex(indexName).ToIndex(indexName2));
        observable.Subscribe(new ReindexObserver<Document>(response => Console.WriteLine(response.IsValid),
            Console.WriteLine, () => Console.WriteLine("Done")));

        var documentToAdd = new Document { Id = 2, Name = "new" };

        var indexResponse = client.Index(documentToAdd);

        //indexResponse -> can't index new document with message: blocked by: [FORBIDDEN/8/index write (api)];

        var getResponse = client.Get<Document>(descriptor => descriptor.Id(1));

        //getResponse -> still can read from index

        var acknowledgedResponse2 = client.UpdateSettings(descriptor => descriptor.Index(indexName).BlocksWrite(false));

        var indexResponse2 = client.Index(documentToAdd);

        //indexResponse2 -> now I can add new document to my index

        Console.ReadKey();
    }
}

public class Document
{
    public int Id { get; set; }
    public string Name { get; set; }
}