我们用ES作日志检索和简单分析,它适用于全文搜索,近实时分析,也可以作为nosql存储(订单的冷库接入ES),需要关注架构,单机的功能(搜索原理,动态索引),性能(索引和数据组织),分布式的可靠性,可扩展,一致性。
概述
搜索引擎和NoSQL数据库功能,用于全文搜索,结构化搜索,近实时分析[竞品:Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch
]
指南:https://es.xiaoleilu.com/020_...
常用:E(存储和索引)L(数据转换和解析Beat采集过来)K(可视化)
逻辑架构图:
Local FileSystem等。存储:索引信息,集群内信息,mapping,transaction log
lucene directory lucene不同存储层服务发现的抽象,FSDirectory,RAWDirectory 控制索引文件的位置
discovery Zen 服务发现+选主
river:数据源 mq等
memcached协议:get/set/delete/quit
高可用、可扩展、一致性
- 集群发现与故障处理:
服务发现+选主,ping,rsp包含节点基本信息和该节点认为的master节点,支持非奇数,信息不对等时会有脑裂,要求ping所有节点。返回其他节点认为的主节点,也返回候选主节点(配置中master!=false)。如果第一个不为空,直接选节点最小的,若为空,候选节点>discovery.zen.minimum_master_nodes则选一个状态+nodeid最小的,否则失败。思想就是有旧的master活着尽量用,投票都要达到法定人数。
主节点是群集中唯一可以更改群集状态的节点。主节点一次处理一个群集状态更新,应用所需的更改并将更新的群集状态发布到群集中的所有其他节点。每个节点接收发布消息,ack,但不将改变同步到本地的集群状态。如果主服务器discovery.zen.minimum_master_nodes在一定时间内没有从至少节点收到确认(由discovery.zen.commit_timeout设置控制并默认为30秒),则拒绝集群状态更改,重新选主。
无主时默认不能写 - 一致性
上述主节点有变更时,等待从节点的ack,收到大多数则变更,同步从节点,等待所有从节点的确认才返回客户端。这里所有从节点指的是Allocation IDs中的节点。从节点不可用时,主分片所在节点命令主节点将差异分片的Allocation IDs从同步集合(in-sync set)中删除。然后,主分片所在节点等待主节点删除成功的确认消息,这个确认消息意味着集群一致层(consensus layer)已成功更新,之后,才向客户端确认写请求。这样确保只有包含了所有已确认写入的分片副本才会被主节点选为主分片。
节点的重新加入:Translog+checkpoint
每个写操作都会分配两个值,Term和SequenceNumber.LocalCheckpoint代表本Shard中所有小于该值的请求都已经处理完毕。GlobalCheckpoint会由Primary进行维护,每个Replica会向Primary汇报自己的LocalCheckpoint,Primary根据这些信息来提升GlobalCheckpoint。GlobalCheckpoint是一个全局的安全位置,代表其前面的请求都被所有Replica正确处理了,可以应用在节点故障恢复后的数据回补。 - 分片机制:索引键值hash%分片数量。主分片+副本分片
水平扩展(分片数量不能改变,只能改变每个节点有几个分片,每个分片副本分散到哪些节点)
单节点存储瓶颈等时扩展:
处理瓶颈时扩展:
master和节点统一。master只负责索引的创建和删除 - 负载均衡:轮询
数据处理过程
节点对等写入和读取。写入只能在P分片然后同步复制到R分片,读写转发到主节点或副本节点
- 更新过程:
-
搜索:需要先查询排序再取回排序中想要的数据
其中查询:
1)node3创建from+size优先队列
2)请求转发个每个分片,每个分片自己获取from+size本地优先队列
3)返回给node3合并产生全局排序
搜索有两种:基于短语的、全文索引
1)基于短语的:低级查询,没有分析,精确查找(加not_analyzed)
2)match,query_string这种高级查询,会产生短语列表和低级查询结合,得到文档相关度。
Elasticsearch通过下面的步骤执行match查询:GET /my_index/my_type/_search { "query": { "match": { "title": "QUICK!" } } } 1.检查field类型,title字段是一个字符串(analyzed),所以该查询字符串也需要被分析(analyzed) 2.分析查询字符串,查询词QUICK!经过标准分析器的分析后变成单词quick。因为我们只有一个查询词,因此match查询可以以一种低级别term查询的方式执行。 3.找到匹配的文档 term查询在倒排索引中搜索quick,并且返回包含该词的文档。 4.为每个文档打分 term查询综合考虑词频(每篇文档title字段包含quick的次数)、逆文档频率(在全部文档中title字段包含quick的次数)、包含quick的字段长度(长度越短越相关)来计算每篇文档的相关性得分_score。 因为match查询需要查询两个关键词:"brown"和"dog",在内部会执行两个term查询并综合二者的结果得到最终的结果。match的实现方式是将两个term查询放入一个bool查询 https://es.xiaoleilu.com/100_Full_Text_Search/05_Match_query.html
数据组织
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引(=》分片=》segment) ⇒ 类型 ⇒ 文档 ⇒ 字段(Fields)
- 索引
只是一个用来指向一个或多个分片(shards)的“逻辑命名空间(logical namespace)”. - 分片
就是一个Lucene实例,文档存储在分片中,并且在分片中被索引
每个分片上包含此分片的所有数据索引和数据,我们的elk,每天都是一个新库(index),为其建立traceid,urlkey索引的含义只是创建索引,并不对所有词都建立倒排索引,虽然本身es每个词都可搜索 - 词=》倒排索引
包含每个filed(term)在每个文档中的值
写入磁盘的倒排索引是不可变的.不需要加锁,不需要重建任何缓存,可以压缩数据 -
动态索引、近实时索引:
Luence per-segment search 索引:段的集合+提交点(包含所有段的文件)
1.当一个文档被索引,它被加入到内存缓存,同时加到事务日志。 2.refresh使得分片的进入如下图描述的状态。每秒分片都进行refeash: 内存缓冲区的文档写入到段中,但没有fsync。 段被打开,使得新的文档可以搜索。 缓存被清除 3.随着更多的文档加入到缓存区,写入日志,这个过程会继续 4.不时地,比如日志很大了,新的日志会创建,会进行一次全提交: 内存缓存区的所有文档会写入到新段中。 清除缓存 一个提交点写入硬盘 文件系统缓存通过fsync操作flush到硬盘 事务日志被清除
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。