elasticsearch中基于id查询的优化

[TOC]

简介

最近在基于es的id查询时有个困惑,基于id的get查询和基于id的query查询查询速度是否一样;如果不一样又是因为什么不一样?带着这2个疑问我进行了一些分析,下面进行展示

2种查询压测对比

准备工作

下面进行实际压测对比

  • index:
    *种压测使用的index是同一个index,数据量为千万级别
  • 数据:
    使用的不同的id作为压测数据,避免有缓存造成结果不准确
  • 工具:
    使用wrk1 进行压测,wrk是一个现代化的压测工具,可以结合lua进行一些动态数据压测。

基于get id查询

基于get id的查询

wrk -t1 -c1 -d10s --scripts=get.lua --latency urlxxx

基于query id的查询

wrk -t1 -c1 -d10s --scripts=query.lua --latency urlxxx

结果说明

基于上面的实验结果可以看出,直接基于id的查询90%基准会比基于普通query查询效率高出2-3倍,我的第一个问题解决了。

为什么基于id的get请求会更快

上面的实验结果表明直接基于id的get查询效率更高,但是为什么会这样?这得从es底层的数据存储和查询过程说起,可能不同版本间有差异,说的不一定全对,还请各位看客海涵,如果有问题请提出。

es的数据存储

我们以一个例子先来讲讲es存储的几个概念 2

例如我们有一个user表它有四个字段:分别是name,gender,age,address。画出来的话,大概是下面这个样子,跟关系型数据库一样
数据描述

  • docid
    每个文档的唯一性标志
  • doc
    一条记录就是一个文档
  • term:
    一段文本经过分析器分析以后就会输出一串单词,这一个一个的就叫做Term(直译为:单词)
  • posting list
    维护的是哪些 docid出现在该term中
  • term dictionary
    将一列的所有的term进行排序后维护的一个词典就叫term dictionary,查询某个term的时候就可以进行二分法查询(logn复杂度,mysql的b-tree索引就是这一层,但是es还会把term dictionary利用fst 再建立一个 term index放到内存,索引查询会更快)
  • term index
    为了更快的找到某个单词,我们为term dictionary建立索引
    例如上面的name 列表维护的一个term dictionary就是
    在这里插入图片描述

es的查询过程 3

  • query查询
    es的查询分为2个过程 query和fetch
    query过程就是上面的从 term index -> term dictionary --> posting list,再根据docid获取到对应的文档
    fetch过程 再根据各个分片汇总的数据进行排序,再去各节点获取数据
  • get id查询
    get 过程是从 内存 translong–> 磁盘translog --> 根据docid直接获取文档
    从上面过程可以看出get的获取数据更新,更快

其他

上面是基于id的get查询的分析,但是都是针对单个id的;针对多个id的mget查询和ids query是否有类似的差异呢?通过实验发现基于多个id的查询,mget的效率高于ids query。

# 参考

[1]wrk 简介
[2]es的倒排索引结构
[3]es的查询过程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值