| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> ES 的存储原理 -> 正文阅读 |
|
[大数据]ES 的存储原理 |
目录 4.3、刷入 refresh 页缓存的同时,写入 translog 一、ES是什么
二、ES基本结构2.1、结构图?如上图所示,假如在1个主shared,1个副本的配置下,主和replica会分布在不同的Node节点上,起到一个容灾的作用。 replica只负责复制Primary给下来的数据,只有当primary挂了,他才上位。 2.2、基本概念
2.3、与关系数据库概念的类比
分片(Shard)在数据库概念映射里面类似于分表(水平拆分) index、type的初衷 之前es将index、type类比于关系型数据库(例如mysql)中database、table,这么考虑的目的是“方便管理数据之间的关系”。 【本来为了方便管理数据之间的关系,类比database-table 设计了index-type模型】 a.?在关系型数据库中table是独立的(独立存储),但es中同一个index中不同type是存储在同一个索引中的(lucene的索引文件),因此不同type中相同名字的字段的定义(mapping)必须一致。如果是mysql,两个table中的age字段,2个table可以分别定义成int和string,但是es不行,必须一样 b. 不同类型的“记录”存储在同一个index中,会影响lucene的压缩性能。 2.4、数据如何读写1、所有数据的处理都由 Primary Shared去处理
2、假如客户端请求 Node2 写入数据,比如是往spu-record这个index写入数据,此时根据路由字段(一般是主键id)路由到数据应该写入到分片3 Shared3 上,那么此时会找到分片3所在的节点Node3,Node2转发请求给Node3去处理,Node3写入Primary主分片,写入后同步给分片3的副本Replica,同步数据成功后,会告知Node3接收数据成功,Node3发送写入成功Reponse告知Node2,Node2把response发给客户端。 3、读取数据如下图,假如请求Node2,但是数据在Node3,那么会转发请求到Node3去拿到数据转发给客户端。 2.5 容灾能力1、假如服务器 Node3 挂了 2、Node3上有2个primary节点,shared3 和 shared7,此时 Node1 上的shared7的副本会晋升成 Primary Shard,Node4 上的 shared3 的副本也会晋升成 Primary Shard?。晋升后,即可马上对外提供服务。 3、由于配置了副本数是1,所以会把已经丢失的 s3 s7 s2 s5这四个 shard 在其他Node上复制一份。(如果有200G数据,千兆网络,拷贝完需要1600秒。如果没有replica,则这1600秒内这些Shard就不能服务。) 三、ES的文件存储结构1、如何去服务器找到es的配置文件
2、找到文件夹所在位置 es.path.home
找到 config文件夹
找到es服务的配置文件?elasticsearch.yml
找到 path.data
tree 命令,或者?find . -type d -maxdepth 3 上面的 foo 是索引名称,有些可能用索引的 uuid 代替。 data/elasticsearch/nodes/0(这个0是固定的)/indices/foo/0 (这个0是foo位于这个Node上的shard分片) 每个分片的事务日志(Transaction Log)Elasticsearch事务日志确保可以安全地将数据索引到Elasticsearch,而无需为每个文档执行低级Lucene提交。提交Lucene索引会在Lucene级别创建一个新的segment,即执行fsync(),会导致大量磁盘I / O影响性能。 为了接受索引文档并使其可搜索而不需要完整的Lucene提交,Elasticsearch将其添加到Lucene IndexWriter并将其附加到事务日志中。在每个refresh_interval之后,它将在Lucene索引上调用reopen(),这将使数据可以在不需要提交的情况下进行搜索。这是Lucene Near Real Time API的一部分。当IndexWriter最终由于自动刷新事务日志或由于显式刷新操作而提交时,先前的事务日志将被丢弃并且新的事务日志将取代它。 如果需要恢复,将首先恢复在Lucene中写入磁盘的segments,然后重放事务日志,以防止丢失尚未完全提交到磁盘的操作。 Index文件夹内文件含义(lucene文件夹)
四、存储步骤页缓存?(文件系统缓存)?为了提升对文件的读写效率,Linux 内核会以页大小(4KB)为单位,将文件划分为多数据块。当用户对文件中的某个数据块进行读写操作时,内核首先会申请一个内存页(称为 整体存储步骤流程图?? 4.1、写入缓存(内存)Doc会先被搜集到内存中的Buffer内,这个时候还无法被搜索到,如下图所示: 4.2、refresh 刷入页缓存(文件系统缓存)Lucene支持对新段写入和打开,可以使文档在没有完全刷入硬盘的状态下就能对搜索可见,而且是一个开销较小的操作,可以频繁进行。 下面是一个已经将Docs刷入段,但还没有完全提交的示意图: 我们可以看到,新段虽然还没有被完全提交,但是已经对搜索可见了。 引入refresh操作的目的是提高ES的实时性,使添加文档尽可能快的被搜索到,同时又避免频繁fsync带来性能开销,依靠的就是文件系统缓存OS cache里缓存的文件可以被打开(open/reopen)和读取,而这个os cache实际是一块内存区域,而非磁盘,所以操作是很快的,这就是ES被称为近实时搜索的原因。 refresh默认执行的间隔是1秒,可以使用 4.3、刷入 refresh 页缓存的同时,写入 translogtranslog记录的是已经在内存生成(segments)并存储到os cache但是还没写到磁盘的那些索引操作。 index segment刷入 refresh 到os cache后就可以打开供查询,这个操作是有潜在风险的,因为os cache中的数据有可能在意外的故障中丢失,而此时数据必备并未刷入到os disk,此时数据丢失将是不可逆的,这个时候就需要一种机制,可以将对es的操作记录下来,来确保当出现故障的时候,已经落地到磁盘的数据不会丢失,并在重启的时候可以从操作记录中将数据恢复过来。elasticsearch提供了translog来记录这些操作,结合os cached segments数据定时落盘来实现数据可靠性保证(flush)。 文档被添加到buffer同时追加到translog: 4.4、数据 flush 落盘 disk?每隔一段时间(例如translog变得太大),index会被flush到磁盘,新的translog文件被创建,commit执行结束后,会发生以下事件:
4.5、Translog的页缓存(内存缓存)translog本身也是磁盘文件,频繁的写入磁盘会带来巨大的IO开销,因此对translog的追加写入操作的同样操作的是os cache,因此也需要定时落盘(fsync)。translog落盘的时间间隔直接决定了ES的可靠性,因为宕机可能导致这个时间间隔内所有的ES操作既没有生成segment磁盘文件,又没有记录到Translog磁盘文件中,导致这期间的所有操作都丢失且无法恢复。 translog的fsync是ES在后台自动执行的,默认是每5秒钟主动进行一次translog fsync,或者当translog文件大小大于512MB主动进行一次fsync,对应的配置是
当 Elasticsearch 启动的时候, 它会从磁盘中使用最后一个提交点去恢复已知的段,并且会重放 translog 中所有在最后一次提交后发生的变更操作。 translog 也被用来提供实时 CRUD 。当你试着通过ID来RUD一个Doc,它会在从相关的段检索之前先检查 translog 中最新的变更。 默认 这样会带来一些性能损失,可以通过设为异步fsync,但是必须接受由此带来的丢失少量数据的风险。
4.6 flush
满足下列条件之一就会触发冲刷操作:
?4.7 整体存储步骤讲解
五、Es的其他操作5.1、Doc删除删除一个ES文档不会立即从磁盘上移除,它只是被标记成已删除。因为段是不可变的,所以文档既不能从旧的段中移除,旧的段也不能更新以反映文档最新的版本。 ES的做法是,每一个提交点包括一个 5.2、Doc更新 = 删除 + 新增文档的更新操作和删除是类似的:当一个文档被更新,旧版本的文档被标记为删除,新版本的文档在新的段中索引。 5.3、段合并通过每秒自动刷新创建新的段,用不了多久段的数量就爆炸了,每个段消费大量文件句柄,内存,cpu资源。更重要的是,每次搜索请求都需要依次检查每个段。段越多,查询越慢。 ES通过后台合并段解决这个问题。ES利用段合并的时机来真正从文件系统删除那些version较老或者是被标记为删除的文档。被删除的文档(或者是version较老的)不会再被合并到新的更大的段中。 可见,段合并主要有两个目的:
ES对一个不断有数据写入的索引处理流程如下:
合并过程如图: 从上图可以看到,段合并之前,旧有的Commit和没Commit的小段皆可被搜索。 段合并后的操作:
合并完成后新的段可被搜索,旧的段被删除,如下图所示: 注意:段合并过程虽然看起来很爽,但是大段的合并可能会占用大量的IO和CPU,如果不加以控制,可能会大大降低搜索性能。段合并的optimize API 不是非常特殊的情况下千万不要使用,默认策略已经足够好了。不恰当的使用可能会将你机器的资源全部耗尽在段合并上,导致无法搜索、无法响应。
参考文章 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/25 2:42:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |