Elasticsearch - 基础篇

Elasticsearch - 基础篇

Scroll Down

这一章节主要讲解Elasticsearch的几个基础概念,掌握了基础之后,我们就可以真正的开始搜索引擎之旅了。

基础概念:

  • 集群
  • 节点
  • 索引
  • 类型
  • 文档
  • 分片
  • 全文检索
  • 倒排索引

集群(cluster)

  • 可以将多个ES节点作为集群使用,可以在任何一台节点上进行搜索。集群有一个默认的名称(可修改),“elasticsearch”,这个集群名称必须是唯一的,因为集群的节点是通过集群名称来加入集群的。确保在相同环境中不要有相同的集群名称,否则有可能节点会加入到非预期的集群中。

节点(node)

  • 节点是作为集群的一部分的单个服务器,存储数据,并且参与集群的索引和搜索功能。与集群一样,节点由一个名称标识,默认情况下,该名称是在启动时分配给节点的随机通用唯一标识符(UUID)。如果不希望使用默认值,则可以定义所需的任何节点名称。此名称对于管理目的很重要,因为您希望确定网络中的哪些服务器对应于ElasticSearch集群中的哪些节点。

一个节点(node)就是一个Elasticsearch实例,而一个集群(cluster)由一个或多个节点组成,它们具有相同的cluster.name,它们协同工作,分享数据和负载。当加入新的节点或者删除一个节点时,集群就会感知到并平衡数据。

至于索引、类型、文档的概念,如果对MySQL熟悉的同学可以这样子理解

186C3EF0A0EB4679A7FDE23CB2505287_1_201_a.jpeg

注意:在7.x版本版本中已经移除了types概念,一个index下只能有一个type(https://www.elastic.co/guide/en/elasticsearch/reference/7.x/removal-of-types.html) 所以这一点与mysql对比来说,还是有很大的差别,上图的对比只是给刚入门的同学有一个大概的认识。

分片(shards)

  • 每个索引有一个或多个分片,索引的数据被分配到各个分片上,相当于一桶水用了N个杯子装

副本(replica)

  • 可以理解为备份分片,相应地有primary shard(主分片)。处理查询时可以把这些副本当做主分片来对待(primary shard),此外副本策略提供了高可用和数据安全的保障,当分片所在的机器宕机,Elasticsearch可以使用其副本进行恢复,从而避免数据丢失

主副分片设计的优点:

  • 容灾:主分片丢失,副分片就会被顶上去成为新的主分片,使用其副本进行恢复
  • 提高查询性能:与主分片的数据相同,所以分担查询负载,在合适的范围内多个replica性能会更优(但要考虑资源占用也会提升[cpu/disk/heap]),另外index request只能发生在主分片上,replica不能执行index request。
  • 对于一个索引,除非重建索引否则不能调整分片的数目(主分片数, number_of_shards),但可以随时调整replica数(number_of_replicas)
  • 便于横向扩展。新增node3的时候,node1和node2的一个分片会迁移到node3。
    image.png

路由(routing)

  • 在存入时通过路由键将数据存入指定分片,在查询的时候可以通过相同的路由键指明在哪个分片将数据查出来。

    • 默认情况下,索引数据的分片算法如下
      shard_num = hash(_routing) % num_primary_shards
      routing值是一个任意字符串,它默认是_id但也可以自定义
  • 这也解释了为什么主分片的数量只能在创建索引时定义且不能修改:如果主分片的数量在未来改变了,所有先前的路由值就失效了,文档也就永远找不到了

全文检索

  • 全文检索就是对一篇文章进行索引,可以根据关键字搜索,类似于mysql里的like语句。 把内容根据词的意义进行分词,然后分别创建索引,例如“你们的激情是因为什么事情来的” 可能会被分词成:“你们”,“激情”,“什么事情”,“来”等token,这样当你搜索“你们” 或者 “激情” 都会把这句搜出来。

倒排索引(inverted index)

  • 倒排索引也叫反向索引,有反向索引必有正向索引。通俗地来讲,正向索引是通过key找value,反向索引则是通过value找key。

image.png

上图是一个倒排索引的简单例子,每个字段拆分,并且与主键ID关联

这里简单讲解一下,Elasticsearch数据写入磁盘的一些知识点
  • 一个Index由若干个segment组成,搜索的时候按段搜索,我们索引一条段后,每个段会通过fsync 操作持久化到磁盘,而fsync 操作比较耗时,如果每索引一条数据都做这个full commit(rsync)操作,提交和查询的时延都非常之大,所以在这种情况下做不到实时的一个搜索

image.png

  • 为了解决这个问题,尽可能的提高es的读写性能。引入一层称为FileSystem Cache的系统缓存。只要sengment文件被写入cache后,这个sengment就可以打开和查询,从而确保在短时间内就可以搜到,而不用执行一个full commit也就是fsync操作,这是一个非常轻量级的处理方式而且是可以高频次的被执行,而不会破坏es的性能。

image.png

  • 这个轻量级的写入和打开一个cache中的segment的操作叫做refresh,默认情况下,es集群中的每个shard会每隔1秒自动refresh一次,这就是我们为什么说es是近实时的搜索引擎而不是实时的,也就是说给索引插入一条数据后,我们需要等待1秒才能被搜到这条数据,这是es对写入和查询一个平衡的设置方式,这样设置既提升了es的索引写入效率同时也使得es能够近实时检索数据