Elasticsearch是什么
Elasticsearch(ES)是一个基于Apache Lucene构建的开源、分布式、RESTful接口全文搜索引擎。它提供了一个分布式多用户能力的全文搜索引擎。Elasticsearch还是一个分布式文档数据库,每个字段都是被索引的数据并且可以被搜索,它能够扩展至数以百计的服务器存储以及处理PB级的数据。
全文搜索是指计算机搜索程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,搜索程序就会根据事先建立的索引进行查找,并将查询结果返回给用户。
Elasticsearch是一个面向文档型数据库,一条数据在Elasticsearch中就是一个文档,用JSON作为文档序列化的格式。
Elasticsearch和关系数据库属于对照:
关系数据库 =》 数据库Databases =》 表Tables =》 行Rows =》 列Columns
Elasticsearch =》 索引Indices =》 类型Types =》 文档Documents =》 字段Fields
Elasticsearch集群可以包含多个索引,每个索引可以包含很多类型,每个类型中可以包含很多文档,每个文档可以包含很多的字段。
术语与概念
集群(cluster)
代表一个集群,集群中有多个节点node,其中一个为主节点,这个主节点可以通过选举产生的,主节点是对于集群内部来说的。ES的一个概念就是去中心化,字面上理解就是无中心化节点,这是对于集群外部来说的,因为从外部来看ES集群,在逻辑上是一个整体,你与任何一个节点的通信和整个ES集群通信是等价的
一个集群就是由一个或者多个节点组织在一起,它们共同持有整个的数据,并在一起提供索引和搜索功能。一个集群由一个唯一的名字标识。一个节点只能通过指定某个集群的名字,来加入这个集群。
节点(node)
一个节点是集群中的一个服务器,作为集群的一部分,存储数据,参与集群的索引和搜索功能。一个节点也是由一个名字来标识的。默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点,这个名字对于管理工作来说挺重要的,因为在这个管理过程中,要确定网络中的哪些服务器对应于Elasticsearch集群中的哪些节点。
索引(index)
ES将它的数据存储在一个或多个索引(index)中。类似sql中的数据库。可以向索引中写入文档或者读取文档,并通过ES内部使用Lucene将数据索引或从索引中检索数据
一个索引就是一个拥有几分相似特征的文档的集合(类似于我们在数据库中的库结构),一个索引由一个名字来标识,并且在我们要对对这个索引中的文档进行索引,搜索,更新和删除的时候,都要使用到这个名字。
文档(document)
文档是ES中主要的实体。对所有使用ES的案例来说,他们最终都可以终结为对文档的搜索。文档由字段构成。
映射(mapping)
所有文档写进索引之前都会先进行分析,如果将输入的文本分割为词条,哪些词条又会被过滤,这种行为叫做映射(mapping)。一般由用户自己定义规则
类型(type)
每个文档都有与之对应的类型定义。这允许用户在一个索引中存储多种文档类型,并为不同文档类型提供不同的映射
分片(shards)
shards代表索引分片,ES可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
分片有两个好处,一是可以水平扩展,另一个是可以并发提高性能。
副本(replicas)
代表索引副本,ES可以设置多个索引副本,副本的作用一是提高系统的容错性,实现高可用(HA),当某个节点某个分片损坏或丢失时可以从副本中恢复;二是提高ES的查询效率,ES会自动对搜索请求进行负载均衡。
数据恢复(recovery)
代表数据恢复或叫数据重新分布,ES在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复
数据源(river)
代表ES的一个数据源,也是其他存储方式(如:数据库)同步数据到ES的一个方法。它是以插件的方式存在的一个ES服务,通过river中的数据并把它索引到ES中,官方的river有couchDB的,RabbitMQ的
网关(gateway)
代表ES索引的持久化存储方式,ES默认是先把索引存放达到内存中,当内存满了时再持久化到硬盘。当这个ES集群关闭再重新启动的时候就会从gateway中读取索引数据。ES支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,hadoop的hdfs和amazon的s3云存储服务
自动发现(discovery.zen)
代表ES的自动发现节点机制,ES是一个p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互
通信(transport)
代表ES内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时支持http协议(json格式),thrift,selvert,memcached,zeroMQ等传输协议(通过插件方式集成)
候选主节点(Master-eligible Node)
一个节点启动后,就会使用Zen Discovery机制去寻找集群中的其他节点,并与之建立连接。集群中会从候选主节点中选举出一个主节点,主节点负责创建索引、删除索引、分配分片、追踪集群中的节点状态等工作。
数据节点(Data Node)
数据节点负责数据的存储和相关具体操作,比如CRUD,搜索,聚合。所以,数据节点对机器配置要求比较高,首先需要有足够的磁盘空间来存储数据,其他数据操作对系统CPU,Memory和IO的性能消耗都很大。通常随着集群的扩大,需要增加更多的数据节点来提高可用性。
ES集群的三种状态
- Green:所有主分片和备份分片都准备就绪(分配成功),即使有一台机器挂了,数据也不会丢失,但是会变成Yellow状态。
- Yellow:所有主分片准备就绪,但存在至少一个主分片对应的备份分片没有就绪,此时集群属于警告状态,意味着集群高可用和容灾能力下降。如果刚好A所在的机器挂了,并且你只设置了一个备份(已处于未就绪状态),那么A的数据就会丢失(查询结果不完整),此时集群进入Red状态。
- Red:至少有一个主分片没有就绪(找不到对应的备份分片称为新的主分片),此时查询的结果会出现数据丢失。
什么是Shard
- ES是一个分布式的搜索引擎,每个索引有一个或者多个分片,索引的数据被分配到各个分片上,相当于一桶水用N的杯子装
- 分片有助于横向扩展,N个分片会被尽可能平均(rebalance)分配到不同的节点上(relocation过程)
- 分片是独立的,对于一个search request的行为,每个分片都会执行这个request
- 每个分片都是一个Lucene Index,所以一个分片只能存放Integer.MAX_VALUE-128d个docs。
什么是Replica
- 复制,备份分片,相应的有primary shard
- 主分片和备份分片不会出现在同一个节点上(防止单点故障),默认情况下一个索引创建5个分片一个备份(5 primary + 5 replica = 10 shard)
Replica的主要作用
- 高可用:Primary分片丢失,Replica分片就会被顶上去成为新的主分片,同时根据这个新的主分片创建新的replica,集群数据安然无恙。
- 提高查询性能:replica和primary分片的数据是相同的,所以对于一个query既可以查询主分片也可以查询备份分片,在合适的范围内,多个replica性能会更优,但是占用更多的资源(cpu/disk/heap),index request只能发生在主分片上,replica不能执行index request。搜索可以在所有的Replica分片上并行运行,因此可以扩展集群的搜索量。
脑裂现象
什么是脑裂现象
在某些情况下,比如网络通信出现问题、主节点因为负载过大停止响应等,导致重新选举主节点,此时可能会出现集群中有多个主节点的现象,即节点对集群的状态的认知不一致,称之为脑裂现象。
如何避免
通过配置discovery.zen.minimum_master_nodes
来设置最少可工作的候选主节点个数,建议设置为(候选主节点/2)+1,也就是保证集群中有半数以上的候选主节点。
Elasticsearch全文搜索的原理
Elasticsearch的全文搜索主要是依赖Lucene。Lucene使用了倒排文件索引结构。
什么是倒排索引
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的个记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因此被称为倒排索引(Inverted index)。
倒排索引中的索引对象是文档或者文档集合中的单词等,用来存储这些单词在一个文档或者一组文档中的存储位置,是对文档或者文档集合的一种最常用的索引机制。
搜索引擎的关键步骤就是建立倒排索引,倒排索引一般表示为一个关键词,然后是它的频度、位置。
以英文为例,下面是被索引的文本:
T0 = "i like apple"
T1 = "what is it"
T2 = "it is a apple"
我们就能得到下面的反向文件索引:
"i": {0}
"like":{0}
"apple": {0, 2}
"a": {2}
"is": {1, 2}
"it": {1, 2}
"what": {1}
检索的条件"what","is"和"it"将对应集合的交集,所以会搜索出记录T1。
在做全文搜索的时候,用户是不可能把原始记录数据完完整整的记录下来,我们一般在进行搜索的时候,是通过关键字进行对原始记录进行查询的,因此我们需要采用分词器来最大限度的将原始记录进行分词,以便更好的使用关键字来进行搜索。
今天就先学习下Elasticsearch的一些基本概念和基本原理,后面在继续对Elasticsearch深入学习。
推荐阅读: