赞
踩
Welcome to Elastic Docs | Elastic
ES的整体结构?
1)正排就是我记得我电脑有个文档,讲了 ES 的常见问题总结。那么我就找到文档,从上往下翻
页,找到 ES 的部分。通过文档找文档内容。
2)倒排:一个 txt 文件 ES 的常见问题 -> D:/分布式问题总结.doc。
所以倒排就是文档内容找文档。当然内容不是全部的,否则也不需要找文档了,内容就是几个分词
而已。这里的 txt 就是搜索引擎。
通俗解释:
传统的我们的检索是通过文章,逐个遍历找到对应关键词的位置。
而倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典+映射表即为倒排索引。
有了倒排索引,就能实现 o(1)时间复杂度的效率检索文章了,极大的提高了检索效率。
学术解释:
倒排索引,相反于一篇文章包含了哪些词,它从词出发,记载了这个词在哪些文档中出现过,由两部分组成——词典和倒排表。
加分项:倒排索引的底层实现是基于:FST(Finite State Transducer)数据结构。
lucene 从 4+版本后开始大量使用的数据结构是 FST。FST 有两个优点:
1)空间占用小。通过对词典中单词前缀和后缀的重复利用,压缩了存储空间;
2)查询速度快。O(len(str))的查询时间复杂度。
ElasticSearch 是集群的 = 主分片 + 副本分片
写索引只能写主分片,然后主分片同步到副本分片上。但主分片不是固定的,可能网络原因,之前
还是 Node1 是主分片,后来就变成了 Node2 经过选举成了主分片了。
客户端如何知道哪个是主分片呢? 看下面过程。
1) 客户端向某个节点 NodeX 发送写请求
2) NodeX 通过文档信息,请求会转发到主分片的节点上
3) 主分片处理完,通知到副本分片同步数据,向 Nodex 发送成功信息
4) Nodex 将处理结果返回给客户端
1)客户端向集群发送请求,集群随机选择一个 NodeX 处理这次请求。
2)Nodex 先计算文档在哪个主分片上,比如是主分片 A,它有三个副本 A1,A2,A3。那么请求
会轮询三个副本中的一个完成请求。
3)如果无法确认分片,比如检索的不是一个文档,就遍历所有分片。
补充一点,一个节点的存储量是有限的,于是有了分片的概念。但是分片可能有丢失,于是有了副
本的概念。比如:ES 集群有 3 个分片,分片 A、分片 B、分片 C,那么分片 A + 分片 B + 分片 C = 所有数据,每个分片只有大概 1/3。分片 A 又有副本 A1 A2 A3,数据都是一样的
通过分步骤看数据持久化过程:write -> refresh -> flush -> merge
(1)write
一个新文档过来,会存储在 in-memory buffer 内存缓存区中,顺便会记录 Translog(Elasticsearch 增加了一个 translog ,或者叫事务日志,在每一次对 Elasticsearch 进行操作时均进行了日志记录)。
(2)refresh
in-memory buffer 中的文档写入到新的 segment 中,清空 in-memory buffer。文档经过 refresh 后, segment 暂时写到文件系统缓存数据只有被 refresh 后,才可以被搜索到。refresh 默认 1 秒钟,一般建议稍微延长这个 refresh 时间间隔,比如 5 s。因此,ES 其实就是准实时,达不到真正的实时。
(3)flush
文档从文件缓存写入磁盘的过程就是 flush。写入磁盘后,清空 translog。
(4)merge
Elasticsearch通过在后台进行Merge Segment来解决这个问题。小的段被合并到大的段,然后这些大的段再被合并到更大的段。
硬件配置优化 包括三个因素:CPU、内存和 IO。
索引方面优化
查询方面优化
1)可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖,由应用层来处理具体的冲突;
2)另外对于写操作,一致性级别支持 quorum/one/all,默认为 quorum,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建。
3)对于读操作,可以设置 replication 为 sync(默认),这使得操作在主分片和副本分片都完成后才会返回;如果设置 replication 为 async 时,也可以通过设置搜索请求参数_preference 为 primary 来查询主分片,确保文档是最新版本。
一个索引被分解成碎片以便于分发和扩展。副本是分片的副本。一个节点是一个属于一个集群的
ElasticSearch的运行实例。一个集群由一个或多个共享相同集群名称的节点组成。
Elasticsearch 提供的首个近似聚合是 cardinality 度量。它提供一个字段的基数,即该字段的 distinct 或者 unique 值的数目。它是基于 HLL 算法的。HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。其特点是:可配置的精度,用来控制内存的使用(更精确 = 更多内存);小的数据集精度是非常高的;我们可以通过配置参数,来设置去重需要的固定内存使用量。无论数千还是数十亿的唯一值,内存使用量只与你配置的精确度相关。
query 是查询+score, 而filter仅包含查询, 比如在复合查询中constant_score查询无需计算score,所以对应查询是filter而不是query。
term是基于索引的词项,而match基于文本。
should是任意匹配,must是同时匹配。
match本质上是对term组合,match_phrase本质是连续的term的查询(and关系),match_phrase_prefix在match_phrase基础上提供了一种可以查最后一个词项是前缀的方法
简单而言:让上一步的聚合结果成为下一个聚合的输入,这就是管道。
如何理解?
第一个维度:管道聚合有很多不同类型,每种类型都与其他聚合计算不同的信息,但是可以将这些类型分为两类:
第二个维度:根据功能设计的意图
比如前置聚合可能是Bucket聚合,后置的可能是基于Metric聚合,那么它就可以成为一类管道
进而引出了:xxx bucket
avg
平均值max
最大值min
最小值sum
和value_count
数量cardinality
基数(distinct去重)weighted_avg
带权重的avgmedian_absolute_deviation
中位值stats
包含avg,max,min,sum和countmatrix_stats
针对矩阵模型extended_stats
string_stats
针对字符串percentiles
百分数范围percentile_ranks
百分数排行geo_bounds
Geo boundsgeo_centroid
Geo-centroidgeo_line
Geo-Linetop_hits
分桶后的top hitstop_metrics
21.
ES性能优化之缓存Elasticsearch 应用时会使用各种缓存,而缓存是加快数据检索速度的王道。接下来,我们将着重介绍以下三种缓存:
➢ 页缓存:操作系统级别的缓存
➢ 分片级请求缓存:节点级别的缓存
➢ 查询缓存:功能缓存
其他提高检索速度的方法:
1)从操作系统的角度提高IO效率
2)从jvm的角度提高IO效率
(1) 程序同步
直接在代码里写逻辑,数据在增删改查进数据库的同时,也往es里同步一份。
优点:方便,无需集成其他的技术;
缺点:代码耦合性太高,增加接口的处理时间;
(2) logstash
定时查询数据库,查询到数据有变化就发送到es中。
优点:解耦,官方推荐。
缺点:
1)不支持同步删除,当然可以在数据库用逻辑删除代替物理删除,对于logstash来说就是更新操作了;
2)大数据量有性能问题,在对数据库的压力上,logstash的原理是定时扫描变动的表,所以对数据库有一定压力,并且如果有其他程序在进行某条语句更新,锁住了这条行数据,那logstash读取数据时,就会被“卡住”,如果这个时间过长,可能会影响服务器卡死。
3)无法做到实时同步,只能秒级同步。
如果实时性要求不高,并且定时时间内数据变化量不大,推荐使用这个,学习维护成本比较低,毕竟是官方推荐,ELK全家桶。
(3) canal
利用数据库的binlog同步变化数据,然后将数据发送给es,当然也可以通过java代码监听拿到数据,再发送到es或做其他处理。
优点:解耦,实时同步,没有大数据性能压力。
缺点:学习和维护成本高,要求对数据库有创建用户的权限,毕竟要用到数据库同步功能,开启binlog数据库的压力也会增加。
(4) MQ中间件
有数据变化的时候,就通知mq,然后监听mq实现数据同步到mq。
优点:解耦,适合高并发。
缺点:如何保证消息可靠性,需要在业务代码中加入发送消息到MQ的代码。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。