0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

简述ElasticSearch的实现

马哥Linux运维 来源:CSDN技术社区 作者:cdai 2021-10-20 14:45 次阅读

1.近实时搜索

1.1 实时与近实时

实时搜索(Real-time Search)很好理解,对于一个数据库系统,执行插入以后立刻就能搜索到刚刚插入到数据。而近实时(Near Real-time),所谓“近”也就是说比实时要慢一点点。

1.2 近实时的挑战

对于一个单机系统来说,这也并不容易实现,因为还要保证数据的持久化,还要利用缓存等技术加快数据的访问(注:这里不讨论内存计算系统)。对于ElasticSearch这样一个分布式系统,保证持久化的同时,还要初始化好用于全文检索的内部数据结构,做到近实时的难度可想而知。而这就是ElasticSearch大获成功的地方,也正是本文所要学习的主题:ElasticSearch是如何解决这些实现近实时搜索的难题的。

2.ElasticSearch的实现

2.1 不可变的数据结构

有经验的程序员一定知道,在做并发编程时,控制可变数据的并发访问是个难题。古往今来,各种粗细粒度的锁,信号量,Actor模型等概念层出不穷。而另一流派函数式编程更为彻底,尤其是纯函数式比如Haskell,用不可变数据来彻底解决这个问题。

在ElasticSearch这样主要服务全文检索的系统中,Inverted Index是核心数据结构。这里简单说一句,Inverted Index本质上一组document中term的各种统计信息,比如最重要的词频,以及其他许多统计信息,比如文档长度,词序等等。要做到近实时搜索,就要保证新数据能快速构建,已有数据能被高速访问。解决问题的关键就在于Inverted Index的不可变性,这也是ElasticSearch底层依赖的高性能Lucene的根本奥秘。

2.2 从不可变到可变

所以当用户向ElasticSearch中的数据库插入一组document后,底层Lucene构建出一个不可变的Inverted Index。可我们知道,一个数据库不可能是静态的,当用户再次插入新数据时,Lucene该怎样处理呢?答案就是增量保存和逻辑标记。

所谓增量保存就是为新数据构建一个新的不可变的Inverted Index,当执行搜索时,要合并每个Inverted Index中的统计信息得到最终结果。保存新数据的问题解决了,而逻辑标记就是解决更新和删除的。Lucene为每个Inverted Index都额外维护一个del数据结构,当执行删除时,只需在del中标记,这样最终结果就会排出掉删除掉document。同理,更新时也是给老数据做标记,新document会保存在新的Inverted Index中,最终结果会使用最新版本数据的统计信息。在Lucene中,每个Inverted Index叫做Segment,而管理这些Segment的叫做Index。

ElasticSearch中一个数据库被称为Index,每个Index可以在创建时指定要划分为几份,每一份叫做Shard。Shard会被ElasticSearch分配到不同结点,运行中还会根据压力做Rebalance。这个Shard其实就是Lucene中的Index。由于不同层级上名字的重复,初学时很容易混淆。

这种思想其实并非独创,在其他一些高级数据结构中也能找到它的影子。如果没记错的话,一个经典的例子就是LSM树:https://en.m.wikipedia.org/wiki/Log-structured_merge-tree。

2.3 分布式数据存储

对于分布式的数据存储,ElasticSearch采取了经典的做法,对数据进行分片和路由,这里每个分片Shard就是一个Lucene数据库Index。对于有副本replica的Shard,ElasticSearch操作完primary后,再去同步到replica。

2.4 挑战磁盘I/O

现在我们已经可以高效地维护全文检索的数据结构,也遵循经典做法解决了分布式数据存储。可就像前面提到的,还有个挑战就是磁盘读写的巨大开销。Lucene的做法是,每个Segment在文件系统Cache中构建起来就可以被访问,同步到磁盘的fsync之后才会执行。Lucene的Index内部的Commit Point会记住哪些Segment还未同步。ElasticSearch默认每隔1秒会用Buffer中的document新建一个Segment,这个操作叫做refresh。正因为这1秒钟的间隔,ElasticSearch支持的是近实时而非实时。

一个很自然的问题就是每秒钟都会新建一个Segment,那Lucene Index中的Segment个数岂不是很容易就爆炸了。每个Segment都是一个物理文件,操作系统中打开文件的句柄个数是有限的,而且即便不考虑上限,过多Segment也会拖慢搜索,因为前面讲过一次搜索的最终结果是要合并所有Segment中的统计信息的。

ElasticSearch的做法是维护一个后台线程去做Merge,Merge的过程中不仅将多个小Segment合并成大的,同时还会排除掉删除或修改的文件的老版本,最终修改Commit Point排除掉老的Segment,这样那些“垃圾”document就彻底被删除了。得益于Segment的不可变性,后台进程Merge时并不会影响数据插入和搜索的性能。

2.5 保证数据不丢失

一个可以预料到的问题就是,如果当前结点上的ElasticSearch进程意外中止,那Buffer中等待处理的document和未同步到磁盘的Segment中的数据都会丢失。为了避免这一点,ElasticSearch引入了传统数据库中所谓的Write-Ahead Log(WAL)日志,ElasticSearch为其起名为translog。每次插入Buffer时,都会同时写入translog。下面的图示清晰地展示ElasticSearch是如何与Lucene配合的。

当创建新Segment时,Buffer清空,但translog会一直保留到Segment同步到磁盘才会清空。所以当ElasticSearch重启时,先根据Commit Point将所有之前已经commit到磁盘的Segment恢复到Cache,然后再重放(replay)translog中的所有操作。默认每30分钟或者translog很大时,ElasticSearch做一次full commit,即flush操作。

继续刨根问底,translog保证了Buffer和Segment的安全,谁来保证它的安全呢?默认情况下,translog每5秒钟会同步到磁盘,也就是说我们至多会丢失5秒到数据。因为translog只是原始的请求document,所以这里的写磁盘开销是远小于Segment的一次commit的。

3.题外话:如何深入学习ElasticSearch

以本文为例,谈一谈如何学习ElasticSearch。在有了一些分布式系统和开发经验后,像本文2.3和2.5节是完全可以跳过的。前者是分布式系统的通用做法,而后者则早已存在于传统数据库中。要掌握ElasticSearch,基本用法和系统命令是一方面,而设计中的精华往往在前文2.1和2.2中。光理解了设计还不行,就像前面说过的,思想可能流传已久,但做出来东西的质量则可能千差万别。“天下大事,必做于细”,实现中的精髓只能在源代码中体会。

其实这种方法在另一篇文章里也提到过,就是学一门编程语言时也是要抓住它的精髓,而不是每门语言都花很多时间去学基本语法,而没有精力去掌握精华,最终迷失了。在此再次强调一下,自己也引以为戒。

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    7006

    浏览量

    88957
  • 编程
    +关注

    关注

    88

    文章

    3614

    浏览量

    93698
  • 函数
    +关注

    关注

    3

    文章

    4329

    浏览量

    62578
  • 单机
    +关注

    关注

    0

    文章

    15

    浏览量

    6281

原文标题:ElasticSearch近实时搜索的实现

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    企业如何用ELK技术栈实现数据流量爆炸式增长

    ELK简介 什么是ELK 通俗来讲,ELK 是由 Elasticsearch、Logstash、Kibana 三个开源软件的组成的一个组合体,ELK 是 elastic 公司研发的一套完整的日志收集
    的头像 发表于 12-19 11:38 69次阅读
    企业如何用ELK技术栈<b class='flag-5'>实现</b>数据流量爆炸式增长

    Elasticsearch 再次开源

    Elasticsearch 和 Kibana 又可以被称为开源了。很难表达这句话让我有多高兴。我激动得简直要跳起来了。我们 Elastic 的所有人都是如此。开源是我的 DNA。这也是Elastic的DNA。能够再次将 Elasticsearch 称为开源,我感到非常高兴
    的头像 发表于 11-13 12:14 130次阅读
    <b class='flag-5'>Elasticsearch</b> 再次开源

    基于TI以太网Retimer芯片在网络系统应用简述

    电子发烧友网站提供《基于TI以太网Retimer芯片在网络系统应用简述.pdf》资料免费下载
    发表于 09-27 11:03 0次下载
    基于TI以太网Retimer芯片在网络系统应用<b class='flag-5'>简述</b>

    基于AFE79xx的JESD204C应用简述

    电子发烧友网站提供《基于AFE79xx的JESD204C应用简述.pdf》资料免费下载
    发表于 09-27 09:23 0次下载
    基于AFE79xx的JESD204C应用<b class='flag-5'>简述</b>

    气压制动系统工作原理简述

    气压制动系统的工作原理可以简述如下: 一、系统概述 气压制动系统是一种通过压缩空气来实现制动的技术,广泛应用于汽车行业中,特别是大型商用车和重型车辆。该系统利用发动机驱动的空气压缩机产生压缩空气,并
    的头像 发表于 09-18 15:44 651次阅读

    简述基本与非门sr锁存器的结构及工作原理

    基本与非门SR锁存器(Set-Reset Latch)是数字电路中的一种基础元件,用于存储一位二进制数据。它由两个互补的与非门(NAND gate)组成,通过这两个与非门的交叉反馈实现状态的锁存
    的头像 发表于 08-28 11:01 1648次阅读

    软件系统的数据检索设计

    软件系统的数据检索设计 随着业务量加大,数据检索量也会日益增多,为了减轻数据库压力,本系统采用ElasticSearch实现数据检索功能。 简单来说,Elasticsearch 是一个实时的分布式
    的头像 发表于 08-22 14:08 256次阅读
    软件系统的数据检索设计

    统一日志数据流图

    统一日志数据流图 日志系统数据流图 系统进行日志收集的过程可以分为三个环节: (1)日志收集和导入ElasticSearch (2)ElasticSearch进行索引等处理 (3)可视化操作,查询等
    的头像 发表于 08-21 15:00 305次阅读
    统一日志数据流图

    简述拉曼散射效应的实现过程

    拉曼散射效应,作为一种重要的光学现象,其实现过程涉及光与物质之间复杂的相互作用。以下将详细阐述拉曼散射效应的实现过程,包括基本原理、实验观察、理论解释以及应用等方面。
    的头像 发表于 08-16 17:08 502次阅读

    Elasticsearch Mapping类型修改

    原创声明:该文章是个人在项目中亲历后的经验总结和分享,如有搬运需求请注明出处。 这是“深入浅出系列”文章的第一篇,主要记录和分享程序设计的一些思想和方法论,如果读者觉得所有受用,还请“一键三连”,这是对我最大的鼓励。 一、老生常谈,到底啥是可读性 一句话:见名知其义。有人说好的代码必然有清晰完整的注释,我不否认;也有人说代码即注释,是代码简洁之道的最高境界,我也不否认。但我都不完全接受,如果照搬前者,有
    的头像 发表于 08-09 16:00 125次阅读

    简述开关电源两类漏电流的区别

    引言:在日常工作中,硬件设计工程师朋友们经常会接触到漏电流这个指标,其分为泄漏电流和耐压漏电流。本文将简述开关电源两类漏电流的区别,并简要分析了常见漏电流异常的问题,同时给出了对应的验证方法和解决及预防的办法,保障系统可靠性。
    的头像 发表于 08-06 15:24 1052次阅读
    <b class='flag-5'>简述</b>开关电源两类漏电流的区别

    简述四种基本触发器及其功能

    在数字电路设计中,触发器是一种基本且重要的存储元件,用于存储二进制信息(即0和1)。根据功能和应用场景的不同,触发器可以分为多种类型,其中四种基本触发器包括RS触发器、JK触发器、D触发器和T触发器。以下是对这四种基本触发器及其功能的详细简述
    的头像 发表于 07-27 14:59 9314次阅读

    简述半导体原理——晶体管家族的核心工作机制

    简述半导体原理——晶体管家族的核心工作机制
    的头像 发表于 07-20 08:14 964次阅读
    <b class='flag-5'>简述</b>半导体原理——晶体管家族的核心工作机制

    鸿蒙媒体开发【简述

    媒体系统架构 媒体系统提供用户视觉、听觉信息的处理能力,如音视频信息的采集、压缩存储、解压播放等。在操作系统实现中,通常基于不同的媒体信息处理内容,将媒体划分为不同的模块,包括:音频、视频(也称播放
    发表于 02-28 17:53

    Rust编写的首个Postgres基础Elasticsearch开源替代品问世

    ,Firebase 开源替代 Supabase,AirTable 开源替代 NocoDB,等等等等,现在又多了 ElasticSearch 开源替代 —— ParadeDB。
    的头像 发表于 02-22 11:34 836次阅读
    Rust编写的首个Postgres基础<b class='flag-5'>Elasticsearch</b>开源替代品问世