文档章节

elasticsearch 源代码分析之ScanScroll

纳兰琴
 纳兰琴
发布于 2014/10/27 16:57
字数 909
阅读 488
收藏 1

ScanScroll 的特点

  1. 优点

    1. 速度快

    2. 大数据量

  2. 缺点

    1. 不支持排序

    2. 不支持分页

    3. 不支持评分

    4. 不支持续查


使用场景

        看起来,缺点要比优点多很多,不过它很有用。如果说BULK是为了快速入库存在的,那SCAN就是为了快速出库而诞生的。ES的查询性能优越,但是分析能力弱。所以会有,比如把ES的数据拉到Hadoop集群去分析计算的需求,当然这个已经有现成的插件了,不出所料也是用的SCAN。如果SCAN遭遇BULK, 也就是ES到ES的话,它有另一个更熟悉的名字叫 复制表。

使用方法

def scanTest():
    searchRes = es.search(index="users",size=10,body={"query": {"match_all": {}}},search_type="scan",scroll="10s")
    while True:
        scrollRes=es.scroll(scroll_id=searchRes["_scroll_id"],scroll="10s",ignore=[400, 404])
        res_list = scrollRes["hits"]["hits"]
        if not len(res_list):
            break;
        for res in res_list:
            print res["_source"]["userName"]

原理流程

        整个流程比较清晰,先count一个总数,下面每次scroll,返回size*分片数的数据,直到遍历全部。SCAN是支持查询偏好preference的,可以指定分片,所以有人说的size*主分片数,是不准确的,这个很容易验证。

  • 第一阶段:Search

    • 用TotalHitCountCollector统计下总数,并且确定(节点,查询上下文ID),Base64编码成ScrollId返回

  • 第二阶段:SearchScroll

    • 根据ScrollId去每个节点,找到查询上下文ID执行XFilteredQuery,收集结果,合并返回


        第一阶段除了返回总数,还有一个很神秘的ScrollId,这个ScrollId长成这样,很像Base64编码过的。一定不是ID那么简单,了解一番,果不其然 ,主要有3个部分组成type,context,attributes

      1. type 分别是queryThenFetch,queryAndFetch,scan,我们这里讲的是scan

      2. attributes 只有一个元素,total_hits

      3. context 是个分片的元组,有2个元素,分片 = [节点ID,查询上下文ID]

        ScrollId 是个很容易会暴露秘密的东西,我们会发现ScrollId 依赖的节点ID和查询上下文ID都是变量,查询上下文ID,每次请求都要递增的。所以每次请求的ScrollId 都不一样,导致了如果在我们的SCAN过程意外终止,我们可能需要重新来过。

        每次SCAN,处理Scroll跳到下一页去,我们自己指定form是无效的。

//SearchService
private void processScroll(InternalScrollSearchRequest request, SearchContext context) {
        // process scroll
        context.from(context.from() + context.size());
        context.scroll(request.scroll());
        // ...
 }

//ScanContext
public TopDocs execute(SearchContext context) throws IOException {
        ScanCollector collector = new ScanCollector(readerStates, context.from(), context.size(), context.trackScores());
        Query query = new XFilteredQuery(context.query(), new ScanFilter(readerStates, collector));
        try {
            context.searcher().search(query, collector);
        } catch (ScanCollector.StopCollectingException e) {
            // all is well
        }
        return collector.topDocs();
}

        自定义的Filter,Collector,执行搜索,收集那一页的结果集

 //ScanContext
 public void collect(int doc) throws IOException {
            if (counter >= from) {
                docs.add(new ScoreDoc(docBase + doc, trackScores ? scorer.score() : 0f));
            }
            readerState.count++;
            counter++;
            if (counter >= to) {
                throw StopCollectingException;
            }
}


        根据以往数据库的认识,count操作总是很慢的,这让我很担心会延长整个查询的时间,后来我发现这种担心是多余的,对于全文检索count操作是很快速的。根据测试,17亿数据24个分片,平均每个分片的count时间在200ms到700ms之间,最糟糕的情况下总数也能在1秒内返回,这对于整个查询时间而言是可以接受的。


未完待续。。。怎么处理偏好,怎么合并结果集,不在这里讲,在6大查询类型里讲。这里主要想讲清楚 ,SCAN的特点。写到这里我思绪断掉了,好像讲清楚了,又觉得落下什么了。

© 著作权归作者所有

纳兰琴
粉丝 51
博文 23
码字总数 13442
作品 0
杭州
高级程序员
私信 提问
Elastic 在年度用户大会 Elastic{ON} 2018 上发布众多新功能和技术预览

下载超过 2.25 亿次,Elastic 公开 X-Pack 源代码 旧金山 (Elastic{ON} 2018) – 2018 年 2 月 27 日 – Elastic,Elasticsearch 和 Elastic Stack背后的公司,今天宣布其产品累计下载次数达...

Medcl
2018/03/01
11
0
CentOS7.3下ELK日志分析系统集群搭建

Elasticsearch是个基于Lucene实现的开源、分布式、restful的全文本搜索引擎,此外他还是一个分布式实时文档存储,其中每个文档的每个filed均是可被索引的数据,且可被搜索,也是一个带实时分...

wujunqi1996
2018/07/14
0
0
基于Bro的应用层数据包识别工具

  拓扑介绍   应用识别系统将会通过bro识别应用并生成日志。ELK部署在远程端,用于收集,分析,存储和识别所有日志。BRO安装在IP为192.168.1.147的机器上,ELK安装在IP为192.168.1.142的...

FreeBuf
2018/08/13
0
0
centos 7( linux )下安装elasticsearch教程

目录 概述 环境准备 elaticsearch简介 安装elasticsearch 彩蛋 概述 很久没有写博客了,最近在做全文检索的项目,发现elasticsearch踩了不少坑,百度点进去又是坑,在此记录一下自己的踩坑历程。...

java_龙
2018/10/15
683
0
AWS 为 Elasticsearch 推出开源发行版

AWS 近日宣布为 Elasticsearch 推出开源发行版 Open Distro for Elasticsearch。 Elasticsearch 是一个分布式、面向文档的搜索和分析引擎,它支持结构化和非结构化查询,并且不需要提前定义模...

linux-tao
2019/03/27
54
0

没有更多内容

加载失败,请刷新页面

加载更多

MySQL-基于SELECT查询的UPDATE查询

我需要检查(从同一张表)基于日期时间的两个事件之间是否存在关联。 一组数据将包含某些事件的结束日期时间,另一组数据将包含其他事件的开始日期时间。 如果第一个事件在第二个事件之前完成...

javail
46分钟前
60
0
将PostgreSQL数据库复制到另一台服务器

我正在将生产PostgreSQL数据库复制到开发服务器。 什么是最快,最简单的方法? #1楼 pg_dump the_db_name > the_backup.sql 然后将备份复制到您的开发服务器,并使用以下命令进行还原: ps...

技术盛宴
今天
39
0
[译]软件架构师之路

今天给大家带来一篇自己翻译的干货《软件架构师之路》。本周Github上升很快的项目。其内容对致力于成为软件架构师(不论前后端)的同学应该都会有极大的帮助。 项目地址: 中文地址 https://...

gamedilong
今天
41
0
聊聊artemis的ExpiryScanner

序 本文主要研究一下artemis的ExpiryScanner startExpiryScanner activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl......

go4it
今天
51
0
MySQL概述

MySql主要概念 参考:https://snailclimb.gitee.io/javaguide/#/database/MySQL MySQL 是一种关系型数据库,在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展。阿里巴巴数...

Las_Vegas
今天
42
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部