什么是ElasticSearch
Elasticsearch是一个基于Lucene库的搜索引擎。它提供了一个分布式、支持多租户的全文搜索引擎,具有HTTP Web接口和无模式JSON文档。Elasticsearch是用Java开发的,并在Apache许可证下作为开源软件发布。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。
特点
Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。再平衡和路由是自动完成的。相关数据通常存储在同一个索引中,该索引由一个或多个主分片和零个或多个复制分片组成。一旦创建了索引,就不能更改主分片的数量。Elasticsearch使用Lucene,并试图通过JSON和Java API提供其所有特性。另一个特性称为“网关”,处理索引的长期持久性;例如,在服务器崩溃的情况下,可以从网关恢复索引。Elasticsearch支持实时GET请求,适合作为NoSQL数据存储,但缺少分布式事务。
单机版安装
这里我们选择的学习版本是7.9.0
由于官方下载地址特别慢,推荐使用华为开源镜像站
mirrors.huaweicloud.com/
windows安装
下载安装包
下载对应操作系统的版本,这里我们下载的是64位的操作系统压缩版
解压修改配置文件
解压完成后目录如下
各模块的解释
目录 | 含义 |
---|---|
bin | 可执行脚本 |
config | 配置文件目录 |
jdk | 内置的jdk |
lib | 相关的jar包 |
logs | 日志目录 |
modules | 模块目录 |
plugins | 插件目录 |
运行
bin/elasticsearch.bat
复制代码
启动日志
9200为http访问端口,9300为ElasticSearch内部通信端口
访问测试
linux安装
上传压缩包,解压
tar -zxvf elasticsearch-7.9.0-linux-x86_64.tar.gz -C /opt/modules/
复制代码
修改配置文件
vim conf/elasticsearch.yml
# 加入如下配置
cluster.name: elasticsearch
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
cluster.initial_master_nodes: ["node-1"]
复制代码
建立新用户,修改权限
由于linux上es不支持root启动,所以我们需要建立新用户
新建用户
useradd elasticsearch
设置密码
passwd elasticsearch
#修改es目录权限
chown elasticsearch:elasticsearch elasticsearch-7.9.0 -R
复制代码
切换用户运行
切换非root用户
su elasticsearch
控制台启动
./bin/elasticsearch
后台启动
./bin/elasticsearch -d
复制代码
运行提示的错误
ERROR: [3] bootstrap checks failed
[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
[2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
[3]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
复制代码
问题的处理:
vim /etc/security/limits.conf
# 在文件末尾中增加下面内容
# 指定上面添加用户操作每个进程可以打开的文件数的限制
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
vim /etc/security/limits.d/20-nproc.conf
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
# 操作系统级别对每个用户创建的进程数的限制
* hard nproc 4096
# 注:* 带表Linux所有用户名称
vim /etc/sysctl.conf
# 在文件中增加下面内容
# 一个进程可以拥有的VMA(虚拟内存区域)的数量,默认值为65536
vm.max_map_count=655360
重新加载
sysctl -p
退出elasticsearch用户,重新登录启动生效
exit
su elasticsearch
复制代码
核心概念
索引 Index
类似的数据文档的集合,其本身就是Lucene index,类似于关系型数据库中的db
类型 Type
一个index上,可以定义多个type,type是index的分类,从6.0之后渐渐移除type这个概念,5.x支持自定义多个type,6.x只支持一个自定义type,7.x不再支持自定义type,只支持_doc,类似于关系型数据库中的table
官网给出了详细的说明:www.elastic.co/guide/en/el…
文档 Document
document是index的基本单元,是非结构化的数据。在es中以json的格式存储document,你可以存储任意多个document,类似于关系型数据库中的一条数据
字段 Field
field是document的一个属性,类似于关系型数据库中的一个字段
分片 Shards
一个索引可以存储超出单个节点硬件限制的大量数据。比如,一个具有10亿文档数据的索引占据1TB的磁盘空间,而任一节点都可能没有这样大的磁盘空间。或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,每一份就称之为分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。
副本 Replicas
在一个网络 / 云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片(副本)。
映射 Mapping
mapping是处理数据的方式和规则方面做一些限制,如:某个字段的数据类型、默认值、分析器、是否被索引等等。这些都是映射里面可以设置的,其它就是处理ES里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。
Rest风格操作
ElasticSearch提供了丰富且完整的http api接口,并且官网也描述的非常详细,本文就不多介绍,直接对着官网学习即可。
www.elastic.co/guide/en/el…
Java API操作
ElasticSearch提供了丰富且完整的java api接口,可以去官方根据文档学习。
www.elastic.co/guide/en/el…
Spring Data集成ES
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
# es版本和spring版本相依赖,如果es版本不一致,添加
<properties>
<elasticsearch>${对应的es版本}</elasticsearch>
</properties>
复制代码
编写es实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Document(indexName = "product", shards = 3, replicas = 1)
public class ProductES {
@Id
private Integer id;
/**
* 商品名称
*/
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;
/**
* 商品分类名
*/
@Field(type = FieldType.Keyword)
private String category;
/**
* 价格
*/
@Field(type = FieldType.Double)
private Double price;
/**
* 图片地址
*/
@Field(type = FieldType.Text, index = false)
private String image;
}
复制代码
编写接口,继承ElasticsearchRepository
public interface ProductESRepository extends ElasticsearchRepository<ProductES, Integer> {
}
复制代码
配置类
@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
private String url;
@Bean
@Override
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(url)
.build();
return RestClients.create(clientConfiguration).rest();
}
public void setUrl(String url) {
this.url = url;
}
}
application.yml
elasticsearch:
url: ip:port
复制代码
测试
@Test
public void add() {
ProductES productES = new ProductES();
productES.setId(1).setTitle("图书")
.setCategory("科学类").setPrice(100.28);
System.out.println(elasticsearchRestTemplate.save(productES));
}
@Test
public void bulkDoc() {
List<ProductES> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(new ProductES().setId(i).setTitle("小米" + i)
.setCategory("手机").setPrice(900d + i)
.setImage(String.format("http://www.xiaomi%s.com", i)));
}
productESRepository.saveAll(list);
}
复制代码
elasticsearchRestTemplate和productESRepository都可以实现对es的操作,但是productESRepository中存在大量过时的方法,建议简单的crud操作使用productESRepository,复杂的es操作,还是推荐使用elasticsearchRestTemplate,其本质就是调用RestHighLevelClient