elasticsearch 的滚动(scroll)

Neil Zhu,简书ID Not_GOD,University AI 创始人 & Chief Scientist,致力于推进世界人工智能化进程。制定并实施 UAI 中长期增长战略和目标,带领团队快速成长为人工智能领域最专业的力量。
作为行业领导者,他和UAI一起在2014年创建了TASA(中国最早的人工智能社团), DL Center(深度学习知识中心全球价值网络),AI growth(行业智库培训)等,为中国的人工智能人才建设输送了大量的血液和养分。此外,他还参与或者举办过各类国际性的人工智能峰会和活动,产生了巨大的影响力,书写了60万字的人工智能精品技术内容,生产翻译了全球第一本深度学习入门书《神经网络与深度学习》,生产的内容被大量的专业垂直公众号和媒体转载与连载。曾经受邀为国内顶尖大学制定人工智能学习规划和教授人工智能前沿课程,均受学生和老师好评。

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_idscroll 可以放在查询字符串中传递。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 保持了哪些结果已经返回的记录,所以能更加高效地返回排序的结果。但是,按照默认设定排序结果仍然需要代价。

一般来说,你仅仅想要找到结果,不关心顺序。你可以通过组合 scrollscan 来关闭任何打分或者排序,以最高效的方式返回结果。你需要做的就是将 search_type=scan 加入到查询的字符串中:

curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m&search_type=scan' -d '
{
   "query": {
       "match" : {
           "title" : "elasticsearch"
       }
   }
}
'
  • 设置 search_typescan 可以关闭打分,让滚动更加高效。

扫描式的滚动请求和标准的滚动请求有四处不同:

  • 不算分,关闭排序。结果会按照在索引中出现的顺序返回。
  • 不支持聚合
  • 初始 search 请求的响应不会在 hits 数组中包含任何结果。第一批结果就会按照第一个 scroll 请求返回。
  • 参数 size 控制了每个分片上而非每个请求的结果数目,所以 size10 的情况下,如果命中了 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/_all

scroll_id 也可以使用一个查询字符串的参数或者在请求的body中传递。多个scroll ID 可以使用逗号分隔传入:

curl -XDELETE localhost:9200/_search/scroll \ -d 'c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1,aGVuRmV0Y2g7NTsxOnkxaDZ'
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容