项目用到了,看了3y哥的文章自己记录一下加强印象
内容来源:「扫盲」 Elasticsearch (qq.com)
什么是elasticsearch
Elasticsearch 是一个实时的分布式存储、搜索、分析的引擎。
要想了解es我们就要明白这几个加粗的词。
为什么要用 es就像它的名字,我们要用它就是为了搜索。那问题就来了,在日常开发中,我们可以使用sql语句直接对数据库进行查询,为什么还要用es呢? 因为有这方面的问题
- 用户可能会输错,那么如果使用数据库就无法更正
- 使用数据库进行搜索可能无法走索引,导致全表扫描,降低搜索的速度
- 使用数据库搜索的结果是全部匹配的,有可能我们不需要这么多。
es是一个专门的搜索引擎,它可以解决好上面的问题:
- Elasticsearch对模糊搜索非常擅长(搜索速度很快)
- 从Elasticsearch搜索到的数据可以根据评分过滤掉大部分的,只要返回评分高的给用户就好了(原生就支持排序)
- 没有那么准确的关键字也能搜出相关的结果(能匹配有相关性的记录)
es的数据结构
当我们输入查询的语句,es会对语句进行分词操作,并显示每个分出的词在哪里出现了。 这种根据某个词(不完整的条件)再查找对应记录,叫做倒排索引。
es内部置有分词器
- Standard Analyzer 。按词切分,将词小写
- Simple Analyzer。按非字母过滤(符号被过滤掉),将词小写
- WhitespaceAnalyzer。按照空格切分,不转小写
- ….等等等
es的数据结构具体长这样
当我们输入一段文字后es就会对我们输入的文字进行分词操作,这些分词汇总起来叫做Term Dictionary ,通过分词找到的相关记录就放在PostingList中,Term Dictionary会被排序,然后使用二分法进行查询。
由于Term Dictionary内容太大了,不可能将所有的内容都放入内存当中,所以又有了Term Index 用于在内存中记录,这里只存储部分记录。
Term Index 的结构是FST(Finite State Transducers)字典数据结构。
特点是非常节省内存。FST有两个优点:
- 1)空间占用小。通过对词典中单词前缀和后缀的重复利用,压缩了存储空间;
- 2)查询速度快。O(len(str))的查询时间复杂度。
同时PostingList也会有对应的优化。它会使用Frame Of Reference(FOR)编码技术对里边的数据进行压缩,节约磁盘空间。
同时PostingList里边存的是文档ID,我们查的时候往往需要对这些文档ID做交集和并集的操作(比如在多条件查询时),PostingList使用Roaring Bitmaps来对文档ID进行交并集操作。好处就是可以节省空间和快速得出交并集的结果。
es的术语
- Index:Elasticsearch的Index相当于数据库的Table
- Type:这个在新的Elasticsearch版本已经废除(在以前的Elasticsearch版本,一个Index下支持多个Type--有点类似于消息队列一个topic下多个group的概念)
- Document:Document相当于数据库的一行记录
- Field:相当于数据库的Column的概念
- Mapping:相当于数据库的Schema的概念
- DSL:相当于数据库的SQL(给我们读取Elasticsearch数据的API)
es的结构框架
一个es集群会有多个es的节点,一个节点就是一个运行着es的机器。
在众多节点中有一个Mast Node,它负责维护索引元数据、负责切换主分片和副本分片身份等工作。如果它挂了,那么就会由其他节点选举产生一个新的Mast Node。
上面提到的Mast Node负责的分片是什么呢?在术语中我们知道了Index类似于数据库中的表,将一个Index的数据分配到不同的节点上存储就是分片。
使用分片的原因有下面几点
- 如果只有一个节点,随着数据量的增大,一个节点未必能存储完一个完整的index。
- 有多个分片,在查询或写入时可以进行并行操作。(从各个节点中读写数据,提高吞吐量)
为了防止节点挂掉导致数据丢失,es实行了主副分片机制,也就是先将数据写入到主分片,然后再副分片复制数据,主副分片不在同一个节点上。在读取数据的时候主副分片都能读。
如果主分片挂了,那么MastNode会把副分片提为主分片。
es写入数据时干了什么
客户端写入一条信息后,就由集群中的节点来负责处理,节点都是coordinating node(协调节点),协调节点表明这个节点可以做路由。比如节点1接收到了请求,但发现这个请求的数据应该是由节点2处理(因为主分片在节点2上),所以会把请求转发到节点2上。
- coodinate(协调)节点通过hash算法可以计算出是在哪个主分片上,然后路由到对应的节点
shard = hash(document_id) % (num_of_primary_shards)
路由到其对应节点和对应主分片时做的事概括为:写内存缓冲区(定时(1s)去生成segement,生成translog),能够让数据能被索引、被持久化。最后通过commit完成一次的持久化。
es的更新和删除
更新和删除的操作:- 给对应的doc记录打上.del标识,如果是删除操作就打上delete状态,如果是更新操作就把原来的doc标志为delete,然后重新新写入一条数据。
每隔1s会生成一个segement 文件,那segement文件会越来越多越来越多。Elasticsearch会有一个merge任务,会将多个segement文件合并成一个segement文件。
在合并的过程中,会把带有delete状态的doc给物理删除掉。
es的查询
查询我们最简单的方式可以分为两种:
- 根据ID查询doc
- 根据query(搜索词)去查询匹配的doc
通过id查询的顺序是:查询内存的Translog,查询硬盘的Translog,查询硬盘的Segement
通过query查询的过程看不懂了,看懂了再回来重新写写。