Elasticsearch 需要了解的都在这

news2024/11/16 7:01:01

ES选主过程?

其实ES的选主过程其实没有很高深的算法加持,启动过程中对接点的ID进行排序,取ID最大节点作为Master节点,那么如果选出来的主节点中存储的元信息不是最新的怎么办?

其实他是分了2个步骤做这件事,先选出ID最大的主节点,然后再从元信息最新的节点将元信息数据复制到选举出来的主节点

当然虽然是选出ID取值最大的节点作为主节点,但是内部还是有一定限制逻辑的:

  1. 参选人数需要过半,达到 quorum(多数)后就选出了临时的主。为什么是临时的?每个节点运行排序取最大值的算法,结果不一定相同。举个例子,集群有5台主机,节点ID分别是1、2、3、4、5。当产生网络分区或节点启动速度差异较大时,节点1看到的节点列表是1、2、3、4,选出4;节点2看到的节点列表是2、3、4、5,选出5。结果就不一致了,由此产生下面的第二条限制。

  1. 得票数需过半。某节点被选为主节点,必须判断加入它的节点数过半,才确认Master身份。解决第一个问题。

  1. 当探测到节点离开事件时,必须判断当前节点数是否过半。如果达不到quorum,则放弃Master身份,重新加入集群。如果不这么做,则设想以下情况:假设5台机器组成的集群产生网络分区,2台一组,3台一组,产生分区前,Master位于2台中的一个,此时3台一组的节点会重新并成功选取Master,产生双主,俗称脑裂。

选举主分片过程?

Master节点并不知道主分片节点位于哪里,它只能向所有节点上的所有Shard去询问你的website下标是不是0,那么这个询问的请求量就等于 节点数 * Shard数,如果你的规模非常庞大,那么这个将会很耗时,这个时候可能会获取到多份下标为0的请求响应,5.X版本之后主分片的选举是根据一个List<最新主分片>,在这个集合中的分片都是元信息最新的分片数据

高并发写数会不会影响读?

首先写是加锁的,无论是Bulk方式还是普通方式

Bulk方式的写锁

但是这个时候的写锁并不影响读,只是为了确保这一次请求被一个线程处理,这个时候用的是java的可重入锁

Put方式的写锁

这里使用的是可重入读写锁,然后再初始化到Es自己的ReleasableLock中执行

Get方式读取数据读锁

由于读和写使用的是ReentrantReadWriteLock进行加锁,那么读和写之间就是互斥的,所以主分片在写数据到Cache的时候高并发的写是会影响读的性能的,但是此时副分片节点的读不受影响,之后副分片节点也开始处理主分片同步过来的数据时那么副分片的读也会收到影响

数据写入顺序性怎么保证?

每一个写入的文档都有一个_version,每次修改会递增用来判断本次修改命令是执行还是丢弃

10亿数据导入到ES需要7个小时?

我们先看下写入过程:

副本节点越多写入时间越久,因为写入是串行的,主节点写入完成后会并发请求所有副本节点,会等到每一个副本节点响应后才会返回给协调者,无论副本节点是否成功都会等待每一个节点响应

如果没有任何优化的话差不多需要这个时间,如果你的场景是每天都会初始化一次那么多数据到ES的话,我们一定需要优化的,写入优化主要是几个方面:

异步刷盘

可以利用异步刷盘加速写入速度,只要丢失数据的风险是可接受范围就行了

index.translog.durability:async

调整副本数

ES副本数过多的时候就会导致写入缓慢,看上面的流程应该比较清楚了,每次大数据量导入之前将副本节点数调整成0是加速写入最直接的办法

BULK批量写入

通过API一条条写入的话太慢了,ES是原生支持BULK批量方式操作

调整FLUSH

  • 适当调整max_index_buffer_size大小,不要太频繁的flush,如果你的使用场景不需要数据太实时能被读到,那么适当放大这个值

  • 调整FLUSH时间

调整REFUSH

ES在修改数据的时候并不是修改原数据,而是新增了一条数据然后将原数据打上了delete标记,这样做的好处就是不需要对同一条数据进行加锁,但是坏处就是数据碎片过多需要不定时merge,而merge过程中需要对被merge的数据块获取合并锁但是不影响读

那么如果要提高写入的性能,我们通常还可以调整segment块的大小避免太多碎片出现以及调整merge的时间

public void forceMerge(final boolean flush, int maxNumSegments, boolean onlyExpungeDeletes, final String forceMergeUUID)
    throws EngineException, IOException {
    if (onlyExpungeDeletes && maxNumSegments >= 0) {
        throw new IllegalArgumentException("only_expunge_deletes and max_num_segments are mutually exclusive");}
    //获取合并锁,但是没有抢占读锁
    optimizeLock.lock();try {
        ensureOpen();store.incRef(); // increment the ref just to ensure nobody closes the store while we optimize
        try {
            if (onlyExpungeDeletes) {
                indexWriter.forceMergeDeletes(true /* blocks and waits for merges*/);} else if (maxNumSegments <= 0) {
                indexWriter.maybeMerge();} else {
                indexWriter.forceMerge(maxNumSegments, true /* blocks and waits for merges*/);this.forceMergeUUID = forceMergeUUID;}
            if (flush) {
                flush(false, true);// 这里会删除已经被打上delete标记的数据
                refresh("force-merge");}
        } finally {
            store.decRef();}
    } catch (AlreadyClosedException ex) {
        //释放任何因为异常而未合并的segment
        ensureOpen(ex);failOnTragicEvent(ex);throw ex;} catch (Exception e) {
        try {
            maybeFailEngine("force merge", e);} catch (Exception inner) {
            e.addSuppressed(inner);}
        throw e;} finally {
        optimizeLock.unlock();}
}

为什么我查询ES的RT已经偏高?

可能几种原因:

  1. 查询过于复杂,需要扫描的文档数过多

  1. 缓存命中率太低

  1. 分片节点数据不均匀,大量数据在一个节点

  1. 数据涉及分片过多

查询过于复杂,需要扫描的文档数过多

这个需要在设计数据结构的时候就避免出现,过于嵌套的结构会使后期查询缓慢,如果现在已经是这种结构了,那么可能最好的办法就是将查询语句拆分,分批去ES查询应用本地内存进行最终结果聚合

缓存命中率太低

ES内部其实是会对查询结果集进行缓存的,但是如果你的查询条件参数值都是now()等类型的数据,那么ES是无法缓存的,也就导致你的缓存命中率很低,完全没有用到Cache

分片级别缓存的逻辑
Node级别缓存的逻辑

ShardRequestCache是ES层级的实现,缓存机制为 LRU, 访问一次,就会考虑缓存,主要用途是对聚合结果进行缓存

NodeQueryCache是Lucene层级的实现,缓存机制为 LRU, 访问达到一定频率,才会考虑缓存,主要用途是对filter子查询的缓存

分片节点数据不均匀,大量数据在一个节点

这个如果采用ES原生的hash进行分片的话一般不会出现这个情况,主要是采用了自己的分片策略,这个时候大量请求都在一个节点那么查询性能肯定降低,最好的解决方案是重新Shard

数据涉及分片过多

节点接收到查询请求后,需要并发请求所有分片等待分片的查询结果返回,如果分片节点过多,那么这个场景势必会导致请求很慢,最好的处理方案是指定分片查询,这个就涉及数据写入的时候就设计好

预索引优化

还可以针对某些查询的模式来优化数据的索引方式。例如,如果所有文档都有一个price字段,并且大多数查询在一个固定的范围上运行range聚合,那么可以通过将范围“pre-indexing”到索引中并使用terms聚合来加快聚合速度,新增一个price_range字段,然后创建索引,查询的时候使用这个字段进行查询

我自己能查看哪些是慢查询嘛?

使用Profile API定位慢查询,这个API返回的统计纬度是按分片纬度统计的

ES集群状态为啥会显示Yellow或Red?

一个ES索引由多个分片组成,由于某些原因,某些分片可能会处于未分配状态(Unassigned),导致集群健康处于Yellow或Red状态,这是一种比较常见的错误信息,导致分片处于未分配的原因可能是节点离线、分片数量设置错误等原因,使用Explain API可以很容易分析当前的分片分配情况

GET /_cluster/allocation/explain

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

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

相关文章

react 项目 中使用 Dllplugin 打包优化技巧

目录 0.React和DLLPlugin 前言 使用步骤 结果截图 主要说明 0.React和DLLPlugin React 是一个用于构建用户界面的 JavaScript 库。它由 Facebook 开发&#xff0c;现在由 Facebook 和一个由个人开发者和公司组成的社区维护。React 允许开发人员构建可重用的 UI 组件并有…

“回文子串、最长回文子序列”总结,动态规划再显神通(Java实现)

目录 一、回文子串 1.1、dp定义 1.2、递推公式 1.3、初始化 1.4、遍历顺序 1.5、解题代码 二、最长回文子序列 2.1、dp定义 2.2、递推公式 2.3、初始化 2.4、遍历顺序 2.5、解题代码 一、回文子串 题目描述&#xff1a; 题目来源&#xff1a;647. 回文子串 1.1、dp定…

解决使用copy.deepcopy()拷贝Tensor或model时报错只支持用户显式创建的Tensor问题

模型训练过程中常需边训练边做validation或在训练完的模型需要做测试&#xff0c;通常的做法当然是先创建model实例然后掉用load_state_dict()装载训练出来的权重到model里再调用model.eval()把模型转为测试模式&#xff0c;这样写对于训练完专门做测试时当然是比较合适的&…

ssm学生心理健康测评网的规划与设计

摘 要 1 Abstract 1 1 绪论 1 1.1 课题背景 1 1.2 课题研究现状 1 1.3 初步设计方法与实施方案 2 1.4 本文研究内容 2 2 系统开发环境 4 2.1 JSP技术介绍 4 2.2 B/S模式 4 2.3 MySQL环境配置 5 3 系统分析 6 3.1 系统可行性分析 6 3.1.…

【模糊神经网络】基于模糊神经网络的倒立摆轨迹跟踪控制

临近春节没啥事做&#xff0c;突然想起前两年未完成的模糊神经网络&#xff0c;当时是学了一段时间&#xff0c;但是到最后矩阵求偏导那块始终不对&#xff0c;最后也不了了之了&#xff0c;趁最近有空&#xff0c;想重新回顾回顾&#xff0c;看看会不会产生新的想法。经过不断…

elasticsearch基本操作

elasticsearch基本操作基础两种模式:ik分词器词库拓展索引库操作mapping映射属性typeindexanalyzerproperties索引库的CRUD创建修改查询删除文档操作创建查询修改删除基础 本教程使用es8.6.0与kibana作为测试环境 打开开发工具 ## 1.查看节点信息 GET /_cat/nodes?v ## 2.查…

【JUC并发编程】深入浅出Java并发基石——AQS

【JUC并发编程】深入浅出Java并发基石——AQS 参考资料&#xff1a; RedSpider社区——第十一章 AQS 深入剖析并发之AQS独占锁 1.5w字&#xff0c;30图带你彻底掌握 AQS&#xff01; 深入浅出AbstractQueuedSynchronizer 我画了35张图就是为了让你深入 AQS 动画演示AQS的核心原…

遍历 “可变参数模板” 的模板参数

类模板和函数模板&#xff0c;只能包含固定数量的模板参数&#xff0c;C11支持模板参数可变&#xff0c;那么在不知道模板参数有多少个的情况下&#xff0c;如何遍历模板参数&#xff1f; 目录 一、可变参数模板的声明 二、可变参数模板的遍历 1、递归遍历 2、非递归遍历 …

idea使用DataBase连接数据库 Free MyBatis Tool自动生成 实体类工具使用

DataBase DataBase连接数据库 设置DataSources Host 》IP地址Port 》端口号User 》用户名Password 》密码Database 》连接的数据库 设置驱动 Drives tables 文件夹中即所连接数据库中表 Free MyBatis Tool自动生成 实体类&#xff0c;Mapper &#xff0c;以及mapper.xml 选…

CleanMyMac4.12.3最新版本Mac系统清理工具

CleanMyMac可以为Mac腾出空间&#xff0c;软件已经更新到CleanMyMac X 支持最新版Macos 10.14系统。CleanMyMac具有一系列巧妙的新功能&#xff0c;可让您安全&#xff0c;智能地扫描和清理整个系统&#xff0c;删除大量未使用的文件&#xff0c;减小iPhoto图库的大小&#xff…

非类型模板参数/模板的特化/模板的分离编译

上一篇文章中&#xff0c;我们对模板有了初步的认识&#xff0c;接下来我们便对模板进一步地学习&#xff01; 1.非类型模板参数 模板参数分为类型形参与非类型形参&#xff1a; ①类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类…

20 个杀手级的 JavaScript 单行代码,可以节省你的编码时间

使用这些基本的单行代码将您的 JavaScript 技能提升到一个新的水平&#xff0c;这也将节省您的编码时间 &#x1f680;1) 查找数组中的最大值&#xff1a;Math.max(...array)2&#xff09;从数组中删除重复项&#xff1a;[...newSet(array)]3&#xff09;生成一个1到100之间的随…

Java开发环境搭建实践

前言 刚刚弄完python的环境搭建&#xff0c;今年打算也要好好学习Java&#xff0c;所以把Java的环境弄起来 搭建过程 jdk下载和安装 下载 官网&#xff1a;Oracle 甲骨文中国 | 云应用和云平台 打开官网 点击产品后下拉找到Java点进去。 下载Java 我就下载最新的jdk把…

Spring Boot学习之任务学习【异步、定时、邮件】

文章目录一 异步任务1.1 创建spring Boot项目&#xff0c;选择Spring Web1.2 创建AsyncService类1.3 编写controller类1.4 在启动类上开启异步功能1.5 测试结果二 定时任务2.1 基础知识2.2 项目创建2.3 创建一个ScheduledService2.4 在主程序上增加EnableScheduling 开启定时任…

Hbuilder打包成苹果IOS-App的详解

本文相关主要记录一下使用Hbuilder打包成苹果IOS-App的详细步骤。介绍一下个人开发者账号&#xff1a;再说下什么是免费的苹果开发者账号&#xff0c;就是你没交688年费的就是免费账号&#xff0c;如果你想变成付费开发者账号&#xff0c;提交申请付费就行&#xff0c;账号都是…

【C++】priority_queue使用模拟实现

priority_queue使用 http://www.cplusplus.com/reference/queue/priority_queue/ 文档介绍 优先级队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的(大堆为例) 在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)…

应用系统基于OAuth2实现单点登录的解决方案

1、OAuth2单点认证原理 基于OAuth2的认证方式包含四种&#xff0c;其中单点登录最常用的是授权码模式&#xff0c;其基本的认证过程如下&#xff1a; 用户访问业务应用&#xff0c;业务应用进行登录检查&#xff1b;业务应用重定向到OAuth2认证服务器&#xff0c;调用获取授权…

米哈伊年终奖是32万,我的年终奖是彩虹屁!

数据来源沉默王二 | 数据报表小熊绘制 年都过完了&#xff0c;年终奖结果也都出来了&#xff0c;我这个年没有过好&#xff0c;每次想到就难受&#xff0c;在看王二整理出来的年终奖&#xff0c;整个人都不好了。 本次统计基于49条数据的不准确统计&#xff0c;仅抽取部分公司部…

Lesson 4.4 随机梯度下降与小批量梯度下降

文章目录一、损失函数理论基础二、随机梯度下降&#xff08;Stochastic Gradient Descent&#xff09;1. 随机梯度下降计算流程2. 随机梯度下降的算法特性3. 随机梯度下降求解线性回归4. 随机梯度下降算法评价三、小批量梯度下降&#xff08;Mini-batch Gradient Descent&#…

SpringMVC执行流程和原理

1、用户发送出请求到前端控制器DispatcherServlet。 2、DispatcherServlet收到请求调用HandlerMapping&#xff08;处理器映射器&#xff09;。 3、HandlerMapping找到具体的处理器(可查找xml配置或注解配置)&#xff0c;生成处理器对象及处理器拦截器 (如果有)&#xff0c;再…