【ES】ES基础概念和读写模型整理(基于6.3版本)

菜鸡一只,本文会记录ES的基础概念和读写模型 

闲话:最近其实说忙也忙,说不忙也不太忙,(jira十几个需求。。。但是并不是自己一个人努力做就做完的,都是做一部分,然后需要验证,或者需要其他同事协助的问题)因此在闲下来(等待)的时间里,就会自己看看其他东西。比如之前租了腾讯的服务器,搭了个游戏的私服,但是苦于没时间玩,也没什么朋友一起玩,所以一直闲置在那里,所以就把游戏和数据库保存了,装了个linux系统,在上面装了elasticsearch和kibana用于学习!

我,大数据打杂工,为什么要学elasticsearch呢?是这样子的,对于大数据而言,ES是一个非常普遍而且通用的大数据检索解决方案了。

它的经典场景,我举个例子:我有十万个人的所有发布的文章的正文的数据,给一个很简单的需求,我想知道“赛车”这个名词,在哪些文章被提及,都是哪些人的文章。如果用数据库,就需要使用like '%赛车%'来处理,这性能是非常差的,但是如果用ES,由于ES在插入数据的时候会将数据做索引,本身做了索引之后查询就会变快,而且还有shards(分片)和replication(备份)的功能来实现并发加速查询,这就会使得查询起来非常的迅捷。

不仅如此,它也可以用来做一些监控的数据存储层,通过kibana来做dashboard的展示,非常的方便!

 

缺陷:当然它也是有缺陷的,ES更新太快了,而且更新的时候往往伴有api的更新,导致老版本要升级成新版本的ES,会有代码重构的问题(而且一般要重构的还挺多),升级起来代价打,还有ES对于sql的支持还不是特别友好,只支持一些相对简单的sql,在当今这个各种大数据框架都提供sql的api让用户调用的年代,一个流行的框架对sql支持不友好,势必会被使用者所诟病!

正题:

如果只会操作ES的API好像不太够,往往使用一个框架,会遇到各种各样的bug,特别是在数据量大的情况下一个小小的问题也会被凸显出来,所以我们需要更加详细深入的了解ES的内部机制!

因此我先来记录下ES的读写模型,了解下ES为什么快?

官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/6.3/docs-replication.html

 

在开始之前,我想说三个概念:

1、如果用数据库来类比ES中的架构
 

Relational DBDatabases(库)Tables(表)Rows(行)Columns(字段)
ElasticsearchIndicesTypesDocumentsFields

2、在ES文档中的index有两层含义,第一是:将数据插入ES中,这个过程叫做建立索引(index),第二是:ES可以有不同的index,就好像数据库可以有不同的库(databases)一样

3、默认创建一个index(库),会有5个分片(shard),可以理解为往这个index中插入数据,数据会根据某种规则(官方说是:routing规则)被分成5个文件存储,每个分片会有1个副本,这样总共就会有10个分片。不过如果你的ES集群只有一台机器,那么ES集群将会是黄色的预警模式,因为它不会把相同的副本也存在同一台机器上,因此只有5个分片存在,分片副本无处安放。

 

一、基础的写模型:

以下是我的个人理解和翻译,大家也可以去看英文原文:

1、像ES任意一台机器发起写的请求,首先解决的是根据插入的文档(Documents)的路由来寻找该条记录要插入到哪个分片中,通常是基于文档的id来做判断的

2、一旦确认了要放在哪个分片,就会从ES集群内部将该操作发送到主分片上,由主分片来进行验证(有异常就拒绝操作)和插入操作。

3、该主分片会有对应的副本分片,主分片的机器上会有一个集合来存放在线(可用)的副本分片(有可能会有一些副本分配由于同步数据不及时或者网络机器状态不佳而导致下线),主分片就将这个写入操作发送给这些可用的副本分片(这一步是并行完成的)。这样就完成了数据的写入

4、当这些可用的副本都写入完成的时候,主分片机器就向客户机发出操作确认完成的请求

5、原文还有一些在写入数据的时候遇到故障,ES是如何处理的,大家有兴趣可以读一读

 

二、基础的读模型:

1、读数据可以是简单的基于某个字段或者id查询,也有可能是比较复杂的聚合操作的请求,在写数据的时候主分片会把数据同步到可用的副本中,那么读的时候,就单个同步的副本就可以相应读取请求,因此有副本是很重要的

2、当有一个读取请求发送到ES集群的某台机器上时,该机器就叫做协调节点(coordinating node),它会将读取请求解析成应该读哪个分片

3、确定好读哪个分片之后,默认情况下,ES就会随便(通过round robin 轮询的方式)找一个对应的可用的分片(可以是主分片也可以是副本)发送读取请求,以此来避免将所有的读请求都放到主分片上

4、接受到请求的分片处理得到结果,返回给协调节点,协调节点返回数据给客户端

因此有副本的情况下是可以提高读数据的速度的,但是也因为有副本写入数据就会减慢。

因此官网:https://www.elastic.co/guide/en/elasticsearch/reference/6.3/tune-for-search-speed.html#_replicas_might_help_with_throughput_but_not_always

So what is the right number of replicas? If you have a cluster that has num_nodes nodes, num_primaries primary shards in total and if you want to be able to cope with max_failures node failures at once at most, then the right number of replicas for you is max(max_failures, ceil(num_nodes / num_primaries) - 1).

也可以看看其他的调优文章,但是还是要以官网为主! 

《<漫谈ElasticSearch>关于ES性能调优几件必须知道的事》:https://www.cnblogs.com/guguli/p/5218297.html(作者:Kimmin)

甚至还可以自适应副本数

https://www.elastic.co/guide/en/elasticsearch/reference/6.3/tune-for-search-speed.html#_turn_on_adaptive_replica_selection

Turn on adaptive replica selection

When multiple copies of data are present, elasticsearch can use a set of criteria called adaptive replica selection to select the best copy of the data based on response time, service time, and queue size of the node containing each copy of the shard. This can improve query throughput and reduce latency for search-heavy applications.

 

三、写数据底层原理

1、数据先写入内存buffer和translog日志文件(日志文件默认5s会执行fsync操作,将日志文件写入磁盘,所以理论上来说,写数据的时候宕机,是会存在丢失5s的数据的)

2、默认1s(或者buffer达到一定阈值,或者手动执行)会将buffer数据refresh到一个新的segment file中,但是并不是立即写进磁盘,而是先写到系统的缓存中(os cache),当触发refresh的操作的时候,会清空对应的buffer,但是会保留translog(日志是写到磁盘持久化的),这样即使机器异常,下次重启的时候也可以从日志中重新读取到数据

注意:只有数据进到os cache层往后,数据才能被搜索到,所以ES是准实时的框架(默认延迟是1s)

3、当磁盘上的translog越来越大,就会触发flush操作(默认30分钟或者日志文件达到512M执行一次)

官网:https://www.elastic.co/guide/en/elasticsearch/reference/6.3/index-modules-translog.html#_translog_settings

-1.将buffer数据全部写到os cache中,清空buffer

-2.将一个commit point写入到磁盘中,它记录当前所有可用的segment,每个commit point都会维护一个.del文件(es删除数据本质是不属于物理删除),当es做删改操作时首先会在.del文件中声明某个document已经被删除,文件内记录了在某个segment内某个文档已经被删除,当查询请求过来时在segment中被删除的文件是能够查出来的,但是当返回结果时会根据commit point维护的那个.del文件把已经删除的文档过滤掉

-3.将os cache层的所有数据写入磁盘,清空当前translog日志,重启一个新的日志文件

4、当磁盘中存在越来越多的segment file,就会占用太多系统的文件句柄,因此需要merge

在老版本(1.X的版本)ES的merge限制每秒的速率来放置他影响写入数据,但是反而会因为merge跟不上而导致宕机等问题,后来的版本一直在对merge做改进,6.3的版本是通过设置index.merge.scheduler.max_thread_count,用几条线程来做合并操作,来控制速率的

官网:https://www.elastic.co/guide/en/elasticsearch/reference/6.3/index-modules-merge.html

-1.这个操作就是将小segment合并成大的segment

-2.合并的时候,会生成一个新的segment,会通过commit point来过滤掉那些被标识为删除或者已经是被更新过的老数据,不会将这些数据合并到新的segment上

-3.删除那些已经被合并处理过的segment

-4.可以手动触发合并

因此总结下:

write->【写入buffer和translog】

refresh->【每1s开启一个segment file,但是先写入os cache,清空buffer】

flush->【日志写入磁盘】

merge->【合并小文件】

 

这里允许我贴一张别人的图上来,因为我觉得实在画的很棒:

《ES 写数据底层原理》:https://www.cnblogs.com/hbbbs/articles/9096504.html(作者:HB1)

 

老话,菜鸡一只,本文其实集合了非常多文章的内容,而且也贴出了很多官方文档的链接,我发现ES的文档还是描述的比较简单的,如果想对ES有一定了解的,我十分推荐把官方的文档从头到尾看一遍,又因为ES每个版本区别比较大,所以建议还是看对应的版本的文档!!如果对本文有任何疑问,欢迎留言!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值