Elasticsearch
Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上。
https://github.com/ZhongFuCheng3y/3y 引用Java3y
Elasticsearch会对文字进行分词
- 这些分词汇总起来我们叫做
Term Dictionary
,而我们需要通过分词找到对应的记录,这些文档ID保存在PostingList
。 - 在
Term Dictionary
中的词由于是非常非常多的,所以我们会为其进行排序, - Term Dictionary还抽了一层叫做
Term Index
,这层只存储 部分 词的前缀
Term Index
在内存中是以FST(Finite State Transducers)的形式保存的,其特点是非常节省内存。
PostingList
会使用Frame Of Reference(FOR)编码技术对里边的数据进行压缩,节约磁盘空间。
Elasticsearch术语
- Index:Elasticsearch的Index相当于数据库的Table
- Document:Document相当于数据库的一行记录
- Field:相当于数据库的Column的概念
- Mapping:相当于数据库的Schema的概念
- DSL:相当于数据库的SQL(给我们读取Elasticsearch数据的API)
Elasticsearch的架构
一个Elasticsearch集群会有多个Elasticsearch节点,所谓节点实际上就是运行着Elasticsearch进程的机器。
在众多的节点中,其中会有一个Master Node
,它主要负责维护索引元数据、负责切换主分片和副本分片身份等工作,如果主节点挂了,会选举出一个新的主节点。
一个Index的数据我们可以分发到不同的Node上进行存储,这个操作就叫做分片。分片会有主分片和副本分片之分。数据写入的时候是写到主分片,副本分片会复制主分片的数据,读取的时候主分片和副本分片都可以读。如果某个节点挂了,前面所提高的Master Node
就会把对应的副本分片提拔为主分片,这样即便节点挂了,数据就不会丢。
分片的好处
- 如果一个Index的数据量太大,只有一个分片,那只会在一个节点上存储,随着数据量的增长,一个节点未必能把一个Index存储下来。
- 多个分片,在写入或查询的时候就可以并行操作(从各个节点中读写数据,提高吞吐量)
Elasticsearch 写入的流程
Elasticsearch写入数据的时候,是写到主分片上的。
集群上的每个节点都是coordinating node
(协调节点),协调节点表明这个节点可以做路由。
coodinate(协调)节点通过hash算法可以计算出是在哪个主分片上,然后路由到对应的节点
路由到对应的节点以及对应的主分片时,会做以下的事:
- 将数据写到内存缓存区
- 然后将数据写到translog缓存区
- 每隔1s数据从buffer中refresh到FileSystemCache中,生成segment文件,一旦生成segment文件,就能通过索引查询到了
- refresh完,memory buffer就清空了。
- 每隔5s中,translog 从buffer flush到磁盘中
- 定期/定量从FileSystemCache中,结合translog内容
flush index
到磁盘中。
Elasticsearch更新和删除
- 给对对应doc记录打上.del标识
- 删除则打上delete状态,更新则在此之后重新写入一条数据
- 每隔1s会生成一个segement 文件,那segement文件会越来越多越来越多。Elasticsearch会有一个merge任务,会将多个segement文件合并成一个segement文件。在合并的过程中,会把带有
delete
状态的doc
给物理删除掉。
Elasticsearch查询
查询我们最简单的方式可以分为两种:
- 根据ID查询doc
- 根据query(搜索词)去查询匹配的doc
由于Elasticsearch是分布式的,所以需要从各个节点都拉取对应的数据,然后最终统一合成给客户端。