【ElasticSearch系列-07】ES的开发场景和索引分片的设置及优化

ElasticSearch系列整体栏目


内容链接地址
【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827
【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631
【三】ElasticSearch的高级查询Query DSLhttps://blog.csdn.net/zhenghuishengq/article/details/134159587
【四】ElasticSearch的聚合查询操作https://blog.csdn.net/zhenghuishengq/article/details/134159587
【五】SpringBoot整合elasticSearchhttps://blog.csdn.net/zhenghuishengq/article/details/134212200
【六】Es集群架构的搭建以及集群的核心概念https://blog.csdn.net/zhenghuishengq/article/details/134258577
【七】ES的开发场景和索引分片的设置及优化https://blog.csdn.net/zhenghuishengq/article/details/134302130

ES的开发场景和索引分片的设置及优化

  • 一,ES的开发场景和索引分片的设置及优化
    • 1,ES应用场景
      • 1.1,信息搜索库
      • 1.2,时间序列库
    • 2,分片的设计和管理
      • 2.1,单个分片
      • 2.2,多个分片
        • 2.2.1,算分不准原因
      • 2.3,分片的设计
        • 2.3.1,分片类型选择以及优缺点
        • 2.3.2,主分片设计与案例
        • 2.3.3,副本分片设计
    • 3,ElasticSearch底层读写原理
      • 3.1,数据的写入
        • 3.1.1,数据写入的流程
        • 3.2.2,数据存储文件形式
      • 3.2,数据的读取
        • 3.2.1,根据id查询
        • 3.2.2,根据关键字查询
      • 3.3,数据读写优化

一,ES的开发场景和索引分片的设置及优化

在上一篇中,讲解了Es集群的搭建,以及一些索引,分片,副本等的概念,接下来这篇主要讲解在实际开发中,ElasticSearch的一些应用场景

1,ES应用场景

在实际开发中,es主要有两种应用场景:一种是基于数据量大,但是数据增长量慢的应用场景,如订单查询,商品查询等;一种是基于数据量大,数据增长量快的应用场景,如每天都会有大量的日志信息,通过时间序列对日志进行存储和查询等。

1.1,信息搜索库

这就是第一种情况,针对于数据量大,但是增长量慢的应用场景。如在一个商城app中,其商品的信息、订单的信息等,在数据加入到es之后,可以选择通过商品的类型或者名称进行分片存储,在查询时只需要根据商品类型或者名称查询对应的分片结点即可

这种场景更加需要考虑的是搜索的相关度,如涉及算分,权重这些,与时间的范围无关。

在这里插入图片描述

如上图中搜索框中输入的家电,下面会展示所有的家电信息,品牌等,那么在es中做索引分片时,就可以根据品牌进行分片存储等。需要注意的是,单个分片最好不要数据量太大,如不要超过20g,如果数据量太多,可以通过增加副本分片的数量,从而提高吞吐量

如果是单个索引的数据量太大,可以通过reindex进行索引拆分,可以根据某种枚举字段进行拆分,如订单可以根据区域进行拆分,商品根据品牌进行拆分等。

1.2,时间序列库

根据时间序列进行统计,容日志的查询等,一般每条数据都会有一条时间戳,并且每条文档基本上都不会更新,主要是为了查询,因此对数据的写入要求会比较高。如每天有几万条数据插入到es数据库中

在创建索引时,可以直接根据时间进行创建索引,如每天或者每周或者每月的方式进行划分,如每天有上万条日志信息,那么就可以直接根据时间进行创建索引,每天晚上可以开启一个定时任务去创建索引,随后今天一天的数据全部存储在这个索引中,后续作统计时,只需要定位到这个索引片即可

PUT /logs_2023-11-07

也可以直接选择使用这个Date Math表达式,其语法如下

<static_name{date_math_expr{date_format|time_zone}}>

使用这个Date Math的官网:https://www.elastic.co/guide/en/elasticsearch/reference/7.16/date-math-index-names.html

如官方文档给的实例,显示的结果就是创建今天的日期的索引,前缀就是my-index

# PUT /<my-index-{now/d}>
PUT /%3Cmy-index-%7Bnow%2Fd%7D%3E

在这里插入图片描述

上面的百分号在官网中也有对应的值,只需要根据这些值进行修改即可

在这里插入图片描述

官网提供的转义表达式有这些,如now/d等等,从<、-、{、}、/ 等一一的按照上面的值进行替换即可

在这里插入图片描述

如果是需要查询最近的数据,也可以采用冷热分离的架构,将最近几天的数据加入到hot热点数据中;并且在存储日志这种信息是,丢失几条数据也是没事的,因此在设置副本的数量时,可以直接设置为0

如果前端是要固定的查询一个索引,那么可以通过别名的方式去新增索引,先将原索引删除,然后将创建的新索引的别名设置为原索引的名称

2,分片的设计和管理

2.1,单个分片

在es7开始,在创建一个索引时,默认是只有一个分片和一个副本的。如下例子,本人就是使用的7.7的版本,在创建一个索引之后,其默认的分片数和副本数就是1。因为直接使用单个分片,可以避免很多问题,如算分问题,聚合问题

"number_of_shards" : "1",
"number_of_replicas" : "1",

在这里插入图片描述

但是单个分片也存在一些缺点,如在集群中,单个分片不能很好的实现水平扩展,除非要手动reindex增加分片,将数据进行拆分

2.2,多个分片

多个分片和单个分片的优缺点刚好相反,多个分片是有利于实现节点的水平扩展的,在性能上会高于单分片的索引。但是多分片也会出现一些问题,如算分不准,聚合查询等问题

2.2.1,算分不准原因

当数据量大的时候,一般数据都是均分分布在各个节点的,因此不会出现这种算分不准的情况,一般是会出现在数据量小的情况,如每个分片的数据量都比较小,举个例子

先创建一个索引,并设置分片数为3

PUT /zhs_db
{"settings":{"number_of_shards" : "3"}
}

随后往文档中插入数据,这里不使用_bulk批量插入,因为批量插入会在一个分片中。往里面插入三条数据,根据hash规则,那么三条数据就会分别落在三个分片中,一个分片中一条数据

POST /zhs_db/_doc/1?routing=zhenghuisheng
{"content":"Cross Cluster elasticsearch Search"
}POST /zhs_db/_doc/2?routing=zhenghuisheng2
{"content":"elasticsearch Search"
}POST /zhs_db/_doc/3?routing=zhenghuisheng3
{"content":"elasticsearch"
}

随后进行match查询这个content,并且value为elasticSearch

GET /zhs_db/_search
{"query": {"match": {"content": "elasticsearch"}}
}

在执行上面的查询之后,其结果如下,本来是所占文档比率越高,算分的值越大,就是id为3的占百分百,因此按理来说是算分最高的,然而实际在查询出来的是id为1的算分最高,实际id为1的算分是最低的,因此综合来看,这个算分就是不准的

在这里插入图片描述

主要原因是每个分片都有自己打分的标准,每个分片都是基于自己分片上的数据的相关度来进行计算的,其最主要原因是数据量少,因此如果是数据量少的情况下,还是建议设置这个分片数为1

当然在数据量小的时候,也有对应的解决方案,就是使用DFS Query Then Fetch ,其原理就是将所有的数据全部搜索出来,然后统一放在一个协调结点中,通过协调节点再进行一次完整的算分。但是在实际开发中,这种方式并不推荐使用,因为其性能相对是较低的

GET /zhs_db/_search?search_type=dfs_query_then_fetch
{"query": {"match": {"content": "elasticsearch"}}
}

2.3,分片的设计

2.3.1,分片类型选择以及优缺点

上面说了单个分片和多个分片使用的优缺点,接下来谈谈在实际开发中,是如何设计这个分片的。

往往来说,分片的数量是需要大于结点数的,那么这样基本都是优选考虑多分片数据,这样有利于在新增数据节点时,可以进行自动的分配,并且如果一个索引的数据分布在不同的节点,这样就可以并行的执行,并且在数据写入时,也可以分散到多个机器。

但是分片过多,也会带来一些副作用,因为每一个分片就是一个Lucene索引,其实就是一个进程,如果过多的分片,就会占用机器的资源,导致带来额外的开销,并且所有的分片都是需要Master主节点进行维护和管理,这样就会导致master主节点承受更大的负担,因此分片需要控制在10W之内

2.3.2,主分片设计与案例

在实际开发中,日志类的数据只需要设置主分片数,但是不需要设置副本数,而其他的数据增长量慢的需要设置主分片数和副本数,接下来谈谈主分片数需要如何设计

  • 当数据为搜索类时,如商品信息类,那么单个分片不要超过20个G的数据
  • 当数据为日志类时,如订单类、流水类,那么单个分片不要超过50G的数据

搜索类设计:如根据品牌进行设计,一个品牌对应一个索引,一个索引对应一个主分片和一个副本分片

日志类设计:每天创建一个日志索引,每个日志索引创建10个分片,一个月需要创建300个分片,不需要副本

2.3.3,副本分片设计

一般在实际开发中,副本都是设置为0或者1,日志类数据不需要副本,可以直接设置为0,搜索类数据一般设置为1,副本就是类似于主分片的一个从分片,有主分片中的全部数据。

副本分片数据就是数据在住分片中插入完成之后,再在副本分片中再保存一份,如果副本分片数过多,那么在存入副本数据时就会花费更多的时间,在写性能上会有一定的影响

但是副本分片也有好处,首先就是可以提高查询的效率,并且可以防止数据丢失,保证数据的安全性,因此副本分片是需要的,但是也不能设计太大,日志类除外。并且可以通过不断的调整副本分片的个数,来是整个系统的查询率和响应率达到最佳状态

为了避免分配的不均衡,分片数的调整如下:

  • index.routing.allocation.total_shards_per_node:表示在索引中每个Node的最大分片数量,-1表示无穷大
  • cluster.routing.allocation.total_shards_per_node:表示在集群中每个Node结点最大分片的数量,-1表示无穷多个

3,ElasticSearch底层读写原理

上面谈到了分片和副本的一些概念和设计,接下来通过es写入数据的流程来分析,分片和副本的功能到底是什么。

3.1,数据的写入

3.1.1,数据写入的流程

在前面谈到了通过不同的数据节点实现不同的功能,写入请求是需要先通过协调节点,在转发到data数据节点存储,随后先将数据存储到主分片上面,然后再将数据同步到副本分片上面,其具体的流程实现如下

  • 1,在用户发起写请求之后,首先该请求会先到协调节点
  • 2,协调结点接收到这个请求之后,会通过route路由的方式将请求转发给对应的节点
  • 3,随后会将数据同步到该节点的主分片上,如果有副本分片,则将数据给副本分片也同步一份
  • 4,当master主分片和副本分片都同步完数据之后,协调节点再给客户端一个存入成功的响应
3.2.2,数据存储文件形式

segment file :在mysql中,mysql是以页为单位存储在磁盘中,在ElasticSearch中,是通过这个Segment file的方式存储,每一个文件的本质就是一个倒排索引,一个大的分片中,都是由各个小的Segment file文件合并成的。文件过多时会自动合并各个小文件,也可以手动强制合并,在合并时会将被标记删除的文档给物理删除

commit point :当将某个文档删除时,ElasticSearch不会立马删除,而是先通过这个commit point文件做一个标志,每个文件中都有.del的一个标志,如果设置了被删除的状态,那么在查询数据时,默认会将这个文档给过滤掉。这个也有点类似于mysql的行格式,里面有字段用于标记是否被删除

translog文件 :类似于mysql的redolog文件,防止因为宕机造成数据丢失,用于做数据恢复

os cache :缓存,每隔一s会进行一个刷盘操作,也可以通过refresh强制刷盘

3.2,数据的读取

数据的查询主要有两种方式,一种是直接根据id进行查询,一种是直接根据关键字进行匹配

3.2.1,根据id查询

根据id查询的方式是比较简单的,首先也是先由客户端发起请求,随后将请求发送到协调者结点,协调者节点通过这个id进行hash取模定位到Data数据节点,数据节点上有主分片和副本分片,这两种分片都可以进行数据的查询,会通过随机的方式选择副本还在主分片,如下面的P0和R0,会在这两个分片中,选择一个分片作为数据查询的依据,随后将响应结果返回给协调者分片分片,最后再通过协调者分片将数据返回给用户

当然如果副本分片和主分片之间,也可以做一个负载均衡,来提高整个系统的高性能

在这里插入图片描述

3.2.2,根据关键字查询

其流程大致和上面的一样,先将请求给协调者节点,随后定位到Data数据节点,但是在查询数据再到返回数据的过程中,需要经历过两个阶段的操作。

因为es底层使用的是倒排索引,因此第一步是先将需要查询带有关键字的数据全部查询出来,随后携带那一行数据的id,再通过id查询,这就是相当于要查询两次,用mysql来解释,就是通过一个加了索引的字段进行数据查询,随后将携带的id进行回表操作

  • query phase:第一步就是这个,先将全部的数据返回给协调者节点,再协调者节点中进行过滤、排序等操作
  • fetch phase:第二步就是根据第一步所确定的结果,通过数据的id再进行一次查询工作将数据返回

3.3,数据读写优化

上面了解了读写的底层原理,在知道原理之后,那么就可以根据原理进行优化操作。

读取数据优化

如在读取数据时,减少这种通配符查询、前缀查询等需要全文检索的查询;如不需要算分的字段可以使用精确查询;使用Filter Context,利用内部的缓存机制,减少不必要的算分;结合profile、explain分析查询慢的问题等

写入数据优化

在写入数据时,可以使用批量插入数据来增加系统的吞吐量,或者使用多线程的方式插入数据;

分片优化

除了在查询优化,也可以在分片上做优化,数据量不大的情况可以使用单分片,数据量大使用多分片时,需要防止分片过多带来的开销。对于这种时间序列的查询,可以强制的force merge,将不需要的文档删除,从而减少这种segment的数量。

除了上面的几中优化之外,还可以对服务端硬件设备等进行优化,还可以调节这个refresh的频率进行优化、调整translog写入磁盘的频率进行调整等。如下面的这个模板,设置refresh刷新时间,translog刷盘等

DELETE myindex
PUT myindex
{"settings": {"index": {"refresh_interval": "30s",  #30s一次refresh"number_of_shards": "2"},"routing": {"allocation": {"total_shards_per_node": "3"  #控制分片,避免数据热点}},"translog": {"sync_interval": "30s","durability": "async"    #降低translog落盘频率},"number_of_replicas": 0},"mappings": {"dynamic": false,     #避免不必要的字段索引,必要时可以通过update by query
索引必要的字段"properties": {}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/136669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单好看个人引导页毛玻璃页面 HTML 源码

毛玻璃个人引导页源码&#xff0c;界面简洁&#xff0c;已测可完美搭建&#xff0c;UI非常不错的&#xff0c;有兴趣的自行去安装体验吧&#xff0c;其它就没什么好介绍的了。 学习资料源代码&#xff1a;百度网盘 请输入提取码&#xff1a;ig8c

读程序员的制胜技笔记08_死磕优化(上)

1. 过早的优化是万恶之源 1.1. 著名的计算机科学家高德纳(Donald Knuth)的一句名言 1.2. 原话是&#xff1a;“对于约97%的微小优化点&#xff0c;我们应该忽略它们&#xff1a;过早的优化是万恶之源。而对于剩下的关键的3%&#xff0c;我们则不能放弃优化的机会。” 2. 过早…

适合汽车音频系统的ADAU1977WBCPZ、ADAU1978WBCPZ、ADAU1979WBCPZ四通道 ADC,24-bit,音频

一、ADAU1977WBCPZ 集成诊断功能的四通道ADC&#xff0c;音频 24 b 192k IC&#xff0c;SPI 40LFCSP ADAU1977集成4个高性能模数转换器(ADC)&#xff0c;其直接耦合输入具有10 V rms性能。该ADC采用多位Σ-Δ架构&#xff0c;其连续时间前端能够实现低EMI性能。它可以直接连接…

11.9存储器实验总结(单ram,双ram,FIFO)

实验设计 单端口RAM实现 双端口RAM实现 FIFO实现 文件结构为

python-jupyter实现OpenAi语音对话聊天

1.安装jupyter 这里使用的是jupyter工具&#xff0c;安装时需要再cmd执行如下命令&#xff0c;由于直接执行pip install jupyter会很慢&#xff0c;咱们直接使用国内源 pip install --user jupyter -i http://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.t…

Python按类别和比例从Labelme数据集中划分出训练数据集和测试数据集

Python按类别和比例从Labelme数据集中划分出训练数据集和测试数据集 前言前提条件相关介绍实验环境按类别和比例从Labelme数据集中划分出训练数据集和测试数据集代码实现输出结果 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精彩内容&#x…

真正解决jellyfin硬解码转码

前段时间入手一个DS423集成显卡UHD600&#xff0c;搭了一个jellyfin&#xff0c;发现网上关于硬解码的教程基本都存在问题&#xff0c;没有真正解决我的硬解码问题。经过一系列分析修改&#xff0c;最终实现硬解码。先贴效果图&#xff1a; 下载安装jellyfin这里就不叙述&#…

Maven-构建生命周期与插件

一、概念和基础 Maven针对项目的构建和发布定义了一系列明确的步骤&#xff0c;根据作用不同这些步骤分属于不同的生命周期。Maven针对每个步骤都有对应的默认插件&#xff0c;Maven在构建过程中是通过调用这些插件完成整个过程的。开发者只需要通过简单的命令就可以驱动maven…

若依分离版——使用Knife4j 自动生成接口文档

背景&#xff1a; 前后端分离程序&#xff0c;如果需要前端开发人员和后端开发人员配合开发&#xff0c;则需要将接口文档并显性给前端人员 解决办法&#xff1a; 使用knife4j替代若依自带的swagger&#xff0c;因为knife4j是在swagger基础上包装的&#xff0c;Knife4j不仅具…

nodejs+vue+python+PHP+微信小程序南七街道志愿者服务平台的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

键盘win键无法使用,win+r不生效、win键没反应、Windows键失灵解决方案(亲测可以解决)

最近几天发现自己笔记本的win键无法使用&#xff0c;win失灵了&#xff0c;但是外接键盘后则正常:。 这个问题困扰了我一周&#xff0c;我都以为自己的枪神坏了。 寻找了几个解决方法&#xff0c;网上看了好多好多稀里糊涂的办法&#xff0c;都是不管用的&#xff0c;这里给大…

RAW图像处理软件Capture One 23 Enterprise mac中文版功能特点

Capture One 23 Enterprise mac是一款专业的图像处理软件&#xff0c;旨在为企业用户提供高效、快速和灵活的工作流程。 Capture One 23 Enterprise mac软件的特点和功能 强大的图像编辑工具&#xff1a;Capture One 23 Enterprise提供了一系列强大的图像编辑工具&#xff0c;…

卡尔曼滤波EKF

目录 一、概述 二、卡尔曼滤波的5个公式 三、应用案例&#xff1a;汽车运动 四、应用案例&#xff1a;温度估计 五、总结 一、概述 初学者对于卡尔曼滤波5个公式有点懵&#xff0c;本文先接地气地介绍5个公式&#xff0c;然后举两个常用例子加强理解&#xff0c;同时附有M…

阿里云服务器密码在哪查看?如何设置修改初始密码?

阿里云服务器创建后没有默认初始密码&#xff0c;需要用户通过重置实例密码的方式来设置新的密码&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云服务器ECS重置实例密码的详细操作流程&#xff1a; 阿里云服务器重置密码方法 1、登录到阿里云服务器管理控制台 2、左侧…

STM32-EXTI中断

EXTI简介 EXTI&#xff08;Extern Interrupt&#xff09;外部中断 EXTI可以监测指定GPIO口的电平信号&#xff0c;当其指定的GPIO口产生电平变化时&#xff0c;EXTI将立即向NVIC发出中断申请&#xff0c;经过NVIC裁决后即可中断CPU主程序&#xff0c;使CPU执行EXTI对应的中断程…

【Leetcode】202. 两数之和

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…

判断sparse matrix是否是对称矩阵

参考&#xff1a; https://stackoverflow.com/questions/48798893/error-in-checking-symmetric-sparse-matrix import scipy.sparse as sp import numpy as np np.random.seed(1)a sp.random(5, 5, density0.5)a结果如下 sym_err a - a.T sym_check_res np.all(np.abs(s…

制作一个用户登录界面

Flask-WTF扩展使用Python类来表示web表单。表单类只是将表单的字段定义为类变量。 再次考虑到分离的问题&#xff0c;我将使用一个新的app/forms.py模块来存储我的web表单类。首先&#xff0c;让我们定义一个用户登录表单&#xff0c;它要求用户输入用户名和密码。表单还将包括…

Vue3 + Vite + Ts + Router搭建项目

1、新建文件夹 从新建的文件夹cmd进入终端 2、安装vite—依据vite创建vue3项目 2.1、运行 npm init vitelatest2.2.1、输入项目名称 2.2.2、选择vue 2.2.3、选择TypeScript语言 3、安装依赖项 3.1、进入刚才创建的文件夹 cd vite-project 3.2、查看镜像 #查看当前源 npm con…

mac M2 pytorch_geometric安装

我目前的环境是mac M2&#xff0c;我在base环境中安装了pytorch_geometric,仅仅做测试用的&#xff0c;不做真正跑代码的测试 首先我的base环境的设置如下&#xff1a; pip install pyg_lib torch_scatter torch_sparse torch_cluster torch_spline_conv -f https://data.pyg.…