elasticsearch 的滚动(scroll)
Scroll
search 請求返回一個單一的結果“頁”,而 scroll API 可以被用來檢索大量的結果(甚至所有的結果),就像在傳統數據庫中使用的游標 cursor。
滾動并不是為了實時的用戶響應,而是為了處理大量的數據,例如,為了使用不同的配置來重新索引一個 index 到另一個 index 中去。
client 支持:Perl 和 Python
注意:從 scroll 請求返回的結果反映了 search 發生時刻的索引狀態,就像一個快照。后續的對文檔的改動(索引、更新或者刪除)都只會影響后面的搜索請求。
為了使用 scroll,初始搜索請求應該在查詢中指定 scroll 參數,這可以告訴 Elasticsearch 需要保持搜索的上下文環境多久(參考Keeping the search context alive),如 ?scroll=1m。
curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m' -d ' {"query": {"match" : {"title" : "elasticsearch"}} } '使用上面的請求返回的結果中包含一個 scroll_id,這個 ID 可以被傳遞給 scroll API 來檢索下一個批次的結果。
curl -XGET 'localhost:9200/_search/scroll' -d' {"scroll" : "1m", "scroll_id" : "c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1" } '- GET 或者 POST 可以使用
- URL不應該包含 index 或者 type 名字——這些都指定在了原始的 search 請求中。
- scroll 參數告訴 Elasticsearch 保持搜索的上下文等待另一個 1m
- scroll_id 參數
每次對 scroll API 的調用返回了結果的下一個批次知道沒有更多的結果返回,也就是直到 hits 數組空了。
為了向前兼容,scroll_id 和 scroll 可以放在查詢字符串中傳遞。scroll_id 則可以在請求體中傳遞。
curl -XGET 'localhost:9200/_search/scroll?scroll=1m' -d 'c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1'注意:初始搜索請求和每個后續滾動請求返回一個新的 _scroll_id——只有最近的 _scroll_id 才能被使用。
如果請求指定了聚合(aggregation),僅僅初始搜索響應才會包含聚合結果。
使用 scroll-scan 的高效滾動
使用 from and size 的深度分頁,比如說 ?size=10&from=10000 是非常低效的,因為 100,000 排序的結果必須從每個分片上取出并重新排序最后返回 10 條。這個過程需要對每個請求頁重復。
scroll API 保持了哪些結果已經返回的記錄,所以能更加高效地返回排序的結果。但是,按照默認設定排序結果仍然需要代價。
一般來說,你僅僅想要找到結果,不關心順序。你可以通過組合 scroll 和 scan 來關閉任何打分或者排序,以最高效的方式返回結果。你需要做的就是將 search_type=scan 加入到查詢的字符串中:
curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m&search_type=scan' -d ' {"query": {"match" : {"title" : "elasticsearch"}} } '- 設置 search_type 為 scan 可以關閉打分,讓滾動更加高效。
掃描式的滾動請求和標準的滾動請求有四處不同:
- 不算分,關閉排序。結果會按照在索引中出現的順序返回。
- 不支持聚合
- 初始 search 請求的響應不會在 hits 數組中包含任何結果。第一批結果就會按照第一個 scroll 請求返回。
- 參數 size 控制了每個分片上而非每個請求的結果數目,所以 size 為 10 的情況下,如果命中了 5 個分片,那么每個 scroll 請求最多會返回 50 個結果。
如果你想支持打分,即使不進行排序,將 track_scores 設置為 true。
保持搜索上下文存活
參數 scroll (傳遞給 search 請求還有每個 scroll 請求)告訴 Elasticsearch 應該需要保持搜索上下文多久。這個值(比如說 1m,詳情請見the section called “Time units)并不需要長到可以處理所有的數據——僅僅需要足夠長來處理前一批次的結果。每個 scroll 請求(包含 scroll 參數)設置了一個新的失效時間。
一般來說,背后的合并過程通過合并更小的分段創建更大的分段來優化索引,同時會刪除更小的分段。這個過程在滾動時進行,但是一個打開狀態的搜索上下文阻止了舊分段在使用的時候不會被刪除。這就是 Elasticsearch 能夠不管后續的文檔的變化,返回初始搜索請求的結果的原因。
保持舊的分段存活意味著會產生更多的文件句柄。確保你配置了節點有空閑的文件句柄。參考File Descriptors
你可以檢查有多少搜索上下文開啟了,
curl -XGET localhost:9200/_nodes/stats/indices/search?pretty清除 scroll API
搜索上下文當 scroll 超時就會自動移除。但是保持 scroll 存活需要代價,如在前一節講的那樣,所以 scrolls 當scroll不再被使用的時候需要被用 clear-scroll 顯式地清除:
curl -XDELETE localhost:9200/_search/scroll -d ' { "scroll_id" : ["c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1"] }'2.0.0-beta1 中加入。基于請求體的參數在 2.0.0 中加入。
多個 scroll ID 可按照數據傳入:
curl -XDELETE localhost:9200/_search/scroll -d ' { "scroll_id" : ["c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1", "aGVuRmV0Y2g7NTsxOnkxaDZ"] }'2.0.0 中加入。
所有搜索上下文可以通過 _all 參數而清除:
curl -XDELETE localhost:9200/_search/scroll/_allscroll_id 也可以使用一個查詢字符串的參數或者在請求的body中傳遞。多個scroll ID 可以使用逗號分隔傳入:
curl -XDELETE localhost:9200/_search/scroll \ -d 'c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1,aGVuRmV0Y2g7NTsxOnkxaDZ'轉載鏈接:https://www.jianshu.com/p/14aa8b09c789
總結
以上是生活随笔為你收集整理的elasticsearch 的滚动(scroll)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring几种获取 HttpServl
- 下一篇: 集合同步