文章目录
全文搜索引擎Elasticsearch
Elasticsearch简介
Elasticsearch是一个基于Lucene库的搜索引擎。它提供了一个分布式、支持多租户的全文搜索引擎,具有HTTP Web接口和无模式JSON文档。Elasticsearch是用Java开发的,并在Apache许可证下作为开源软件发布。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。[5]根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。[6]
Elasticsearch是与名为Logstash的数据收集和日志解析引擎以及名为Kibana的分析和可视化平台一起开发的。这三个产品被设计成一个集成解决方案,称为“Elastic Stack”(以前称为“ELK stack”)。
Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。[5]”Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。再平衡和路由是自动完成的。“[5]相关数据通常存储在同一个索引中,该索引由一个或多个主分片和零个或多个复制分片组成。一旦创建了索引,就不能更改主分片的数量。[7]
Elasticsearch使用Lucene,并试图通过JSON和Java API提供其所有特性。它支持facetting和percolating[8],如果新文档与注册查询匹配,这对于通知非常有用。
另一个特性称为“网关”,处理索引的长期持久性;例如,在服务器崩溃的情况下,可以从网关恢复索引。[9]Elasticsearch支持实时GET请求,适合作为NoSQL数据存储[10],但缺少分布式事务。——来自于维基百科
Elasticsearch简称es,概要:
- 是一个开源的高扩展的分布式全文检索引擎
- 近乎实时的存储、检索数据
- 本身扩展性好,支持集群,可以处理PB级别的数据,1024TB = 1PB
- Elasticsearch 在 Lucene 的基础上进行封装,实现了分布式搜索引擎
- es也使用 Java 开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API—HTTP/https来隐藏Lucene的复杂性;而restful风格遵循的是 http/https 协议
- es是一个 java 项目
为什么使用Elasticsearch?
原因:
随着数据量越来越大,作为 Lucene 也感到吃力,将所有的数据分析后存放到一个索引库中,造成性能的降低。而 Elasticsearch 支持集群和分布式,很好的解决了这一问题,而解决这一问题的根本是 “分片”。
分片:当数据大时,不仅存储会降低效率,而且一旦数据丢失那么后果是很严重的。而 es 中提供了分片的概念,它将数据均衡的分配(使用“一致性Hash”)提高了性能。并且其分片还有一个复制的功能,这个功能是给主分片做一个备份,保证当主分片出问题时,备份会将其修复,备份也成为 副本。而副本并不做搜索的作用!
注意:分片的作用在单节点下并没什么用处,主要作用在集群环境中。在集群环境中,主分片和副本都会散布在各节点中,并且是均衡分配。还有一个注意事项就是 主分片和副本不可能在同一节点上!
Elasticsearch 与Solr的对比
- Solr 利用 zookeoper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能;
- Solr 支持更多格式的数据,而 Elasticsearch 仅支持json文件格式;
- Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供;
- Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch 当单纯的对已有数据进行搜索时,Solr更快,当实时建立索引时, Solr会产生io阻塞,查询性能较差, Elasticsearch具有明显的优势。随着数据量的增加,Solr的搜索效率会变得更低,而Elasticsearch却没有明显的变化。综上所述,
- Solr的架构不适合实时搜索的应用。Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用。
Elasticsearch 的安装和使用
注意
Elasticsearch是使用 Java 开发的,所以需要最好使用 jdk1.8 以上的版本。这里设计到的是 es 5.0+ 的版本,6以上版本的还没去了解就不说了,不过5跟6版本区别还是有点大的,5+版本更加稳定。有 jdk1.8+以上版本还不够,请确保是否已经配置的 jdk环境变量,否则 es 服务会启动失败。
安装
直接上官网安装就得了,官网地址: https://www.elastic.co/products/elasticsearch
步骤
-
这里使用的是window版本,将下载好的 ES 压缩包解压就完成了,没什么多大问题!
-
进入bin目录启动服务,
elasticsearch.bat
-
有个config目录,这是存放配置文件的,
elasticsearch.yml
这里面可以改 集群标识名、端口号等 -
图形化界面,直接用谷歌浏览器,去谷歌插件商店下载
elasticsearch head
搞定! -
在浏览器访问
http://localhost:9200
得到如下信息,就安装成功了。
注意:如果在配置文件中改了端口,那么访问的地址也要改成对应的端口。
Elasticsearch 概念
Elasticsearch 与数据库对比
个人觉得用比较会更直观更好的理解,拿mysql数据库为例:
mysql | elasticsearch |
---|---|
Database(数据库) | Indices(索引库) |
Table(数据表) | Type(类型) |
Rows(表中的一行数据) | Documents(文档对象) |
Columns(字段名) | Fields |
Index(字段对应的值) | Index(一样,其实也就是数据) |
可以看出两个很相似,这样看上去如果不好理解,那么配合图形界面来理解会比较容易!
Elasticsearch 概念
这里概念就不细说了,官方文档更直观一点。
- 集群 cluster:Elasticsearch 的好处就是支持集群,一个集群是由一个或多个节点组织在一起的。共同拥有整个数据,一起提供索引和搜索功能(分片提供的)。一个集群会有一个唯一的名称标识,不配置默认集群名为
elasticsearch
,如需要修改则取 Elasticsearch 的配置文件修改即可。只要节点的集群名称相同,就可以加入同一个集群中。 - 节点node:一个节点是集群中的一个服务器,作为集群的一部分。
- 索引 Indices:就是索引库,放索引(数据)的。
- 类型 type:在一个索引中,你可以定义一种或多种类型。其实也就是分门别类。比如冰箱、电视、洗衣机,都归为电器一类。这里面也是如此,没有强制要求。
- 文档 document:数据载体,一个文档是一个可被索引的基础信息单元。(json格式的数据)
- 分片和复制:一个索引可以存储超出单个节点硬件限制的大量数据。当索引(数据)过多过大时,可以通过分片将索引分成很多份,效率就能够提高。而复制也就是备份,起一个修复的作用。
- 映射 mapping:其实也就是做限制的,拿数据库举例,数据库中数据表的字段是不是有数据类型的限制,比如 varchar、int、date类型等,
elasticsearch
中也就类型的限制,同样也是对字段进行限制。其不仅可以限制数据类型,而且还可以设置指定的分析器、默认值、是否被索引等等。。
Elasticsearch的Java Api
elasticsearch环境配置
流程:
- 创建maven工程,导依赖
- 因为遵循了restful风格,所以创建TransportClient通过传输模式来连接到一个
elasticsearch
的集群,定义成静态工厂方法,方便调用 - 通过TransportClient对象创建索引库
步骤:
创建工程,导入依赖
<!-- es核心包 -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.6.8</version>
</dependency>
<!-- 传输包 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.6.8</version>
</dependency>
<!-- 日志包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.24</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 测试包,直接运行看效果 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- jaskon包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>