系统中的数据,随着业务的发展,时间的推移,将会非常多,而业务中往往采用模糊查询进行数据的搜索,而模糊查询会导致查询引擎放弃索引,导致系统查询数据时都是全表扫描,在百万级别的数据库中,查询效率是非常低下的,而我们使用 ES 做一个全文索引,将经常查询的系统功能的某些字段,比如说电商系统的商品表中商品名,描述、价格还有 id 这些字段我们放入 ES 索引库里,可以提高查询速度。
Elasticsearch
的选主是 ZenDiscovery
模块负责的,主要包含 Ping
(节点之间通过这个 RPC
来发现彼此)和 Unicast
(单播模块包含一个主机列表以控制哪些节点需要 ping
通)这两部分master
的节点(node.master: true
、node.roles: [master,data]
)根据 nodeId
字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第 0
位)节点,暂且认为它是 master
节点master
节点数 n/2+1
)并且该节点自己也选举自己,那这个节点就是 master
。否则重新选举一直到满足上述条件master
节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data
节点可以关闭 http
功能master
,认为 master
挂掉了从而选举出新的 master
,并对 master
上的分片和副本标红,分配新的主分片master
又为 data
,访问量较大时可能会导致 ES
停止响应造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点data
节点上的 ES
进程占用的内存较大,引发 JVM
的大规模内存回收,造成 ES
进程失去响应discovery.zen.ping_timeout
节点状态的响应时间,默认为 3s
,可以适当调大master
在该响应时间的范围内没有做出响应应答,判断该节点已经挂掉了。调大参数(如 6s,discovery.zen.ping_timeout:6
),可适当减少误判discovery.zen.minimum_master_nodes:1
(n/2)+1
,n
为主节点个数(即有资格成为主节点的节点个数)master
节点与 data
节点分离,限制角色node.master: true node.data: false
/ node.roles: [master]
node.master: false node.data: true
/ node.roles: [data]
ID
参与计算(也支持通过 routing
),以便为路由提供合适的分片:shard = hash(document_id) % (num_of_primary_shards)
Memory Buffer
,然后定时(默认是每隔 1 秒)写入到 Filesystem Cache
,这个从 Memory Buffer
到 Filesystem Cache
的过程就叫做 refresh
Momery Buffer
和 Filesystem Cache
的数据可能会丢失,ES 是通过 translog
的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到 translog
中,当 Filesystem cache
中的数据写入到磁盘中时,才会清除掉,这个过程叫做 flush
flush
过程中,内存中的缓冲将被清除,内容被写入一个新段,段的 fsync
将创建一个新的提交点,并将内容刷新到磁盘,旧的 translog
将被删除并开始一个新的 translog
flush
触发的时机是定时触发(默认 30
分钟)或者 translog
变得太大(默认为 512M
)时.del
文件。当删除请求发送后,文档并没有真的被删除,而是在 .del
文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在 .del
文件中被标记为删除的文档将不会被写入新段.del
文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉Query Then Fetch
from + size
的优先队列。PS:在搜索的时候是会查询 Filesystem Cache
的,但是有部分数据还在 Memory Buffer
,所以搜索是近实时的ID
和排序值 给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表GET
请求。每个分片加载并丰富文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端Query Then Fetch
的搜索类型在文档相关性打分的时候参考的是本分片的数据,这样在文档数量较少的时候可能不够准确,DFS Query Then Fetch
增加了一个预查询的处理,询问 Term
和 Document frequency
,这个评分更准确,但是性能会变差gateway.recover_after_nodes
、gateway.expected_nodes
、gateway.recover_after_time
可以在集群重启的时候避免过多的分片交换,这可能会让数据恢复从数个小时缩短为几秒钟(CMS)
和各个线程池的大小Lucene
(但不要超过 32GB),通过 ES_HEAP_SIZE
环境变量设置swapping
对于性能是多么可怕Lucene
使用了大量的文件。同时,Elasticsearch 在节点和 HTTP 客户端之间进行通信也使用了大量的套接字。 所有这一切都需要足够的文件描述符。你应该增加你的文件描述符,设置一个很大的值,如 64000
补充:索引阶段性能提升方法
5MB – 15MB
大是个不错的起始点SSD
20MB/s
,对机械磁盘应该是个不错的设置。如果你用的是 SSD
,可以考虑提高到 100 – 200MB/s
。如果你在做批量导入,完全不在意搜索,你可以彻底关掉合并限流。另外还可以增加 index.translog.flush_threshold_size
设置,从默认的 512MB
到更大一些的值,比如 1GB
,这可以在一次清空触发的时候在事务日志里积累出更大的段index.refresh_interval
改到 30s
index.number_of_replicas: 0
关闭副本data node
上 segment memory
增长趋势field cache
, filter cache
, indexing cache
, bulk queue
等等,要设置合理的大小,并且要应该根据最坏的情况来看 heap
是否够用,也就是各类缓存全部占满的时候,还有 heap
空间可以分配给其他任务吗?避免采用 clear cache
等「自欺欺人」的方式来释放内存scan
& scroll api
来实现cluster stats
驻留内存并无法水平扩展,超大规模集群可以考虑分拆成多个集群通过 tribe node
连接heap
够不够,必须结合实际应用场景,并对集群的 heap
使用情况做持续的监控Elasticsearch 提供的首个近似聚合是 cardinality
度量。它提供一个字段的基数,即该字段的 distinct
或者 unique
值的数目。它是基于 HLL算法
的。HLL
会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits
做概率估算从而得到基数。其特点是:可配置的精度,用来控制内存的使用(更精确 = 更多内存);小的数据集精度是非常高的;我们可以通过配置参数,来设置去重需要的固定内存使用量。无论数千还是数十亿的唯一值,内存使用量只与你配置的精确度相关。
quorum/one/all
,默认为 quorum
,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建replication
为 sync(默认)
,这使得操作在主分片和副本分片都完成后才会返回;如果设置 replication
为 async
时,也可以通过设置搜索请求参数 _preference
为 primary
来查询主分片,确保文档是最新版本elasticsearch-head
插件通过 Kibana
监控 Elasticsearch
。你可以实时查看你的集群健康状态和性能,也可以分析过去的集群、索引和节点指标。
my-es-application
。此名称很重要,因为如果节点设置为按名称加入群集,则该节点只能是群集的一部分MySQL
=> 数据库; Elasticsearch
=> 索引倒排索引是搜索引擎的核心。搜索引擎的主要目标是在查找发生搜索条件的文档时提供快速搜索。ES 中的倒排索引其实就是 lucene 的倒排索引,区别于传统的正向索引,倒排索引会在存储数据时将关键词和数据进行关联,保存到倒排表中,然后查询时,将查询内容进行分词后在倒排表中进行查询,最后匹配数据即可。