BulkCreate方法为什么需要进行sleep才能写入
来源:6-7 Go操作ES的一些技巧和注意事项 (二)

404_
2023-02-03
for i := 0; i < 500; i++ {
docID := strconv.Itoa(i)
//update := map[string]interface{}{"name": "xxx"}
doc := Goods{
Id: int64(i),
Name: "name" + docID,
Price: float64(i),
Year: 2022,
LastMonthSales: i,
Favorites: i,
}
esClient.BulkCreate(IndexName, docID, docID, doc)
}
//因为是异步处理,这里需要等待本地channel提交
//time.Sleep(3 * time.Second)
这一块代码为什么需要sleep?难道不能自动提交吗?我们直接将数据扔给ES它自己提交不行吗?
但是client.Bulk()最后在调用Do方法 这种方式就可以,也不用进行sleep阻塞。
写回答
1回答
-
少林码僧
2023-02-03
bulk提交是需要在请求体中放多个文档的,比如我们通过官方api可以这样进行bulk提交
POST _bulk { "index" : { "_index" : "test", "_id" : "1" } } { "field1" : "value1" } { "delete" : { "_index" : "test", "_id" : "2" } } { "create" : { "_index" : "test", "_id" : "3" } } { "field1" : "value3" } { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }
但是如果你只给一个文档就提交,虽然使用的是Bulk方式写入,ES收到请求后还是以请求为单位进行写入的,
这样就失去了批量写入的意义。
Bulk写入的目的就在于一次提交多个文档,减少ES的IO操作大幅提升ES的吞吐性能。
所以 go的sdk(也就是客户端)就提供了这种合并的能力,我们将一条条的文档丢给sdk,sdk将这些文档先放到channel中,然后根据我们设置的三个维度的条件(时间,大小和文档数)进行提交。
这里的提交其实就是定期调用Do方法,其实本质是在go的sdk完成对多次请求的打包,再通过一次Bulk请求提交给ES。
所以在调用BulkCreate时,我们只是将请求丢给go的channel而已,并没有立马提交Bulk请求到ES。
课程中也提供了两个方法,如果业务中本身就是一批批的写入可以调用我们封装的BulkCreateDocs() 方法,拿到实时的写入状态。
如果是单条文档写入想提升性能就可以调用BulkCreate()让SDK帮你做打包提交
212023-02-08
相似问题