Elasticsearch学习笔记

基本概念(搬运官方文档)

入门

Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎。它允许您快速,近实时地存储,搜索和分析大量数据。它通常用作底层引擎/技术,为具有复杂搜索功能和要求的应用程序提供支持。

近实时(NRT)

Elasticsearch是一个近实时搜索平台。这意味着从索引文档到可搜索文档的时间有一点延迟(通常是一秒)。

集群

集群是一个或多个节点(服务器)的集合,它们共同保存您的整个数据,并提供跨所有节点的联合索引和搜索功能。群集由唯一名称标识,默认情况下为“elasticsearch”。此名称很重要,因为如果节点设置为按名称加入群集,则该节点只能是群集的一部分。

确保不要在不同的环境中重用相同的群集名称,否则最终会导致节点加入错误的群集。例如,您可以使用logging-dev,logging-stage以及logging-prod 用于开发,登台和生产集群。

请注意,如果群集中只有一个节点,那么它是完全正常的。此外,您还可以拥有多个独立的集群,每个集群都有自己唯一的集群名称。

节点

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

可以将节点配置为按群集名称加入特定群集。默认情况下,每个节点都设置为加入一个名为cluster的集群elasticsearch,这意味着如果您在网络上启动了许多节点并且假设它们可以相互发现 - 它们将自动形成并加入一个名为的集群elasticsearch。

在单个群集中,您可以拥有任意数量的节点。此外,如果您的网络上当前没有其他Elasticsearch节点正在运行,则默认情况下,启动单个节点将形成一个名为的新单节点集群elasticsearch。

索引

索引是具有某些类似特征的文档集合。例如,您可以拥有客户数据的索引,产品目录的另一个索引以及订单数据的另一个索引。索引由名称标识(必须全部小写),此名称用于在对其中的文档执行索引,搜索,更新和删除操作时引用索引。

在单个群集中,您可以根据需要定义任意数量的索引。

文档(document)

文档是可以编制索引的基本信息单元。例如,您可以为单个客户提供文档,为单个产品提供另一个文档,为单个订单提供另一个文档。该文档以JSON(JavaScript Object Notation)表示,JSON是一种普遍存在的互联网数据交换格式。

在索引/类型中,您可以根据需要存储任意数量的文档。请注意,尽管文档实际上驻留在索引中,但实际上必须将文档编入索引/分配给索引中的类型。

分片和副本

索引可能存储大量可能超过单个节点的硬件限制的数据。例如,占用1TB磁盘空间的十亿个文档的单个索引可能不适合单个节点的磁盘,或者可能太慢而无法单独从单个节点提供搜索请求。

为了解决这个问题,Elasticsearch提供了将索引细分为多个称为分片的功能。创建索引时,只需定义所需的分片数即可。每个分片本身都是一个功能齐全且独立的“索引”,可以托管在集群中的任何节点上。

分片很重要,主要有两个原因:

  • 它允许您水平拆分/缩放内容量
  • 它允许您跨分片(可能在多个节点上)分布和并行化操作,从而提高性能/吞吐量
    分片的分布方式以及如何将其文档聚合回搜索请求的机制完全由Elasticsearch管理,对用户而言是透明的。

在可以随时发生故障的网络/云环境中,非常有用,强烈建议使用故障转移机制,以防分片/节点以某种方式脱机或因任何原因消失。为此,Elasticsearch允许您将索引的分片的一个或多个副本制作成所谓的副本分片或简称副本。

副本很重要,主要有两个原因:

  • 它在分片/节点发生故障时提供高可用性。因此,请务必注意,副本分片永远不会在与从中复制的原始/主分片相同的节点上分配。
  • 它允许您扩展搜索量/吞吐量,因为可以在所有副本上并行执行搜索。
    总而言之,每个索引可以拆分为多个分片。索引也可以复制为零(表示没有副本)或更多次。复制后,每个索引都将具有主分片(从中复制的原始分片)和副本分片(主分片的副本)。

可以在创建索引时为每个索引定义分片和副本的数量。创建索引后,您还可以随时动态更改副本数。您可以使用_shrink和_splitAPI 更改现有索引的分片数,但这不是一项简单的任务,并且预先计划正确数量的分片是最佳方法。

默认情况下,Elasticsearch中的每个索引都分配了5个主分片和1个副本,这意味着如果群集中至少有两个节点,则索引将包含5个主分片和另外5个副本分片(1个完整副本),总计为每个索引10个分片。

ElasticSearch的安装和配置

安装与配置

es依赖与jdk,需要java版本8以上的环境

参考这个

启动权限

这个是真的坑,首先es默认不允许root启动,而其中bin文件夹又是admin.root所属。。。

解决:
先创建一个新用户,将ElasticSearch的安装目录及其子目录改为另外一个非root账户,如:

1
2
sudo chown -R esuser elasticsearch-6.5.0
sudo chgrp -R esgroup elasticsearch-6.5.0

启动es

esuser启动/elasticsearch-6.5.0/bin/elasticsearch,显示started启动成功。

远程访问

修改elasticsearch.yml,绑定服务器IP地址。

然后启动es,会发现三个报错,分别是最大文件创建数不够,esuser能够创建的线程数不够,虚拟内存不够

1
2
3
4
5
6
1.解决第一个错误
修改etc/security/下的limits.conf,在文件最后加入
esuser soft nofile 65536
esuser hard nofile 65536
esuser soft nproc 4096
esuser hard nproc 4096

1
2
3
2.解决第二个错误
修改etc/security/limits.d/下的20-开头的文件
将*改为用户名
1
2
3
4
3.解决第三个错误
修改etc/下的sysctl.conf文件
在最后加上vm.max_map_count=655360
执行sysctl -p以生效

解决完后如继续启动失败,重启虚拟机再次尝试

关闭防火墙以方便使用windows客户端访问

1
2
3
4
systemctl stop firewalld.service

在windows浏览器地址栏键入:
http://es服务器ip:9200

安装elasticsearch-head插件

安装head插件需要依赖于npm和git,所以应首先安装好两个应用,启动head需要用到grunt,所以也应该安装好grunt

推荐安装cnpm(淘宝的国内镜像)

1
npm install -g cnpm --registry=https://registry.npm.taobao.org

安装好后

1
2
3
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
cnpm install

修改head下的Gruntfile.js

1
2
在connect->server->optins下添加
hostname: '*', --允许所有IP访问

修改head插件默认的访问地址

1
2
进入_site下的app.js修改
localhost为es服务器ip地址(在vim命令行模式下使用/搜索localhost)

配置允许es跨域访问

1
2
3
4
修改es下config的.yml文件
在末尾添加
http.cors.enabled: true
http.cors.allow-origin: "*"

打开9100端口(关闭防火墙的忽略)

1
firewall-cmd --zone=public --add-port=9100/tcp --permanent

重启防火墙

1
firewall-cmd --reload

具体步骤

启动head

在head/node_modules/grunt的bin目录下 grunt server

1
[root@localhost bin]# ./grunt server

显示

1
2
Waiting forever...
Started connect web server on http://localhost:9100

则启动成功

关闭防火墙以方便使用windows客户端访问

1
2
3
4
systemctl stop firewalld.service

在windows浏览器地址栏键入:
http://es服务器ip:9100

API学习,用kibana实现增删改查

安装kibana

下载对应版本的二进制压缩文件,解压缩

修改配置文件,进入config,修改.yml

1
2
server.host: "es服务器地址"
elasticsearch.url: "http://es服务器地址:9200"

启动kibana

root启动/kibana/bin/kibana,显示Ready启动成功。

1
[root@localhost bin]# ./kibana

关闭防火墙以方便使用windows客户端访问

1
2
3
4
systemctl stop firewalld.service

在windows浏览器地址栏键入:
http://kibana服务器ip:5601

在windows连接到kibana后打开Dev Tools开发者工具,在里面键入测试代码:

1
2
3
4
5
6
GET _search
{
"query": {
"match_all": {}
}
}

然后就可以根据API练习操作了

中文分词器ik

安装

安装ik需要使用maven,所以事先准备好maven

linux下安装maven

  • 解压后,进入目录,用mvn命令安装(安装时间较长)
    1
    mvn clean install -Dmaven.test.skip=true

安装完成后,会在target/releases下生成一个.zip包

  • 在es下的plugins创建一个ik文件夹,将zip包复制到ik文件夹中并解压

  • 重启es,会发现plugins中会加载一个ik,就代表安装成功了,后续的使用中就可以在创建索引的时候选择使用ik分词器。

注意:中文分词器ik的版本必须与es版本保持一致(完全一致),一般用master版本编译打包出来的。

1
2
3
版本必须完全一致
eg:
java.lang.IllegalArgumentException: Plugin [analysis-ik] was built for Elasticsearch version 6.5.0 but version 6.5.1 is running

在创建索引时,自定义mapping,字段属性中加上

1
"analyzer": "ik_max_word"

就可以使用中文分词了

在Java应用中使用Elasticsearch

创建一个maven项目

引入依赖,因为要测试数据操作,所以也要用到junit

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.5.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>

下载完所有依赖后,直接创建测试类

当然测试索引也要事先准备好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
PUT /javademo
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 0
},
"mappings": {
"blog":{
"properties":{
"id": {
"type": "long"
},
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
},
"postdate": {
"type": "date"
},
"url": {
"type": "text"
}
}
}
}
}

参考项目:

es在Java应用中的测试

es整合spring

同样创建maven项目,导入相关依赖

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>

创建es配置

applicationContext-elasticsearch.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/elasticsearch
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 搜索DAO 扫描 -->
<elasticsearch:repositories base-package="com.pace2car.elastic.dao" />

<!-- 扫描Service包 -->
<context:component-scan base-package="com.pace2car.elastic.service" />

<!-- 配置Client -->
<elasticsearch:transport-client id="client" cluster-name="my-application" cluster-nodes="192.168.44.128:9300"/>

<!-- 配置搜索模板 -->
<bean id="elasticsearchTemplate"
class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
<constructor-arg name="client" ref="client" />
</bean>
</beans>

在spring配置中引入es配置

1
2
<!-- 引入 elasticsearch 配置  -->
<import resource="applicationContext-elasticsearch.xml"/>

ps:dao层需要继承ElasticsearchRepository,方法名安规范写,框架自动生成查询语句

还有一些注解上的使用,如@Document,@Id,@Field等,具体参考spring-data的官方文档即可

整合完毕收工。


PS:随着es越来越强大,我们甚至可以让它在项目中直接作为持久化存储库(类似于NoSQL),当然,目前大多数的企业开发还是让它作为一个前置搜索引擎来使用,即定时将数据库中的内容同步到es中,在用户进行索引操作时,直接的去从es库中查询,这样也能充分的利用到es近实时的特性(1秒之内)。在更大型的企业中,会利用es来做大数据日志分析的工作,主要技术栈为ELK,大致架构为syslog/logstash/flume ->kafka ->Spark/Track/Storm ->HDFS ->elasticsearch ->kibana

热评文章