当前位置: 首页 > news >正文

es基本概念-自学笔记

小白刚学,看了一些概念,避免忘记,以此记录。

基本概念

node,index索引,分片,副本,doc values 和 segment,lucence,FST,压缩数组智能存储 是什么

一、lucence(驱动es的核心引擎)

lucence是apache旗下的代码库,工具包。lucene 是一个超级强大的 V12 发动机,es是超跑。

它的存在只为解决一件事 ——如何以最快速度从海量文本中找出最相关的文档。它不负责网络通信、数据存储、分布式协调等。

极致性能: 它的设计目标就是 “快”!通过:

  • 神奇的倒排索引结构: 直接告诉你哪些文档包含关键词,而不是扫描所有文档。

  • 高效数据结构: FST 压缩字典省内存、快速定位词;FOR/RLE/Packed 压缩文档列表省内存、加速遍历和集合操作。

  • 强大的评分算法: 计算文档与查询的相关度分数(如 TF-IDF, BM25),保证结果质量。

    1. 倒排索引

    其实很简单,你想要在购物商城搜索”苹果手机“,那么肯定是基于这个词进行搜索,就要有词对应的文档信息。比如”苹果手机“存在文档1和文档2中,这样的简单的结构就是倒排索引。

    构建的所有词称为term dictornary

    为了搜索方便,还有个term index,就是把所有的词进行字典序排列,这样查找就变成了二分查找。

    2. FST(前缀树)

    所有的数据存储到硬盘上,因为词太多了,但是为了加快查询速度,会把词的索引信息加载到内存中,构建一个类似前缀树的结构,这样既节省了内存也加快了查询速度。

    3. 压缩数组智能存储

    “压缩数组智能存储”如何智能地解决?

    它采用了一套组合拳:FOR (Frame Of Reference) + Packed Block + (可选的) RLE (Run-Length Encoding)。我们拆解来看:

    1. Frame Of Reference (FOR - 帧参考 / 差值编码)

    • 本质: 利用文档 ID 的局部递增特性,存储差值而不是绝对值。 把大整数变成小整数。
    • 怎么做:
      • 将文档 ID 列表分成固定大小的 块 (Block) (比如 128 个 DocID 一个块)。
      • 对每个块:
        • 取块里的第一个文档 ID 作为基准值
        • 计算块内后续每个 DocID 与基准值的差值
      • 示例:
        • 原始 DocID Block: [1000, 1003, 1005, 1010, 1021]
        • 基准值 (MinID): 1000
        • 差值 Delta List: [0, 3, 5, 10, 21] (1000 - 1000 = 0, 1003 - 1000 = 3, …)
        • 效果: 原本需要存储 5 个 可能很大的 int (比如范围在 0~几十亿)。现在存储 1 个较大的 int (基准值 1000) + 5 个很小的 int (0, 3, 5, 10, 21)。小整数是压缩的关键!

    2. Packed Blocks (打包块 / 位压缩)

    • 本质: 利用差值(或原始小数值)都很小的特点,按需分配比特位,而不是固定32位。
    • 怎么做:
      • 拿到一个块的计算后的差值列表 (或者对于词频列表,直接用原始的小数值列表)。
      • 找出这个列表中的最大值
      • 计算存储这个最大值所需的最少比特位数
      • 使用一个紧凑的位打包结构来存储这个块的所有值:每个值只占用计算出来的比特位数。
      • 示例:
        • 差值列表 Delta List: [0, 3, 5, 10, 21]
        • 最大值 Max Delta: 21
        • 存储 21 需要 5 个比特位 (因为 2^5=32 > 21)。
        • 将每个差值用 5 个比特位存储: 0->00000, 3->00011, 5->00101, 10->01010, 21->10101
        • 将它们紧密打包成一个连续的比特流: 00000 00011 00101 01010 10101 (这个比特流在内存中就是连续的字节)。
      • 效果:
        • 原始存储:5个 int = 5 * 4字节 = 20字节
        • FOR + Packed: 1个基准值(4字节) + 5个5位值 = 4字节 + (5 * 5bits) / 8 bits/byte ≈ 4字节 + 3.125字节 ≈ 7.125字节 (节约了 64% 以上!)。
        • 对于大量词频为 1 的块,压缩率更高(可能只需要 1-2 个比特位)!
      • CPU 优势: 一个块被打包在连续、紧凑的内存区域。当 ES 需要遍历这个块(比如做交集 AND 操作),它能高效地一次性将整个块或大部分块加载到 CPU 缓存中进行处理,避免了频繁访问主内存。位解压操作在现代 CPU 上也很快。

    3. 可选的:Run-Length Encoding (RLE - 游程编码)

    • 本质: 利用连续重复值的特性,用 (值, 连续出现次数) 对来存储,而不是存储每个单独的值。
    • 适用场景: 特别适合词频列表。想象一个非常常见的词(如 “the”),它在成千上万个文档中的词频很可能大部分是 1。也可能在某个长文档中出现很多次。
    • 与 FOR/Packed 结合:
      • 在应用 FOR/Packed 之前或之后,检测块内是否有长串的连续相同值。
      • 如果有,就用 RLE 压缩这些连续值。
      • 例如,词频块 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1] 可能被编码为类似 (1, 12), (2, 1), (3, 1), (1, 3) 的形式。
    • 效果: 对包含大量相同词频的块,RLE 能带来极高的压缩率

    总结: “压缩数组智能存储” 的智能之处

    1. 分块 (Blocking): 将大数据集切分成小块,是后续优化的基础,提高 CPU 缓存利用率。
    2. FOR (差值编码): 利用数值局部递增性(文档ID)或值域相对较小(词频)的特性,将大数转化为小数。
    3. Packed Encoding (位压缩): 利用差值/词频都很小的特性,按需分配比特位,极致节省空间。
    4. (可选) RLE (游程编码): 利用连续重复值的特性,进一步提高压缩率(尤其对词频)。
    5. 空间与速度双赢:
      • 省内存: 显著减少倒排索引中 DocID 和 Freq 列表的内存占用(通常压缩到原始大小的 1/5 到 1/10 甚至更低)。
      • 提速度:
        • CPU 缓存友好: 紧凑的块结构更容易放入高速 CPU 缓存,减少访问主内存的昂贵延迟。
        • SIMD 加速潜力: 打包好的整块数据更适合现代 CPU 的 SIMD (单指令多数据) 指令进行并行处理(比如同时对块内多个差值做加法或比较)。
        • 减少 IO: 内存占用小意味着更多索引数据可以常驻内存,减少磁盘 IO。

    大白话一句话总结:

    ES 的“压缩数组智能存储”就像给倒排索引里的数字列表(哪些文档有这个词、词频多少)做超级打包!它发现这些数字往往变化不大或者经常重复,于是:1) 先记录起点和差值(把大数变小);2) 然后像拼拼图一样只用最少的“小格子”(比特位)存这些小差值;3) 碰到一串一模一样的数(比如一堆词频是1),就记成“1出现100次”而不是写100个1。最终效果是:省了大把内存,查起来还飞快!

    这就是 Elasticsearch (以及 Apache Lucene) 能在有限内存下支撑海量数据高效搜索的关键黑魔法之一。它和 FST (处理文本词表) 配合,共同构成了倒排索引高性能的基石。

    4. 模糊查询

    通过编辑距离(Levenshtein算法)来实现的,太远的距离就pass了,能节省很多时间。

二、其他词汇

1. node

node就是es的实例,一个进程。node有很多角色,承担不同的任务。

node的核心角色类型及其本质作用:

  1. master (主节点候选人 / 集群管家候选人):

    • 通俗本质: 它们是有资格竞选“集群总管”职位的员工
    • 核心职责:
      • 集群管理: 维护集群状态(所有索引、分片、节点的元数据,称为 cluster state)。
      • 决策: 做出全局性决策:
        • 创建/删除索引
        • 跟踪所有分片的位置 (哪个节点上有什么分片)。
        • 决定分片的分配和迁移(当节点加入或离开时重新平衡数据)。
        • 处理索引分片分配相关的设置
      • 协调节点加入/离开: 处理新节点加入集群和节点故障离开的事件。
    • 关键点:
      • master 角色只表示该节点有资格成为主节点或被选为主节点,不表示它当前一定是主节点。
      • 一个健康的集群必须至少有 3 个配置了 master 角色的节点(生产环境强烈推荐奇数个,如 3、5、7)。这是为了确保在少数节点故障时,仍然能形成一个法定人数 (Quorum) 来进行选举和管理。
      • 主节点本身通常不存储数据 (除非同时配置了 data 角色)。这是为了让它专注于集群管理任务,避免因数据处理负载过重而影响集群稳定性。
      • 负载: 主要是 CPU 和内存(用于维护集群状态和处理决策)。集群状态变更(如索引创建)会广播给所有 master 节点。
  2. data (数据节点 / 仓库管理员):

    • 通俗本质: 它们是实际保管书本(数据分片)和提供借阅服务(搜索、聚合)的仓库管理员
    • 核心职责:
      • 存储分片: 存储分配给它的主分片和副本分片
      • 数据处理: 执行所有与数据相关的操作
        • 数据的写入更新删除
        • 对数据的搜索请求
        • 对数据的聚合计算
        • 执行字段值的排序等。
    • 关键点:
      • 这是存储和计算负载最重的节点,需要大量的 CPU、内存(特别是 JVM Heap)和磁盘 I/O。
      • 集群的性能(吞吐量、延迟)主要取决于 data 节点的数量和能力。
      • 通常配置为仅具有 data 角色(避免同时承担 master 角色),以最大化其数据处理能力。
  3. ingest (预处理节点 / 数据整理员):

    • 通俗本质: 数据入库前的“流水线工人”,在书本上架(索引)之前对原始数据进行清洗、转换、丰富
    • 核心职责:
      • 在文档被索引到 data 节点之前,应用预定义的预处理管道 (Ingest Pipeline)
      • 管道中可以执行的操作包括:
        • 字段重命名、删除、添加。
        • 数据类型转换。
        • 文本处理(如小写转换)。
        • 丰富数据(如根据 IP 查地理位置)。
        • 解析复杂结构(如 CSV, JSON)。
    • 关键点:
      • 目的是在数据入库将数据整理成更易用的格式,避免在 data 节点上执行昂贵的转换操作。
      • 可选角色。如果没有专门的 ingest 节点,data 节点或 coordinating 节点也会执行管道处理(但会增加它们的负担)。
  4. coordinating (协调节点 / 接待员/调度员):

    • 通俗本质: 它是集群的统一入口和任务调度中心
    • 核心职责:
      • 请求入口: 接收来自客户端应用程序 (如你的代码、Kibana) 的所有请求(搜索、写入)。
      • 请求路由:
        • 写请求: 根据文档 ID 确定应该写到哪个数据节点上的哪个分片(主分片)。
        • 搜索请求: 将搜索请求分发到所有相关的 data 节点(包含目标分片的节点),收集并汇总来自这些节点的部分结果,最后将完整结果排序后返回给客户端
      • 预处理执行: 如果请求需要预处理且该节点有 ingest 角色,它会执行预处理管道。
      • 结果合并: 处理搜索结果的排序、分页、聚合结果合并等。
    • 关键点:
      • 本身不存储数据 (data: false),不能是主节点 (master: false),通常也不做预处理 (ingest: false)。 它是纯协调角色
      • 大集群或高查询负载的场景下,显式配置专门的 coordinating 节点非常重要
        • 避免 data 节点宝贵的 CPU 和 I/O 资源被协调任务消耗。
        • 提供一个可扩展的、无状态的入口层,方便负载均衡(在 coordinating 节点前加负载均衡器如 Nginx, HAProxy)。
      • 负载: 主要是 CPU 和网络 I/O(处理请求分发和结果合并)。

2. index索引

按业务需求进行的大的逻辑分区。
比如日志系统对接es,索引就是各个业务系统名称。
打个比方就像:图书馆里按主题划分的一个分区。比如 “计算机科学书库”、“历史书库”、“小说书库”。每个专题书库就是一个 “索引”。

3.分片

索引的数据存在分片中,分片是对索引数据的水平切分。分片可以存在不同的机器不同的位置处。(高可用)

ES 会自动管理分片的分布,确保同一个分片的主副本不会在同一个节点上(避免单点故障),并尽可能均衡分布。

分片分为:

  • shard主分片
  • 副本分片。
    每个分片本身就是一个功能完整的、独立的 Lucene 索引实例(包含倒排索引、正排索引等所有结构)。

特别注意:索引的主分片数量在索引创建时指定,之后不能修改(除非通过 Reindex)。

4. segment 段

逻辑分区索引下面有分片,负责存储在不同的node的不同地方,分片是由多个segment构成的,segment就是最小的、不可变的 Lucene 索引单元。(不用担心再嵌套下去了,学不玩了/(ㄒoㄒ)/~~)

segment的编辑操作
只会创建新的segment,不会去改动原有的segment!!!这是因为segment中存储了大量其他基本信息(倒排索引,文件结构,元信息等),牵一发动全身。那么高并发的时候,segment必然会创建很多份,防止文件爆炸,es会定期merge segment。

5. doc values

正排索引,为了解决用户需要根据文档内容进行【聚合、排序、脚本操作等】的需要,比如根据创建时间排序,获取用户的数量等信息。

本质是个列式存储结构(类似mysql那种,一列就是一个字段)。 Doc Values 是 Lucene 在索引文档时,在磁盘上额外构建的一种正向索引结构。它以文档 ID 为行,字段为列存储数据。

解决倒排索引的痛点: 倒排索引精于快速查找 “某个词在哪些文档”,但不适合聚合、排序、脚本访问字段值。这些操作需要遍历大量文档并访问字段的原始值,使用倒排索引效率极低(需要 “随机” 打开每个文档找字段值)。

三、ES集群高可用核心

1. Master 节点选举机制 (Bully 算法原理)

ES 采用一个改进版的 Bully 算法 来选举主节点。其核心目标是:在具有 master 资格的节点中,选出一个节点来承担主节点职责。

选举的核心流程与本质:

  1. 触发选举 (什么时候选?):

    • 集群启动: 当第一个具有 master 角色的节点启动时,它发现没有主节点存在,就会触发选举。
    • 主节点故障: 当前主节点宕机或与集群失去联系(网络分区)时,其他 master 节点检测到主节点丢失(通过心跳超时),会触发新的选举。
    • 显式移除主节点: 运维操作导致。
  2. 候选人 (谁可以参选?):

    • 只有配置了 node.roles 包含 master 的节点才有资格参与选举。
  3. 核心选举步骤 (怎么选? - Bully 算法精髓):

    • 步骤 1:发现主节点丢失:一个或多个 master 节点 (candidate) 检测到主节点心跳超时,认为主节点失效。
    • 步骤 2:发起选举:每个认为自己可能是新主节点的 candidate 节点(通常是所有检测到主节点丢失的 master),向当前所有已知的、具有 master 资格的节点广播一个 StartElectionRequest(选举请求)。这个请求包含一个 clusterStateVersion(集群状态版本号,越高表示包含的变更越新)。
    • 步骤 3:比较竞争
      • 收到 StartElectionRequestmaster 节点会比较:
        • 集群状态版本 (clusterStateVersion)拥有最新集群状态版本的 master 节点具有最高优先级。这是为了避免新选出的主节点状态落后,导致数据不一致(最重要原则!)。
        • 节点 ID (Node ID):如果集群状态版本相同(例如集群刚启动时都是0),则比较 节点 ID(一个唯一的字符串标识符)。节点 ID 越小,优先级越高。
        • 节点启动顺序:极端情况下(相同集群状态版本和节点ID),比较节点启动顺序(很少见)。
      • 比较规则:先比 clusterStateVersion (越大越好),再比节点 ID (越小越好)。
    • 步骤 4:投票 (Acknowledgment)
      • 收到 StartElectionRequestmaster 节点,会判断自己是否比发起请求的节点 更适合 (more qualified) 当主节点(根据上面的比较规则)。
        • 如果请求发起者比自己更适合:该节点会投票支持 (acknowledge) 这个发起者,并承诺在选举期间不会投票给其他人。同时会返回自己知道的最新集群状态版本给发起者。
        • 如果自己比发起者更适合:会拒绝 (reject) 这个发起者的请求,并且可能会自己发起一个新的选举请求
    • 步骤 5:当选 & 发布集群状态
      • 发起选举的 candidate 节点需要收到 法定人数 (quorum) 的投票支持才能当选主节点。
        • 法定人数 (quorum) 计算:discovery.zen.minimum_master_nodes (Zen1) 或 cluster.initial_master_nodes + 集群拓扑感知 (Zen2) 共同保证。核心是:floor(N / 2) + 1 (其中 N 是 master 节点总数)。 例如,你有 3 个 master 节点,法定人数是 2 (floor(3/2)+1 = 1+1=2);有 5 个,法定人数是 3。
      • 当一个 candidate 收到超过法定人数的投票支持后,它就宣告自己成为新的主节点 (elected-as-master)
      • 新主节点立即发布一个包含自己当选信息的新版 cluster state 给集群中的所有节点(包括 masterdata/coordinating/ingest 节点)。其他节点接收到这个状态后,就认可这个新主节点。
  4. 关键保障机制:

    • 法定人数 (Quorum)
      • 本质:防止脑裂 (split-brain) 的核心机制。
      • 原理:要求任何决策(包括选举结果、集群状态变更)必须获得大多数 master 节点 (quorum) 的同意才能生效。这样就能确保在网络分区的情况下,最多只有一个分区能形成有效的集群(获得 quorum),另一个分区因为没有足够节点而无法选举或更新状态,从而避免两个主节点同时存在导致数据损坏。
      • 配置:在 ES 7.0 之前,需要手动配置 discovery.zen.minimum_master_nodes(必须设置成 quorum 数)。在 ES 7.0+ 的集群引导阶段,使用 cluster.initial_master_nodes 列出初始 master 节点列表,ES 会自动计算和维护 quorum(推荐方式,不再需要手动设置 discovery.zen.minimum_master_nodes)。
    • 集群状态版本 (Cluster State Version):确保新主节点拥有最完整的集群视图,避免数据丢失或冲突。版本号最高的节点优先当选。

2. 和raft的区别

Raft 算法是什么?

简单说,Raft 是一个 管理复制日志(Replicated Log)的一致性算法

它的核心目标是:让一组计算机(服务器/节点)在部分节点可能故障或网络可能出错的情况下,依然能就一系列操作(状态变更)的顺序达成一致,并安全地复制这些操作。

为什么需要这个? 想象你要在多个图书馆(分布式系统)之间同步图书库存信息。每个图书馆都要记录“新书入库”、“书籍借出”、“书籍归还”这些操作。所有图书馆的操作记录本(日志)必须一模一样且顺序一致,否则有的图书馆认为书在库,有的认为已借出,就乱套了。Raft 就是保证所有管理员(节点)的记录本高度一致的规则。

Raft 的核心思想:领导与跟随

Raft 最大的特点是 强领导(Strong Leader) 模型。每个时刻,至多只能有一个有效的领导者(Leader)。所有决策都由领导者发出,跟随者(Followers)只需接收和执行领导者的指令。这大大简化了协调过程。

Raft 中的节点角色:

  1. Leader (领导者/总管理员):

    • 职责: 接收客户端的所有操作请求(如“添加新书《算法导论》”);将这些操作写入自己的操作记录本(日志)强制要求所有跟随者复制这个操作记录;在确保操作被安全复制后,通知所有跟随者“可以正式执行这个操作了”(即提交该日志条目);响应客户端操作是否成功。
    • 权力: 独裁者,所有写操作必须经过它。定期给所有跟随者发心跳(Heartbeat) 来维持权威。
  2. Follower (跟随者/分馆管理员):

    • 职责: 被动响应来自领导者的 RPC(远程调用),包括接收并复制领导者发来的操作记录(日志条目)执行领导者通知的已提交的操作(将操作实际应用到自己的状态机,比如更新本地库存表)。如果长时间没收到领导者的心跳,就“揭竿而起”变成候选人,尝试竞选新领导。
    • 状态: 大部分时间节点都处于跟随者状态(一个健康的集群通常只有一个领导者,其余全是跟随者)。
  3. Candidate (候选人/竞选者):

    • 职责: 当跟随者怀疑领导者挂了(心跳超时),就变身候选人,发起一次选举(Election),拉票争取成为新领导者。
    • 临时状态: 这个角色是临时的,只在选举期间存在。选举结束后,成功则成为新领导者,失败则变回跟随者。

Raft 如何工作?(两大核心流程)

一、领导人选举(Leader Election):(目标是选出一个唯一的领导)

  1. 触发: 每个跟随者内部都有一个 选举定时器(Election Timeout)(通常是 150ms-300ms 的随机值)。当这个定时器超时前都没有收到当前领导者的心跳或任何有效RPC,跟随者就认为:“领导可能挂了!”,于是它:

    • 增加自己的 任期号(Term)(一个单调递增的整数,代表不同的朝代)。
    • 切换到 Candidate 状态。
    • 为自己投票。
    • 其他所有节点 发送 请求投票 RPC(RequestVote RPC),请求他们投自己一票。
  2. 投票: 其他节点收到 RequestVote RPC 后,判断:

    • 任期号是否比自己的小? 是 → 拒绝投票。
    • 在同一个任期是否已投过票? 是 → 拒绝投票(一人一票)。
    • 候选人的日志至少和自己一样新吗?(Raft 的 日志完整性检查:比较最后一条日志条目的 Term 和 Index)否 → 拒绝投票(保证新领导的数据不能比跟随者旧)。是 → 同意投票。
    • 如果同意投票,该节点会重置自己的选举定时器(避免自己也发起选举)。
  3. 当选:

    • 候选人收到同一任期内超过半数的投票(包括自己那一票),它就赢得选举,成为该任期的新领导人。
    • 新领导人立即向所有节点发送心跳(AppendEntries RPC,但不包含日志条目),宣告自己掌权,并阻止新的选举。
    • 法定人数(Quorum)规则: 要求多数票(N/2 + 1) 才能当选。这确保了:
      • 领导唯一性: 同一任期内不可能有两个节点都获得多数票。
      • 防止脑裂: 即使网络分区,分裂成两个小群体,也只有包含多数节点的那边能选出新领导(达到多数票),另一边因节点数不足无法选出有效领导,避免了同时有两个领导发号施令。
  4. 选举僵局(分裂投票):

    • 如果第一次选举没有任何候选人获得多数票(比如多个跟随者同时超时竞选),所有候选人超时,增加任期号,重新发起新一轮选举(随机超时时间的设计大大降低了再次冲突的概率)。
    • 最终总有一个候选人能先获得多数票当选。

二、日志复制(Log Replication):(目标是安全、一致地复制操作)

  1. 接收请求: 客户端向领导者发送一个操作(如“Set x=5”)。
  2. 追加本地日志: 领导者将操作作为一个新的日志条目(Log Entry) 追加到自己的操作记录本末尾。该条目包含:
    • 客户端的命令 (Set x=5)
    • 领导者的当前任期号 (Term)
    • 在日志中的索引位置 (Index)
  3. 复制日志: 领导者通过 追加条目 RPC(AppendEntries RPC) 将此新日志条目并行发送给所有跟随者,要求他们复制。
  4. 跟随者响应:
    • 如果跟随者成功复制该条目到本地日志(还没真正执行),则向领导者返回成功
    • 如果跟随者失败(如网络中断、日志冲突),则返回失败。领导者会尝试发送更早的日志条目(或进行冲突解决),直到跟随者追上领导者的日志。
  5. 领导者提交:
    • 当领导者收到超过半数跟随者的成功响应后,认为该日志条目已经安全复制(Committed)。领导者将这个条目应用到自己的状态机(执行命令:把 x 设置成 5)。
    • 领导者通知所有跟随者该条目已提交(在后续的 AppendEntries RPC 中包含最新的已提交索引)。
  6. 跟随者应用: 所有跟随者收到提交通知后,也将该日志条目应用到自己的状态机(执行 Set x=5)。
  7. 响应客户端: 领导者应用成功后,响应客户端操作成功

关键保障机制:

  1. 日志匹配特性(Log Matching Property): Raft 保证:
    • 如果两个节点在相同索引位置有日志条目,且它们的 Term 也相同,那么它们包含的命令相同。
    • 如果一个日志条目在某个 Term 被提交(Committed),那么所有更高任期的领导者的日志中一定包含这个条目,且位置相同
  2. 领导者的日志完整性(Leader Completeness): 选举时强制要求候选人日志必须比多数节点都新(或一样新)。这保证了:
    • 任何已提交的日志条目,最终一定会出现在后续所有领导者的日志中(已提交的条目不会丢失)。
    • 新领导者拥有所有已提交的日志条目,并能强制让其他节点复制这些条目。
  3. 状态机安全(State Machine Safety): 如果一个跟随者在其状态机中应用了一个给定索引的日志条目,那么任何其他节点在其状态机中应用相同索引的日志条目时,必定是同一个命令。这保证了所有节点最终看到的状态一致。

ES (Zen2) vs Raft:

  • 相似点:
    • 都需要法定人数(多数票) 来选举和提交操作,防止脑裂。
    • 都有任期号(Term)的概念。
  • 不同点:
    • 主要目标不同: ES 的主节点选举(Zen1/Zen2)主要解决的是选一个管理元数据的领导。而 Raft 主要解决的是在多个副本之间安全复制操作日志并达成一致状态。ES 7.x 之后的选主机制(基于类似 Raft 的实现)融合了 Raft 的思路(如基于日志的选举投票,而不是 Zen1 简单的版本比较),使其更健壮。
    • 复杂性: Raft 的核心是日志复制协议,选举只是其中的一部分(虽然很关键)。ES 的 Zen 机制相对更专注于选举本身。
    • 领导角色: Raft 的领导者是强领导,负责处理所有客户端请求和日志复制。ES 的协调节点(Coordinating Node)接收请求并路由,主节点(Master)只负责集群状态管理,数据节点(Data Node)负责数据分片上的实际数据操作和搜索。

总结:

Raft 就像一个精心设计的议会民主制+强执行力的领导机制

  1. 选举: 大家通过投票(要求多数票支持)选出一个唯一的领导(任期制)。
  2. 治理: 所有政策(操作命令)都由领导发起,写入议案记录本(日志)。
  3. 立法: 领导必须说服议会超过半数成员(跟随者)同意并记录(复制)该议案。
  4. 生效: 议案获得多数支持后,才正式生效(提交),并通知全国所有地方政府(所有节点)执行该政策(应用到状态机)。
  5. 容错: 领导挂了(心跳超时),立即启动新选举。只要议会(集群)超过半数成员还活着,就能选出新领导继续治理,确保国家(系统)稳定运行。

它的清晰结构(强领导、日志复制、安全性约束)使其比 Paxos 等算法更容易理解和工程实现,成为构建可靠分布式系统(如 etcd, Consul, TiKV, CockroachDB,也包括 ES 7.x+ 的选主模块)的基石。

http://www.dtcms.com/a/325834.html

相关文章:

  • 嵌入式硬件中MOS管图形详解
  • Unity笔记(五)知识补充——场景切换、退出游戏、鼠标隐藏锁定、随机数、委托
  • Mini-Omni: Language Models Can Hear, Talk While Thinking in Streaming
  • 数据库的基本操作(约束与DQL查询)
  • 分治-归并-912.排序数组-力扣(LeetCode)
  • 京东科技集团寻求稳定币链上活动规划师
  • 150V降压芯片DCDC150V100V80V降压12V5V1.5A车载仪表恒压驱动H6203L惠洋科技
  • shape转换ersi json 修改增加多部件要素处理和空洞处理
  • 安卓\android程序开发之基于 Android 的校园报修系统的设计与实现
  • Android.mk教程
  • RFID系统:物联网时代的数字化管理中枢
  • 算法训练营day45 动态规划⑫ 115.不同的子序列、583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结篇
  • Java -- 集合 --Collection接口和常用的方法
  • (3万字详解)Linux系统学习:深入了解Linux系统开发工具
  • leetcode 15 三数之和
  • 【《数字货币量化交易:Linux下策略回测平台的搭建》】
  • 2025-2026 专升本论文写作【八项规范】
  • [202404-B]画矩形
  • 微信小程序常用 API
  • Arcpy-重采样记录
  • B站直播, 拼接4个窗口,能否实现
  • 从源码看 Coze:Agent 的三大支柱是如何构建的?
  • 【优化】图片批量合并为word
  • 嵌入式学习day24
  • MySQL的索引(索引的数据结构-B+树索引):
  • P2865 [USACO06NOV] Roadblocks G
  • 音视频学习(五十三):音频重采样
  • 数据备份与进程管理
  • AI大模型:(二)5.1 文生视频(Text-to-Video)模型发展史
  • Apache ECharts 6 核心技术解密 – Vue3企业级可视化实战指南