elasticsearch记录

110 阅读6分钟

项目用到了,看了3y哥的文章自己记录一下加强印象

内容来源:「扫盲」 Elasticsearch (qq.com)

什么是elasticsearch

Elasticsearch 是一个实时分布式存储、搜索、分析的引擎。
要想了解es我们就要明白这几个加粗的词。

为什么要用 es就像它的名字,我们要用它就是为了搜索。那问题就来了,在日常开发中,我们可以使用sql语句直接对数据库进行查询,为什么还要用es呢? 因为有这方面的问题

  1. 用户可能会输错,那么如果使用数据库就无法更正
  2. 使用数据库进行搜索可能无法走索引,导致全表扫描,降低搜索的速度
  3. 使用数据库搜索的结果是全部匹配的,有可能我们不需要这么多。

es是一个专门的搜索引擎,它可以解决好上面的问题:

  • Elasticsearch对模糊搜索非常擅长(搜索速度很快)
  • 从Elasticsearch搜索到的数据可以根据评分过滤掉大部分的,只要返回评分高的给用户就好了(原生就支持排序)
  • 没有那么准确的关键字也能搜出相关的结果(能匹配有相关性的记录)

es的数据结构

当我们输入查询的语句,es会对语句进行分词操作,并显示每个分出的词在哪里出现了。 这种根据某个词(不完整的条件)再查找对应记录,叫做倒排索引

es内部置有分词器

  • Standard  Analyzer 。按词切分,将词小写
  • Simple Analyzer。按非字母过滤(符号被过滤掉),将词小写
  • WhitespaceAnalyzer。按照空格切分,不转小写
  • ….等等等

es的数据结构具体长这样

image.png

当我们输入一段文字后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的数据分配到不同的节点上存储就是分片。

使用分片的原因有下面几点

  1. 如果只有一个节点,随着数据量的增大,一个节点未必能存储完一个完整的index。
  2. 有多个分片,在查询或写入时可以进行并行操作。(从各个节点中读写数据,提高吞吐量)

为了防止节点挂掉导致数据丢失,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查询的过程看不懂了,看懂了再回来重新写写。