基本概念和原理


ES其实就是基于lucene之上封装的一个分布式 索引框架,所以lucene拥有的特性,它都是有的,同时因为它是基于分布式的,所以对很多的功能进行了扩展,要想掌握ES,需要先熟悉一下Lucene,因为熟悉了Lucene之后,不论是学ES,还是Solr都是比较容易的.在这里插一句经常有人在选型的时候,不知道用ES还是Solr,建议可以参考下面的方案:如果系统是从头接入搜索引擎,那么就不要犹豫了,直接使用ES,因为它上手快,使用也比较简单,如果是现有系统已经有搜索引擎框架,这个时候就需要思考一下,当下框架是否可以满足业务不断的发展需求?以及如果要替换对应升级所需要面对的风险是否可控?以及对应的解决方案.好了进入正题,解析来进入ES的入门.

 

概念

Elasticsearch(ES)是一个基于Apache的开源索引库Lucene而构建的 开源、分布式、具有RESTful接口的全文搜索引擎, 还是一个 分布式文档数据库.

ES可以轻松扩展数以百计的服务器(水平扩展), 用于存储和处理数据. 它可以在很短的时间内存储、搜索和分析海量数据, 通常被作为复杂搜索场景下的核心引擎.

 

近实时搜索

我们知道只有getApi是实时的,搜索是逐段进行的。我们都知道一个index是由若干个segment组成,随着每个segment的不断增长,我们索引一条数据后可能要经过分钟级别的延迟才能被搜索,为什么有这么大的延迟,这里面的瓶颈点主要在磁盘。持久化一个segment需要fsync操作用来确保segment能够物理的被写入磁盘以真正的避免数据丢失,但是fsync操作比较耗时,所以它不能在每索引一条数据后就执行一次,如果那样索引和搜索的延迟都会非常之大。所以在es中新增的document会被收集到indexing buffer区后被重写成一个segment然后直接写入filesystem cache中,这个操作是非常轻量级的,相对耗时较少,之后经过一定的间隔或外部触发后才会被flush到磁盘上,这个操作非常耗时。但只要segment文件被写入cache后,这个sengment就可以打开和查询,从而确保在短时间内就可以搜到,而不用执行一个full commit也就是fsync操作,这是一个非常轻量级的处理方式而且是可以高频次的被执行,而不会破坏es的性能。这个轻量级的写入和打开一个cache中的segment的操作叫做refresh,默认情况下,es集群中的每个shard会每隔1秒自动refresh一次,这就是我们为什么说es是近实时的搜索引擎而不是实时的。

优点


(1) 横向可扩展性: 作为大型分布式集群, 很容易就能扩展新的服务器到ES集群中; 也可运行在单机上作为轻量级搜索引擎使用. (2) 更丰富的功能: 与传统关系型数据库相比, ES提供了全文检索、同义词处理、相关度排名、复杂数据分析、海量数据的近实时处理等功能. (3) 分片机制提供更好地分布性: 同一个索引被分为多个分片(Shard), 利用分而治之的思想提升处理效率. (4) 高可用: 提供副本(Replica)机制, 一个分片可以设置多个副本, 即使在某些服务器宕机后, 集群仍能正常工作. (5) 开箱即用: 提供简单易用的API, 服务的搭建、部署和使用都很容易操作.


 

ES中有几个基本概念:索引(index)、类型(type)、文档(document)、映射(mapping)等。

我们将这几个概念与传统的关系型数据库中的库、表、行、列等概念进行对比,如下表:

 

RDBS

ES

数据库(database)

索引(index)

表(table)

类型(type)(ES6.0之后被废弃,es7中完全删除,等于index)

表结构(schema)

映射(mapping)

行(row)

文档(document)

列(column)

字段(field)

索引(index)

反向索引(everything is index)

SQL

查询DSL

SELECT * FROM table

GET http://.....

UPDATE table SET

PUT  http://......

DELETE

DELETE  http://......

 

索引(index)

索引是ES的一个逻辑存储,对应关系型数据库中的库,ES可以把索引数据存放到服务器中,也可以sharding(分片)后存储到多台服务器上。每个索引有一个或多个分片,每个分片可以有多个副本。

类型(type)

ES中,一个索引可以存储多个用于不同用途的对象,可以通过类型来区分索引中的不同对象,对应关系型数据库中表的概念。但是在ES6.0开始,类型的概念被废弃,ES7中将它完全删除。删除type的原因:

我们一直认为ES中的“index”类似于关系型数据库的“database”,而“type”相当于一个数据表。ES的开发者们认为这是一个糟糕的认识。例如:关系型数据库中两个数据表示是独立的,即使他们里面有相同名称的列也不影响使用,但ES中不是这样的。

我们都知道elasticsearch是基于Lucene开发的搜索引擎,而ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。举个例子,两个不同type下的两个user_name,在ES同一个索引下其实被认为是同一个filed,你必须在两个不同的type中定义相同的filed映射。否则,不同type中的相同字段名称就会在处理中出现冲突的情况,导致Lucene处理效率下降。

去掉type能够使数据存储在独立的index中,这样即使有相同的字段名称也不会出现冲突,就像ElasticSearch出现的第一句话一样“你知道的,为了搜索····”,去掉type就是为了提高ES处理数据的效率。

除此之外,在同一个索引的不同type下存储字段数不一样的实体会导致存储中出现稀疏数据,影响Lucene压缩文档的能力,导致ES查询效率的降低

文档(document)

存储在ES中的主要实体叫文档,可以理解为关系型数据库中表的一行数据记录。每个文档由多个字段(field)组成。区别于关系型数据库的是,ES是一个非结构化的数据库,每个文档可以有不同的字段,并且有一个唯一标识。

映射(mapping)

mapping是对索引库中的索引字段及其数据类型进行定义,类似于关系型数据库中的表结构。ES默认动态创建索引和索引类型的mapping,这就像是关系型数据中的,无需定义表机构,更不用指定字段的数据类型。当然也可以手动指定mapping类型。

分片(shard)

如果我们的索引数据量很大,超过硬件存放单个文件的限制,就会影响查询请求的速度,Es引入了分片技术。一个分片本身就是一个完整的搜索引擎,文档存储在分片中,而分片会被分配到集群中的各个节点中,随着集群的扩大和缩小,ES会自动的将分片在节点之间进行迁移,以保证集群能保持一种平衡。分片有以下特点:

  1. ES的一个索引可以包含多个分片(shard);
  2. 每一个分片(shard)都是一个最小的工作单元,承载部分数据;
  3. 每个shard都是一个lucene实例,有完整的简历索引和处理请求的能力;
  4. 增减节点时,shard会自动在nodes中负载均衡;
  5. 一个文档只能完整的存放在一个shard上
  6. 一个索引中含有shard的数量,默认值为5,在索引创建后这个值是不能被更改的。
  7. 优点:水平分割和扩展我们存放的内容索引;分发和并行跨碎片操作提高性能/吞吐量;
  8. 每一个shard关联的副本分片(replica shard)的数量,默认值为1,这个设置在任何时候都可以修改。

副本:replica

副本(replica shard)就是shard的冗余备份,它的主要作用:

  1. 冗余备份,防止数据丢失;
  2. shard异常时负责容错和负载均衡;

特性

速度快、易扩展、弹性、灵活、操作简单、多语言客户端、X-Pack、hadoop/spark强强联手、开箱即用。

  • 分布式:横向扩展非常灵活
  • 全文检索:基于lucene的强大的全文检索能力;
  • 近实时搜索和分析:数据进入ES,可达到近实时搜索,还可进行聚合分析
  • 高可用:容错机制,自动发现新的或失败的节点,重组和重新平衡数据
  • 模式自由:ES的动态mapping机制可以自动检测数据的结构和类型,创建索引并使数据可搜索。
  • RESTful API:JSON + HTTP