1.适用场景

* 数据量特别大,需要各种复杂查询(全文搜索功能、相似度搜索与比较、模糊匹配、地理位置聚合、搜索内容多语言支持与分词支持等)、聚合并尽量实时的场景。

* 大量数据写入频繁,但更新较少,查询较多的情况

* 数据模型后期存在大概率变动或不确定性等(改数据库结构会导致业务代码不稳定性)

* 数据体量较大或者增量较快但是变更较小的情况(如海量日志数据:ELK)

2.基础的一些概念

1.节点(node)

es中有四中节点,四种不同类型的Node是一个node.master和node.data的true/false的两两组合

1.master

负责保存和更新集群的一些元数据信息,之后同步到所有节点,所以每个节点都需要保存全量的元数据信息:

* 集群的配置信息

* 集群的节点信息

* 模板template设置

* 索引以及对应的设置、mapping、分词器和别名

* 索引关联到的分片以及分配到的节点

2.datanode

* 负责实际的数据存储和查询

3.coordinator

* 路由索引请求

* 聚合搜索结果集

* 分发批量索引请求

4.ingestor

* 类似于logstash,对输入数据进行处理和转换

2.分片(sharding)

        es中的分片,类似于数据库中的分库分表。分片是其支持分布式和负载均衡的关键。一个索引可以有多个分片,它们会均衡地分布在集群的机器中。要注意的是在设置分片的时候需要注意的是不能太少,也不能太多,因为太少的话会限制其并发能力和后期的一个集群扩展能力。并发能力都可以理解应该。会影响集群里节点的扩展是由于,单个分片只支持分布在一台机器上如果说分片数小于等于集群的机器了,那再怎么扩容机器其实也无用的。那分片是不是越多越好呢?当然也不是了,物极必反,因为es默认的集群分片数是1000,当索引分片过多时,就会出现后期由于分片上限后创建失败的情况出现。还有就是es的底层还是依赖与lucene引擎,而它也是比较耗内存的,分片越多对内存的占用也就越多,并且每个查询请求都会打到这个索引下的所有分片,然后在聚合,所以分片过多也会导致查询反而变慢。这个后面会介绍。

3.数据副本(replica)

        顾名思义它是es拿来当分片副本的,也可以叫做副本分片,一个主分片可以存在多个副本分片。合理地设置副本分片,可以提升es的一个查询效率和高可用性以及扩展性。

1.高可用:

        因为副本分片和主分片是不会在同一个节点上的,这样就避免了单点故障,在主分片出故障时,副本分片就会顶上去,并同时根据当前配在相应增加会更新副本分片,保障系统稳定。

2.提升性能:

        同时由于副本分片的数据是主分片数据一致的,所有searchRequest可以打到主分片也可以打到副分片,这样就提高了查询性能,由于主副分片不能在同一节点上,所以如果设置了副分片但是又都部署在一个节点上,这时候副分片会创建失败,es的状态会变为yellow黄色(关于es状态灯的描述后续会讲一下)。但也正是由于主副分片数据一致这个特性如果副分片设置过多也会增加系统负担,甚至降低查询效率,因为es的写入策略是先写入对应的主分片,然后在设置了副分片的前提下,至少有一个副分片返回写入成功才会响应此次写入成功,同时分片,对于cpu、负载的占用也是一笔开销。所以尽可能合理分配自己副本分片数量,避免适得其反。

3.扩展性:

        因为主分片在上线后是不可修改的,但是副本分片可以,提升了扩展的能力。

4.es集群的状态

        上面有提到yellow状态灯,es目前是有三哥状态灯,红、黄、绿,代表它的将康状态依次增强分别。

红灯:

        至少有一个主分片没有准备就绪,此时整个集群可能会出现数据丢失和查询不准报错的现象

黄灯:

        所有主分片都准备就绪了,但是至少有一个主分片的副分片没有准备就绪,可能 会出现在原有副分片异常或者扩容副分片节点时失败、大量数据写入等情况下出现,问题不大,但也要值得注意,因为如果黄灯持续时间较长极有可能转为红灯。

绿灯:

        表示主副分片节点都处于健康状态。

5.倒排索引

        通常来说,索引是为了优化查询检索来使用的,常规的是直接建立索引键key和数据data之间的映射关系,检索的时候命中索引键将大大提升检索效率,也就是说是通过key来检索出来value。而倒排索引则相反是通过检索value匹配出一系列的key,再通过key检索出完整的data的过程。当然还有其他一列的优化手段,类似于索引压缩、查询结果集合并等等,使得正常情况下,倒排索引的检索效率甚至高于b+Tree的效率。

具体的检索过程后续介绍。

4.一些重要的内部策略

1.节点选主策略

        作为一款优秀的中间件,它也有自己对应的一些高可用策略,比如主节点节点容灾里的选主等。首先整个集群中也是以心跳机制来检测除自身以外的节点的可用性。当一个集群内多数节点发现主节点不可用时,会启动主节点投票流程。首先每个节点都会查询一遍集群中是否已存在主节点,如果是直接选择join该主节点,如果不存在,则查询当前主节点候选节点列表,并判断该数量是否满足选举的最小原则。不满足则会选举失败,再次重新开始选举流程。如果数量达标,则会进行对当前候选节点列表中id最小的节点进行投票,并统计票数,判断是否多数从节点投票一致。若不一致则也会重新开始选举。如果一致,会判断当前节点是否为主节点,如果不是会发送join请求加入到当选的主节点,如果是会校验当前join进来的节点数是否达到候选节点数的一半,达到了表示选举成功,选举结束,否则选举失败重新选举。

** 值的注意的点是,选举过程中会出现脑裂现象也就是产生了两个master,这会导致集群内数据的不一致、数据丢失等一系列异常情况,而脑裂产生的原因有很多,比如网络抖动从节点投票给某一节点后,虽然被投票节点顺利晋升,但是由于网络问题投票节点未收到反馈,又再次投票也就是一个节点再一次选举中多次投票。这个后面es引入了投票周期的概念来解决,其实也就是类似于版本号。而我们在使用可以通过适当配置心跳ping的超时时间、ping的次数。以及选举时需要的节点连接数,一般过半原则,特别要注意的是在做扩容时要注意调整这个参数。**

#一个节点多久ping一次,默认1s
discovery.zen.fd.ping_interval: 5s
##等待ping返回时间,默认30s
discovery.zen.fd.ping_timeout: 30s
##ping超时重试次数,默认3次
discovery.zen.fd.ping_retries: 5
##选举时需要的节点连接数,N为具有master资格的节点数量
discovery.zen.minimum_master_nodes=N/2+1

es 基本 es基本偏差_big data

 

2.数据写入策略

        数据写入流程:首先是数据文档写入内存缓冲区,在这个阶段不可被查询,紧接着会进行refresh操作将数据构建成文档写入到文件系统的缓冲区和translog,这时候数据就可以被检索到了(这个自动会刷,可以配置refresh_interval 频次)也可以手动刷,在刷新这个阶段,内存缓冲区会被清除,但是translog内数据直到刷磁盘前还是存在。接着会刷从translog刷盘到磁盘(顺序写入保证了高效),这个默认是异步的所以当写入请求打进来后在translog写完后就会返回成功,当然也可以配置同步刷盘如果对数据的安全性要求很高的话。但同样这也必将会牺牲写入的响应速度和吞吐量。这就是大致的一个写入过程了。