V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
byte10
V2EX  ›  程序员

ES 查询的 scroll_id 不会变,我真的服了。。

  •  
  •   byte10 · 231 天前 · 349 次点击
    这是一个创建于 231 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    今天做 codereview 发现以下的代码是有问题的,然后我解释说明这部分代码是有问题的,但是他坚持说没问题,生产也没问题。所以我就怀疑是数据量小,所以根本没有翻页,或者翻页一次就结束了。

    然后我就在本地进行调试,最后发现 scrollId 不会变的,后面换了 60w 的数据继续测试,也不会改变,我真顶你的个肺。

    测试代码:

    // 第一次查询
    SearchScrollHits<Book> searchHits = elasticsearchRestTemplate.searchScrollStart(6000, nativeSearchQuery, Book.class, IndexCoordinates.of("book"));
    String scrollId = searchScrollHits.getScrollId();
    while (searchHits.hasSearchHits()) {
        for (SearchHit<Book> searchHit : searchHits.getSearchHits()) {
            this.execute(searchHit.getContent());
        }
        // 后续查询
        searchHits = elasticsearchRestTemplate.searchScrollContinue(scrollId, 6000, Book.class, IndexCoordinates.of("book"));
        // 他的代码不存在这行的 scrollId = searchHits.getScrollId();
    }
    

    因为 scrollId 在非分片的情况下是不会变的,所以即使不用 scrollId = searchHits.getScrollId(); 它也能正常跑,我也是醉了。。。这 tmd 瞎猫碰上死老鼠。

    没啥好说的,他代码确实可以跑,ES 也没有用到分片,所以结果也是对的,领导也没说啥😂。

    网上的答案

    scrollid 可能不变,scroll 得到的 doc 是会变的。

    scrollid 保留的是 shard 信息,假如 scroll 查询语句需要路由到 100 个 shard 上查。 scrollid 会比较长,记录这 100 个 shard 。有可能从开始到完成都需要路由到这 100 个 shard ,shardid 都不会变化😒,也有可能随着不断进行 scroll ,需要路由到的 shard 越来越少,shardId 也会越来越短。

    那么如果 shardid 不变,es 如何每次拿到不同的数据呢?通过 lastEmittedDoc 保留每个 shard 上应取数据在优先队列中的位置信息,并在 fetch 阶段更新 lastEmittedDoc(因为经过全局排序之后,在 fetch 阶段才能确定在不同 shard 上面取多少条数据)。

    BTW

    虽然我打赌输了,但是我还是不认为那个代码是对的,即使代码是可以正常跑,运行结果也是对的。当然我也不会去改,爱咋滴咋滴,能跑就行。我是坚持不了,尊重他人的思想和认知。

    如果是你们会怎么处理呢😂。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3402 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 11:49 · PVG 19:49 · LAX 04:49 · JFK 07:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.