Elasticsearch Point in time查詢
Point in time API
默認(rèn)情況下,搜索請求針對目標(biāo)索引的最新可見數(shù)據(jù)執(zhí)行,這稱為時(shí)間點(diǎn)。 Elasticsearch pit(時(shí)間點(diǎn))是一個(gè)輕量級(jí)的視圖,可以查看數(shù)據(jù)在啟動(dòng)時(shí)的狀態(tài)。 在某些情況下,最好使用同一時(shí)間點(diǎn)執(zhí)行多個(gè)搜索請求。 例如,如果在 search_after 請求之間發(fā)生刷新,則這些請求的結(jié)果可能不一致,因?yàn)樗阉髦g發(fā)生的更改僅在最近的時(shí)間點(diǎn)可見。
先決條件
如果啟用了 Elasticsearch 安全特性,你必須具有目標(biāo)數(shù)據(jù)流、索引或別名的讀取索引權(quán)限。要在某個(gè)時(shí)間點(diǎn) (PIT) 中搜索別名,你必須具有該別名的數(shù)據(jù)流或索引的讀取索引權(quán)限。
下面,我們將以一些例子來展示如何使用 PIT 來進(jìn)行搜索。我們首先來導(dǎo)入我們的索引:
POST _bulk
{ "index" : { "_index" : "twitter", "_id": 1} }
{"user":"雙榆樹-張三","message":"今兒天氣不錯(cuò)啊,出去轉(zhuǎn)轉(zhuǎn)去","uid":2,"age":20,"city":"北京","province":"北京","country":"中國","address":"中國北京市海淀區(qū)","location":{"lat":"39.970718","lon":"116.325747"}}
{ "index" : { "_index" : "twitter", "_id": 2 }}
{"user":"東城區(qū)-老劉","message":"出發(fā),下一站云南!","uid":3,"age":30,"city":"北京","province":"北京","country":"中國","address":"中國北京市東城區(qū)臺(tái)基廠三條3號(hào)","location":{"lat":"39.904313","lon":"116.412754"}}
{ "index" : { "_index" : "twitter", "_id": 3} }
{"user":"東城區(qū)-李四","message":"happy birthday!","uid":4,"age":30,"city":"北京","province":"北京","country":"中國","address":"中國北京市東城區(qū)","location":{"lat":"39.893801","lon":"116.408986"}}
{ "index" : { "_index" : "twitter", "_id": 4} }
{"user":"朝陽區(qū)-老賈","message":"123,gogogo","uid":5,"age":35,"city":"北京","province":"北京","country":"中國","address":"中國北京市朝陽區(qū)建國門","location":{"lat":"39.718256","lon":"116.367910"}}
{ "index" : { "_index" : "twitter", "_id": 5} }
{"user":"朝陽區(qū)-老王","message":"Happy BirthDay My Friend!","uid":6,"age":50,"city":"北京","province":"北京","country":"中國","address":"中國北京市朝陽區(qū)國貿(mào)","location":{"lat":"39.918256","lon":"116.467910"}}
{ "index" : { "_index" : "twitter", "_id": 6} }
{"user":"虹橋-老吳","message":"好友來了都今天我生日,好友來了,什么 birthday happy 就成!","uid":7,"age":90,"city":"上海","province":"上海","country":"中國","address":"中國上海市閔行區(qū)","location":{"lat":"31.175927","lon":"121.383328"}}
我們使用上面的 bulk 命令導(dǎo)入6個(gè)數(shù)據(jù)。它將創(chuàng)建一個(gè)叫做 twitter 的索引。
在搜索請求中使用之前,必須明確打開時(shí)間點(diǎn)。 keep_alive 參數(shù)告訴 Elasticsearch 它應(yīng)該保持一個(gè)時(shí)間點(diǎn)存活多久,例如 ?keep_alive=5m。
ini復(fù)制代碼POST /twitter/_pit?keep_alive=2m
上面的命令將返回如下的結(jié)果:
{
"id" : "g-azAwEHdHdpdHRlchZIck44aVdSNlFMNnEyTmVMUGJEVm9RABZxNnpoTVIxQVFIeTRkci1MSGlibU9BAAAAAAAAARtiFldSS2x2LVZJUU5xajU1ZkxCN2dyMUEAARZIck44aVdSNlFMNnEyTmVMUGJEVm9RAAA="
}
接下來,我們可以使用如下的命令來對我們的索引進(jìn)行搜索:
GET _search
{
"query": {
"match": {
"city": "北京"
}
},
"pit": {
"id" : "g-azAwEHdHdpdHRlchZIck44aVdSNlFMNnEyTmVMUGJEVm9RABZxNnpoTVIxQVFIeTRkci1MSGlibU9BAAAAAAAAARtiFldSS2x2LVZJUU5xajU1ZkxCN2dyMUEAARZIck44aVdSNlFMNnEyTmVMUGJEVm9RAAA=",
"keep_alive": "2m"
}
}
在使用上面的搜索時(shí)必須注意的一點(diǎn)是:我們不能使用如下的格式:
bash復(fù)制代碼GET /twitter/_search
也就是說,我們不能使用索引名作為請求的一部分。我們必須注意一下的幾個(gè)方面:
帶有 pit 參數(shù)的搜索請求不得指定 index、routing 和 preference,因?yàn)檫@些參數(shù)是從時(shí)間點(diǎn)復(fù)制的。
id 參數(shù)告訴 Elasticsearch 從這個(gè)時(shí)間點(diǎn)使用上下文執(zhí)行請求。
keep_alive 參數(shù)告訴 Elasticsearch 應(yīng)該將時(shí)間點(diǎn)的生存時(shí)間延長多長時(shí)間。
在上面,我們設(shè)置 keep_alive 為2分鐘。當(dāng)我們在2分鐘后再執(zhí)行上面的搜索時(shí),我們可以看到如下的錯(cuò)誤信息:
{
"error" : {
"root_cause" : [
{
"type" : "search_context_missing_exception",
"reason" : "No search context found for id [72546]"
}
],
"type" : "search_phase_execution_exception",
"reason" : "all shards failed",
"phase" : "query",
"grouped" : true,
"failed_shards" : [
{
"shard" : 0,
"index" : "twitter",
"node" : "q6zhMR1AQHy4dr-LHibmOA",
"reason" : {
"type" : "search_context_missing_exception",
"reason" : "No search context found for id [72546]"
}
}
]
},
"status" : 404
}
重要:開放時(shí)間點(diǎn)請求和后續(xù)的每個(gè)搜索請求可以返回不同的 id; 因此對于下一個(gè)搜索請求總是使用最近收到的 id。
我們接下來做另外一個(gè)實(shí)驗(yàn)。我們首先再次運(yùn)行如下的命令:
POST /twitter/_pit?keep_alive=2m
運(yùn)行完后,我們得到一個(gè)不一樣的 id,盡管這個(gè)新的 id 和上次返回的值長的非常像。
我們使用最新的 id 來做如下的查詢:
GET _search
{
"query": {
"match": {
"city": "北京"
}
},
"pit": {
"id" : "g-azAwEHdHdpdHRlchZIck44aVdSNlFMNnEyTmVMUGJEVm9RABZxNnpoTVIxQVFIeTRkci1MSGlibU9BAAAAAAAAAR8tFldSS2x2LVZJUU5xajU1ZkxCN2dyMUEAARZIck44aVdSNlFMNnEyTmVMUGJEVm9RAAA=",
"keep_alive": "2m"
}
}
我們可以看到有5個(gè)這樣的文檔:
我們接下來,使用如下的命令來添加一個(gè)新的文檔:
PUT twitter/_doc/7
{
"user": "張三",
"message": "今天天氣真好",
"uid": 8,
"age": 35,
"city": "北京",
"province": "北京",
"country": "中國",
"address": "中國北京市朝陽區(qū)",
"location": {
"lat": "31.175927",
"lon": "121.383328"
}
}
請注意這個(gè)文檔的 city 字段也是 “北京”,那么在新增加一個(gè)文檔后,再次來做如下的查詢:
GET _search
{
"query": {
"match": {
"city": "北京"
}
},
"pit": {
"id" : "g-azAwEHdHdpdHRlchZIck44aVdSNlFMNnEyTmVMUGJEVm9RABZxNnpoTVIxQVFIeTRkci1MSGlibU9BAAAAAAAAAR8tFldSS2x2LVZJUU5xajU1ZkxCN2dyMUEAARZIck44aVdSNlFMNnEyTmVMUGJEVm9RAAA=",
"keep_alive": "2m"
}
}
我們可以看到和之前一模一樣的結(jié)果,還是5個(gè)文檔。
然后,當(dāng)我們做如下的查詢:
GET /twitter/_search
{
"query": {
"match": {
"city": "北京"
}
}
}
我們可以清楚地看到有6個(gè)文檔的 city 是 “北京”
這到底是怎么回事呢?究其原因就是當(dāng)我們查詢時(shí)使用 pit 參數(shù)時(shí),它只能查詢在那個(gè)時(shí)間點(diǎn)之前的所有文檔,而后面新增加的文檔不能被查詢到。這個(gè)在實(shí)際的很多應(yīng)用中非常有用。比如針對一個(gè)快速變化的索引來說,我們想對它進(jìn)行表格化,我們不希望在我們進(jìn)行分頁時(shí)每次得到的數(shù)據(jù)集是不同的。
保持時(shí)間點(diǎn)活著
傳遞給開放時(shí)間點(diǎn)請求和搜索請求的 keep_alive 參數(shù)延長了相應(yīng)時(shí)間點(diǎn)的生存時(shí)間。 該值(例如 1m,參見時(shí)間單位)不需要足夠長來處理所有數(shù)據(jù) — 它只需要足夠長以用于下一個(gè)請求。
通常,后臺(tái)合并過程通過將較小的段合并在一起以創(chuàng)建新的更大的段來優(yōu)化索引。 一旦不再需要較小的段,它們就會(huì)被刪除。 但是,開放時(shí)間點(diǎn)會(huì)阻止刪除舊段,因?yàn)樗鼈內(nèi)栽谑褂弥小?/p>
提示:保持舊段(segment)處于活動(dòng)狀態(tài)意味著需要更多的磁盤空間和文件句柄。 確保你已將節(jié)點(diǎn)配置為具有充足的空閑文件句柄。 請參閱文件描述符。
此外,如果一個(gè)段(segment)包含已刪除或更新的文檔,那么該時(shí)間點(diǎn)必須跟蹤該段中的每個(gè)文檔在初始搜索請求時(shí)是否處于活動(dòng)狀態(tài)。 如果索引上有許多打開的時(shí)間點(diǎn),并且會(huì)受到持續(xù)刪除或更新的影響,請確保你的節(jié)點(diǎn)有足夠的堆空間。
你可以使用節(jié)點(diǎn)統(tǒng)計(jì) API 檢查有多少時(shí)間點(diǎn)(即搜索上下文)打開:
sql復(fù)制代碼GET /_nodes/stats/indices/search
關(guān)閉時(shí)間點(diǎn) API
時(shí)間點(diǎn)在其 keep_alive 結(jié)束后自動(dòng)關(guān)閉。 然而,保持時(shí)間點(diǎn)是有代價(jià)的,如上一節(jié)所述。 一旦不再用于搜索請求,就應(yīng)關(guān)閉時(shí)間點(diǎn)。我們可以通過如下的命令來對它進(jìn)行關(guān)閉:
DELETE /_pit
{
"id" : "g-azAwEHdHdpdHRlchZIck44aVdSNlFMNnEyTmVMUGJEVm9RABZxNnpoTVIxQVFIeTRkci1MSGlibU9BAAAAAAAAASLCFldSS2x2LVZJUU5xajU1ZkxCN2dyMUEAARZIck44aVdSNlFMNnEyTmVMUGJEVm9RAAA="
}
如果該 id 還是 alive 的狀態(tài),那么它將返回:
json復(fù)制代碼
{
"succeeded" : true,
"num_freed" : 1
}
在上面,如果返回 true,則與時(shí)間點(diǎn) ID 關(guān)聯(lián)的所有搜索上下文都將成功關(guān)閉。num_freed 表示多少個(gè)搜索上下文數(shù)量已成功關(guān)閉。文章來源:http://www.zghlxwxcb.cn/news/detail-826132.html
參考
作者:Elasticsearch
鏈接:https://juejin.cn/post/7002757814963666980
來源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。文章來源地址http://www.zghlxwxcb.cn/news/detail-826132.html
到了這里,關(guān)于Elasticsearch Point in time查詢的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!