Elasticsearch笔记4 基础入门

2023-11-14

执行分布式检索

一个查询操作,在ES分布式环境中分为两步:查询与合并

查询阶段

ES集群向所有分片传递查询语句。
分片接收到请求后,执行搜索并建立一个长度为top-n的优先队列,存储结果。
top-n 的大小取决于分页参数 top-n=from+size

步骤

  • 客户端发送查询请求到节点A,节点A创建分片数*(from+size)长度的优先队列(空的)。
  • 此处ES对top-n的长度最大是10000(可配置)
  • 节点A将查询请求并行发送到所有主分片和副分片。
  • 各分片本地执行检索,并将结果存到各自本地的top-n优先队列
  • 各分片将优先队列返回给A节点(仅id和排名(_score))
  • 节点A合并各节点返回的内容,产生一个全局排序的结果存到自身优先队列中。

取回阶段

步骤

  • 协调节点判断哪些需要返回,哪些需要丢弃。form的丢弃,size的返回。
  • 协调节点根据个分片返回的id,向个分片发起get请求。
  • 各分片接收到get请求,检索完整文档,返回给协调节点。
  • 协调节点判断所有文档均返回后,向客户端返回结果。

深分页

协调节点创建的优先队列,长度是有限制的。即便长度无限,处理他们也是非常耗时的。所以不建议提供过深的分页功能。

搜索选项

有几个影响性能的参数

  • preference(偏好)
    控制分片是否参与检索
    • _primary
    • _primary_first
    • _local
    • _only_node:xyz
    • _prefer_node:xyz
    • _shards:2,3

Bouncing Results

当使用类似入库时间这样的字段检索时,由于主分片和副本分片本身存在入库时间差异,所以导致多次查询结果集变化的情况。可以使用preference处理。

超时问题

处理过程可能超时

路由

在取回阶段,协调节点根据id获取文档,此时会走获取流程,会根据id计算所属分片,快速提取。

搜索类型

缺省类型是query_then_fetch(包含预查阶段)

游标查询

ES为解决深分页的性能问题,提供了游标查询机制。

游标分解

  • 初始化阶段:按照检索条件进行数据检索,并将结果缓存起来。
  • 遍历阶段:从缓存中提取数据
    特点:初始化阶段后任何操作不会对结果产生影响,因为读的是缓存数据

索引管理

创建一个索引

语法格式

PUT /my_index
{
    "settings": { ... any settings ... },
    "mappings": {
        "type_one": { ... any mappings ... },
        "type_two": { ... any mappings ... },
        ...
    }
}

禁止自动创建索引

config/elasticsearch.yml

action.auto_create_index: false

删除一个索引

语法格式

DELETE /my_index
DELETE /index_one,index_two
DELETE /index_*
DELETE /_all
DELETE /*

避免误删除,必须指定删除,拒绝模糊范围删除,避免误删除

elasticsearch.yml
action.destructive_requires_name: true

索引设置

ES提倡使用默认设置,不要瞎改

  • number_of_shards 主分片数,默认5。创建后不可变更。
  • number_of_replicas 副本分片数,默认1。创建后可变更。

配置分析器

ES支持配置已有的分析器,或者为你的索引设置创建自定义分析器。

默认全文分析器

standard分析器是用于全文检索的默认分析器,适用于大部分西方语言。特点如下:

  • standard分词器: 通过单词边界分割输入文本。
  • standard语汇单元过滤器: 语汇单元过滤器,目的是整理分词器触发的语汇单元(目前什么也没做)
  • lowercase语汇单元过滤器: 转换所有的语汇单元为小写
  • stop 语汇单元过滤器: 删除停用词-对搜索相关性影响不大的常用词,如a,the,and等等

自定义分析器

可以通过在一个适合你的特定数据的设置之中组合字符过滤器、分词器、词汇单元过滤器来创建自定义的分析器。
一个分析器就是组合了三种函数的一个包装器, 三种函数按照顺序被执行:

  • 字符过滤器
    • 数量 0 ~ N 个
    • 用于整理尚未被分词的字符串,调整内容。比如去除HTML语法,转码等
  • 分词器
    • 用于将字符串分解成单个词条或者词汇单元。
    • 数量 1 唯一
  • 词单元过滤器
    • 经过分词,作为结果的 词单元流 会按照指定的顺序通过指定的词单元过滤器 。
    • 词单元过滤器可以修改、添加或者移除词单元。
    • 数量 0 ~ N 个

创建自定义分析器语法

PUT /my_index
{
    "settings": {
        "analysis": {
            "char_filter": { ... custom character filters ... },
            "tokenizer":   { ...    custom tokenizers     ... },
            "filter":      { ...   custom token filters   ... },
            "analyzer":    { ...    custom analyzers      ... }
        }
    }
}

实例

PUT /my_index
{
    "settings": {
        "analysis": {
            "char_filter": {
                "&_to_and": {
                    "type":       "mapping",
                    "mappings": [ "&=> and "]
            }},
            "filter": {
                "my_stopwords": {
                    "type":       "stop",
                    "stopwords": [ "the", "a" ]
            }},
            "analyzer": {
                "my_analyzer": {
                    "type":         "custom",
                    "char_filter":  [ "html_strip", "&_to_and" ],
                    "tokenizer":    "standard",
                    "filter":       [ "lowercase", "my_stopwords" ]
            }}
}}}

类型和映射(大概意思)

在ES中同一索引下的不同类型通过_type进行区分和使用。但是在Lucene中并没有类型的概念。Lucene中将同一索引下全部类型的映射信息进行无差别的同级存储。
如果不同类型下相同映射采用不同的分析器,ES会报错。
所以新版本中的ES不再支持多类型模式,而是单类型模式的原因

根对象

动态映射

当ES遇到文档中以前未遇到过的字段,会动态的进行映射。该功能可通过dynamic进行配置。

  • true 动态添加新的字段映射
  • false 忽略新的字段
  • strict 遇到新的字段报错
PUT /my_index
{
    "mappings": {
        "my_type": {
            "dynamic":      "strict", 
            "properties": {
                "title":  { "type": "string"},
                "stash":  {
                    "type":     "object",
                    "dynamic":  true 
                }
            }
        }
    }
}

自定义动态映射

日期检测

当新字段内容为‘2020-10-10’时,动态映射成为date类型,此时再次传递字段内容为‘1234’时,将报错。可以通过关闭日期检测避免问题。
关闭日期检测

PUT /my_index
{
    "mappings": {
        "my_type": {
            "date_detection": false
        }
    }
}

动态模板

通过指定动态模板,实现有规则的进行动态映射。比如通过字段名后缀等等。

缺省映射

通过缺省映射为所有映射进行统一配置,如有不同可在具体映射内更改配置。

PUT /my_index
{
    "mappings": {
        "_default_": {
            "_all": { "enabled":  false }
        },
        "blog": {
            "_all": { "enabled":  true  }
        }
    }
}

重新索引你的数据

重新索引:用新的设置创建新的索引并把文档从旧的索引复制到新的索引。

GET /old_index/_search?scroll=1m
{
    "query": {
        "range": {
            "date": {
                "gte":  "2014-01-01",
                "lt":   "2014-02-01"
            }
        }
    },
    "sort": ["_doc"],
    "size":  1000
}

索引别名和零停机

别名

别名支持一对多关系
创建别名

PUT /my_index_v1/_alias/my_index

删除别名
查看别名指向索引

GET /*/_alias/my_index

查看索引关联别名

GET /my_index_v1/_alias/*

零停机

在不停机的情况下,删除原始别名,建立新别名

POST /_aliases
{
    "actions": [
        { "remove": { "index": "my_index_v1", "alias": "my_index" }},
        { "add":    { "index": "my_index_v2", "alias": "my_index" }}
    ]
}

该操作属于原子操作

分片内部原理

段和提交点的概念

一个索引关联多个段索引(每个段都是倒排索引),并由提交点文件进行记录关联关系。

文档的存储流程A

  • 新文档被收集到内存索引缓存
  • 定时,缓存到被提交
    • 一个新的段-》一个追加的倒排索-》被写入磁盘
    • 一个新的包含新段名字的 提交点 被写入磁盘
    • 磁盘进行同步:所有在文件系统缓存中等待的写入都刷新到磁盘,以确保它们被写入物理文件。
    • 文档保存结束,可以被检索(可检索延迟高,后续流程B将解决)

不变性

倒排索引被写入磁盘后是 不可改变 的,不变性的价值

  • 不需要锁。因为没有变更,所以不需要锁来预防并发改的问题。
  • 方便缓存。因为没有变更,只要缓存有空间,便可一直缓存。不需要考虑缓存一致性问题。
  • 其他缓存(Filter)。在检索过程中产生的缓存,可以重复使用。
  • 数据压缩。减少磁盘I/O,节省磁盘空间,节省缓存空间。

动态更新索引

既然索引是不可改变的,又如何应对更新、删除操作?答案是用更多的索引。
当删除一个索引时,其实是状态删除,检索过程中进行过滤。
当更新一个索引时,其实是状态删除和新增索引。检索过程中过滤掉删除的,保留新增的,

近实时索引

文档的存储流程B

  • 新文档被收集(组成一个倒排索引段)到内存索引缓存
  • 倒排索引段保存到系统文件缓存(此时已支持被检索,延迟低)
  • 定时,缓存到被提交
    • 一个新的段-》一个追加的倒排索-》被写入磁盘
    • 一个新的包含新段名字的 提交点 被写入磁盘
    • 磁盘进行同步:所有在文件系统缓存中等待的写入都刷新到磁盘,以确保它们被写入物理文件。
    • 文档保存结束,可以被检索(可检索延迟高,后续流程B将解决)

refresh API

ES对一个新段的操作是需要关联的,不能上来直接用。系统采用定时执行的方式实现自动关联。
手动触发

POST /_refresh 
POST /blogs/_refresh 

设置定时频率

PUT /my_logs
{
  "settings": {
    "refresh_interval": "30s" 
  }
}

设置定时开与关
在做大索引迁移过程中,建议先关闭,迁移结束后再开启。

PUT /my_logs/_settings
{ "refresh_interval": -1 }

PUT /my_logs/_settings
{ "refresh_interval": "1s" }

如果refresh_interval=1 表示1毫秒,每毫秒做一次关联,会把ES搞瘫痪

持久化变更

translog 事务日志

ES通过translog机制确保数据安全性

translog记录点

  • 新文档被收集(组成一个倒排索引段)到内存索引缓存
  • 记录本次操作到translog中。
  • 倒排索引段保存到系统文件缓存(此时已支持被检索,延迟低)
  • 定时,缓存到被提交(全量提交)
    • 一个新的段-》一个追加的倒排索-》被写入磁盘
    • 一个新的包含新段名字的 提交点 被写入磁盘
    • 磁盘进行同步:所有在文件系统缓存中等待的写入都刷新到磁盘,以确保它们被写入物理文件。
    • 文档保存结束,可以被检索(可检索延迟高,后续流程B将解决)

translog处理过程-运行中

每隔一段时间或者translog过大。索引将被刷新(flush);一个新的translog被创建,并且一个全量提交被执行。

  • 所有在内存缓冲区的文档都被写入一个新的段。
  • 缓冲区被清空
  • 一个提交点被写入磁盘
  • 文件系统缓存通过fsync被刷新(flush)
  • 老的translog被删除

translog处理过程-启动

当ES关闭时,translog中还有剩余数据。在ES启动过程中需要被刷新(或者说启动时需要一个新的translog,才把旧translog刷新,而不是继续使用)。

  • 使用提交点记录关联索引与段的关联关系
    • 此时不包含未fulsh段。
    • 此时内存缓存区是空的。
    • 此时translog是有旧数据的。
  • 重放translog
    重放数据到内存缓存区
    建立新段
  • 全量提交
    • 内存缓存区清空
    • translog清空

flush API

通常情况下,自动刷新就足够了。
手动提交

POST /blogs/_flush 
POST /_flush?wait_for_ongoing 

启动与关闭

PUT /my_index/_settings
{
    "index.translog.durability": "async",
    "index.translog.sync_interval": "5s"
}

durability=async表示开启
sync_interval=5s表示间隔5秒同步到磁盘

translog有多安全

translog先记录在内存,每间隔5S同步到磁盘。

段合并

由于自动刷新流程每秒会创建一个新的段 ,这样会导致短时间内的段数量暴增。而段数目太多会带来较大的麻烦。 每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段;所以段越多,搜索也就越慢。
ES在后台自动进行段合并操作,在后台将多个相似的小段合并到大段。并且不会影响ES操作。

合并流程

  • 新的段被刷新(flush)到了磁盘。 ** 写入一个包含新段且排除旧的和较小的段的新提交点。
  • 新的段被打开用来搜索。
  • 老的段被删除。

optimize API

API大可看做是 强制合并 API。它会将一个分片强制合并到 max_num_segments 参数指定大小的段数目。 这样做的意图是减少段的数量(通常减少到一个),来提升搜索性能。

POST /logstash-2014-10/_optimize?max_num_segments=1

文章中部分内容来源于:
Elasticsearch: The Definitive Guide by Clinton Gormley and Zachary Tong (O’Reilly). Copyright 2015 Elasticsearch BV, 978-1-449-35854-9。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Elasticsearch笔记4 基础入门 的相关文章

随机推荐

  • Docker-compose安装mysql

    介绍 本系列文章主要介绍使用docker compose部署mysql nginx redis等中间件 前后分离微服务项目部署流程 不介绍docker安装以及基础命令 话不多说首先进入mysql安装教学 操作 首先创建个目录用来存放dock
  • unity让一个物体从上到下消失_Unity3D中隐藏与显示物体的一些操作

    在使用unity3d开发游戏的过程中 我们常常会遇到需要隐藏或者显示的操作 针对这一点 下面做了一些总结 一 设置Renderer状态 在游戏的开发中 所有能够被渲染的物体都包含有一个Renderer组件 使用它可以将物体渲染到屏幕上 那么
  • linux shell脚本无法执行,报错syntax error near unexpected token `$'\r''解决方法

    最近一直忙于项目上的要求 在编写各种自动化安装的脚本 正好有一个需求是在之前的项目上编写过的 目前只需要拿来修改下即可 之前的shell脚本是在服务器上编写的 后来又已复制的方式存在在了电脑上 以txt文件的形式存放的 于是复制到了编辑工具
  • Spring知识点总结

    一 Spring框架介绍 Spring 是分层的 Java SE EE 应用 full stack 轻量级开源框架 以 IoC Inverse Of Control 反转控制 和 AOP Aspect Oriented Programmin
  • mybatis-mate相关配置

    Mybatis Mate 配置 mybatis mate cert grant 请添加微信wx153666购买授权 不白嫖从我做起 license SM hy2HGmqRZIw7NE5i1vKIiHOQLGXGymokyRCkR TYuNZ
  • html+jQuery自定义报告单

    html jQuery实现自定义报告单 功能 用户按需求自定义拼接生成报告单 支持打印功能 支持导出HTML CSS代码 截图 源码地址 customize report
  • java中byte和Byte详解

    写程序时 误把byte写作Byte 调试了许久 便将二者的区别及用法详细理解一遍 1 byte标题和Byte详解 byte是java的基本数据类型 存储整型数据 占据1个字节 8 bits 能够存储的数据范围是 128 127 Byte是j
  • Windows环境下ARM集成开发环境的搭建与使用

    Windows环境下能够使用Eclipse IDE for C C Developers来搭建ARM开发环境 本文地址 http blog csdn net u011833609 article details 30290655 安装过程例
  • 继续教育自动听课软件_2017继续教育挂机软件下载

    继续教育自动挂机软件2017是一款帮助用户挂机学习的辅助工具 有了它你就不用一直呆在电脑前了 它可以自动更新学习时间 自动换课计时 安全无病毒 方便快捷 省时省力省心 全国中小教师继续教育网的各种远程培训学习 全国各省份都能使用 使用教程
  • Valid注解在嵌套对象中校验失效

    接收对象声明 import lombok Data import javax validation constraints NotBlank import javax validation constraints NotNull impor
  • 数学的幽默打油诗

    1 常微分学常没分 数理方程没天理 实变函数学十遍 泛函分析心犯寒 微分拓扑躲不脱 随机过程随机过 微机原理闹危机 汇编语言不会编 量子力学量力学 机械制图机械制 2 高数 拉格朗日 傅立叶旁 我凝视你凹函数般的脸庞 微分了忧伤 积分了希望
  • 宁波到西塘可以坐火车去吗?

    宁波 嘉善 西塘宁波 嘉善火车 N406 N407 空调快速宁波15 10出发嘉善19 27到达4小时17分270公里硬座 42元硬卧 93元然后从嘉善打车到西塘 9公里 15元左右 坐快客3元也可以乘坐T794 空调特快宁波 10 41出
  • python 实现自动批量下载腾讯在线excel

    python 批量下载腾讯在线文档 如需要源代码供参考 可以留言邮箱 看到的话就发一下 pthon自动批量下载腾讯在线文档 对于大量实时更新维护的在线文档 可以随时轻松自动化批量下载在线文档 无需耗费人工下载 腾讯在线文档标签有时候会随版本
  • BP神经网络算法基本原理,BP神经网络算法流程图

    伤寒 副伤寒流行预测模型 BP神经网络 的建立 由于目前研究的各种数学模型或多或少存在使用条件的局限性 或使用方法的复杂性等问题 预测效果均不十分理想 距离实际应用仍有较大差距 NNT是Matlab中较为重要的一个工具箱 在实际应用中 BP
  • 爬虫中有关验证码的问题处理

    在爬虫中 经常要处理登陆的相关事宜 有时候登陆界面会需要提交验证码 如何处理验证码 解决办法 若是自己编写模块 需要涉及深度学习 这就是另一块大的内容了 在这里简单调用已经封装好的模块来实现获取验证码 本文以超级鹰为例 网址 http ww
  • PADS 原理图如何自动编号

    PADS原理图如何自动编号 PADS 原理图工具 PowerLogic exe 不支持元件位号重名 原生不提供自动编号功能 虽然 PowerPCB exe 可以支持元件位号自动编号功能再同步到原理图 但是其局限性太大没啥实际意义 另外 PA
  • YUV格式学习:YUYV、YVYU、UYVY、VYUY格式转换成RGB

    YUYV YVYU UYVY VYUY格式 它们都是YUV422的打包格式 即在内存中 Y U V都是挨着排序的 它们的名称就表示了Y U V的顺序 像YUYV 就是Y U Y V Y U Y V 在做转换时 就显得很容易 简单了 因为极其
  • 【卷积核设计】10、Scaling Up Your Kernels to 31x31

    文章目录 一 背景 二 方法 三 RepKLNet a Large Kernel Architecture 3 1 结构 3 2 尽可能的让卷积核变大 3 3 图像分类 3 4 语义分割 3 5 目标检测 四 分析 五 限制 六 结论 论文
  • 【笔试强训选择题】Day43.习题(错题)解析

    作者简介 大家好 我是未央 博客首页 未央 303 系列专栏 笔试强训选择题 每日一句 人的一生 可以有所作为的时机只有一次 那就是现在 文章目录 前言 一 Day43习题 错题 解析 总结 前言 一 Day43习题 错题 解析 1 解析
  • Elasticsearch笔记4 基础入门

    执行分布式检索 一个查询操作 在ES分布式环境中分为两步 查询与合并 查询阶段 ES集群向所有分片传递查询语句 分片接收到请求后 执行搜索并建立一个长度为top n的优先队列 存储结果 top n 的大小取决于分页参数 top n from