一、概述
Elasticsearch(ES)是一个基于Lucene构建的开源、分布式、RESTful接口的全文搜索引擎。Elasticsearch还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,ES能够横向扩展至数以百计的服务器存储以及处理PB级的数据。而且可以在极短的时间内存储、搜索和分析大量数据。
Elasticsearch的优点:
- 分布式:横向扩展非常灵活;
- 全文检索:基于lucene的强大的全文检索能力;
- 近实时搜索和分析:数据进入ES,可达到近实时搜索,还可进行聚合分析;
- 高可用:容错机制,自动发现新的或失败的节点,重组和重新平衡数据;
- 模式自由:ES的动态mapping机制可以自动检测数据的结构和类型,创建索引并使数据可搜索;
- RESTful API:JSON + HTTP
二、基本概念
Elasticsearch是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document)。然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在Elasticsearch中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。Elasticsearch比传统关系型数据库如下:
Relational DB ‐> Databases ‐> Tables ‐> Rows ‐> Columns
Elasticsearch ‐> Indices ‐> Types ‐> Documents ‐> Fields
Es的基本概念有:Index索引、Document文档、Types类型、Fields字段、mapping映射、Shards & Replicas分片与副本、Cluster 集群、Node节点等。
1、Index(索引)
拥有相似特征文档的集合。一个索引可以类比为sql的一个数据库。
2、Types(类型)
对索引中的数据进行逻辑分区。在这里面的文档,最好具有相似的字段,类比为sql的表。
自Elasticsearch 7版本开始,引入了一个重大的变化,即不再支持多个type。在Elasticsearch 7及之后的版本中,只能在index级别定义一个单一的type,并且该type字段名默认为"_doc"。这意味着在创建index时,无需再为每个type指定mapping,而是直接在index级别指定整体的mapping。换句话说,只需要为整个index设置一次mapping,而不是为每个type都设置一次mapping。
3、Documents(文档)
一个文档是一个可被索引的基础信息单元。文档以JSON(Javascript Object Notation)格式来表示,文档必须被索引/赋予一个索引的type, 插入索引库以文档为单位,类比于sql数据库中的一行数据。
4、mapping(映射)
映射, 就像数据库中的 schema ,描述了文档可能具有的字段或 属性 、每个字段的数据类型—比如 string, integer 或 date —以及Lucene是如何索引和存储这些字段的。 类型可以很好的区分同一个集合中的不同细分。在不同的细分中数据的整体模式是相同的(或相似的)。
同index中存储不同type时应保持同名的filed的类型一致,且在同一个索引中,存储仅有小部分字段相同或者全部字段都不相同的文档,会导致数据稀疏,影响Lucene有效压缩数据的能力
5、Fields(字段)
对文档的不同属性进行标识。类比为sql数据库表的column。
6、Id
文档的唯一确定性字段。可以在插入文档时进行指定或由Es自动生成。 这个id与sql表的自增id略有不同,只表示当前文档的唯一性。一般在数据插入时,我们将两个id设为相等值使用。
7、shards & Replicas(分片与副本)
分片:
分片是将索引划分为多个较小的部分,以便在集群中进行并行处理和负载均衡。默认情况下,每个索引有5个分片,这意味着可以将数据分布在5个不同的节点上以实现高可用性和可扩展性。但是,可以根据需要调整分片数,以便更好地满足应用程序的需求
副本:
副本是指将索引的分片复制到其他节点上以提高数据的可用性和容错性。默认情况下,每个索引只有一个副本,这意味着如果主分片所在的节点发生故障,则该分片的数据将不可用。但是,可以通过修改副本数来增加数据的冗余度,从而提高数据的可靠性和可用性。
分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是不能改变分片的数量。
Es的基本操作可以参考Es权威指南:
三、使用docker-compose部署Es集群+kibana
Es版本:7.17.1
Kibana版本:7.17.1
docker-compose版本:v2.20.2
docker版本:24.0.2
1、创建docker网络,用于Es集群
docker network create --driver bridge elastic-net
2、拉取镜像
为了在docker-compose启动的时候更快一点,先将要用到的镜像拉取到本地
注意: Es的版本和Kibana的版本要一致,否则kibana无法接入Es
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.1
docker pull kibana:7.17.1
3、编写docker-compose.yaml文件并启动容器
3.1 获取Es配置信息
首先创建elastic文件夹,并在内创建docker-compose.yaml文件,键入以下内容。
version: "3"
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1
container_name: es01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es02,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /home/xxxuser/workspace/elastic/elastic11/data:/usr/share/elasticsearch/data
ports:
- 19200:9200
networks:
default:
external: true
name: elastic-net
以上为一个节点的docker-compose.yaml文件内容,在elastic文件夹目录下启动容器,我们需要从已经运行的容器中将配置文件拷贝至宿主机进行文件挂载,方便后续直接修改配置。
创建用于挂载的文件卷:
(示例的elastic是放在/home/xxxuser/workspace/下)
分别有3个节点,节点文件夹名称为elastic11、elastic22、elastic33。
./elastic
├── docker-compose.yaml
├── elastic11
│ ├── config
│ ├── logs
│ └── data
│
├── elastic22
│ ├── config
│ ├── logs
│ └── data
│
├── elastic33
│ ├── config
│ ├── logs
│ └── data
│
└── kibana
└── config
使用docker cp 命令将 Es容器内/usr/share/elasticsearch下config文件夹内的所有内容直接复制到宿主机的/elasticXX/config文件夹中。
3.2 完善docker-compose.yaml文件内容
将三个节点所需文件创立后,打开docker-compose.yaml文件,输入剩余内容。
version: "3"
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1
container_name: es01
environment:
- node.name=es01
#内存锁设置 软限制和硬限制都为-1 --> es进程可以无限制使用内存
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /home/xxuser/workspace/elastic/elastic11/data:/usr/share/elasticsearch/data
- /home/xxuser/workspace/elastic/elastic11/config:/usr/share/elasticsearch/config
- /home/xxuser/workspace/elastic/elastic11/logs:/usr/share/elasticsearch/logs
ports:
- 19200:9200
es02:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1
container_name: es02
environment:
- node.name=es02
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /home/xxuser/workspace/elastic/elastic22/data:/usr/share/elasticsearch/data
- /home/xxuser/workspace/elastic/elastic22/config:/usr/share/elasticsearch/config
- /home/xxuser/workspace/elastic/elastic22/logs:/usr/share/elasticsearch/logs
ports:
- 29200:9200
es03:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1
container_name: es03
environment:
- node.name=es03
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /home/xxuser/workspace/elastic/elastic33/data:/usr/share/elasticsearch/data
- /home/xxuser/workspace/elastic/elastic33/config:/usr/share/elasticsearch/config
- /home/xxuser/workspace/elastic/elastic33/logs:/usr/share/elasticsearch/logs
ports:
- 39200:9200
kibana:
image: kibana:7.17.1
container_name: kibana
environment:
#Es节点的访问路径
ELASTICSEARCH_URL: http://es01:9200
ELASTICSEARCH_HOSTS: http://es01:9200
ports:
- 15601:5601
volumes:
- /home/xxuser/workspace/elastic/kibana/config:/usr/share/kibana/config
networks:
default:
external: true
name: elastic-net
3.3 添加配置文件信息
分别按照docker-compose.yaml
文件中挂载卷中的信息创建挂载目录。
主要是修改elasticsearch.yml配置集群信息 和 jvm.options 修改运行时内存设置。分别进入三个容器挂载的config目录,对上述两个文件进行修改。
3.3.1 修改jvm.options文件
在jvm.options文件中,取消Xms和Xmx的注释,并改为
-Xms512m
-Xmx512m
作用是设置Elasticsearch进程的初始堆内存大小和最大堆内存大小,避免因为内存不足而导致的问题。
3.3.2 配置elasticsearch.yml文件
此处三个容器的配置内容一样也可以
# 这里修改集群的名字,如果要想搭建集群,所有集群中的每个节点名字都必须一样
cluster.name: es-cluster
# 每个集群中都有节点,这里设置每个节点的名字,节点与节点的名字必须不一样
node.name: es01
# 这里修改为每台节点数据存放的目录
# path.data: /home/estestuser/esdata
# 这里修改为每台节点日志的存放目录
# path.logs: /home/estestuser/eslogs
# 这一行改成 0.0.0.0 意思是允许所有节点访问
network.host: 0.0.0.0
# 配置集群节点集合,种子节点可以把当前节点去掉
discovery.seed_hosts: ["es01", "es02", "es03"]
# 集群选举设置
cluster.initial_master_nodes: ["es01", "es02", "es03"]
# 开启跨域访问
http.cors.enabled: true
http.cors.allow-origin: "*"
bootstrap.memory_lock: true
配置好三个Es容器的配置文件后,可以启动容器。
Kibana直接在docker-compose.yaml文件中指定环境变量进行配置,暂时无需使用config文件。
3.4 使用docke-compose启动容器
在docker-compose.yaml文件目录运行启动命令
~/workspace/elastic$ docker-compose up -d
[+] Running 4/4
✔ Container es02 Started
✔ Container kibana Started
✔ Container es01 Started
✔ Container es03 Started
使用docker ps 查看是否运行成功
~/workspace/elastic$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f9d823aca115 docker.elastic.co/elasticsearch/elasticsearch:7.17.1 "/bin/tini -- /usr/l…" 23 hours ago Up About a minute 9300/tcp, 0.0.0.0:19200->9200/tcp, :::19200->9200/tcp es01
eb01ae68ab9f kibana:7.17.1 "/bin/tini -- /usr/l…" 25 hours ago Up About a minute 0.0.0.0:15601->5601/tcp, :::15601->5601/tcp kibana
31821217df02 docker.elastic.co/elasticsearch/elasticsearch:7.17.1 "/bin/tini -- /usr/l…" 25 hours ago Up About a minute 9300/tcp, 0.0.0.0:39200->9200/tcp, :::39200->9200/tcp es03
c2193f5d0939 docker.elastic.co/elasticsearch/elasticsearch:7.17.1 "/bin/tini -- /usr/l…" 25 hours ago Up About a minute 9300/tcp, 0.0.0.0:29200->9200/tcp, :::29200->9200/tcp es02
在浏览器输入 宿主机ip:19200,出现以下内容即为Es启动成功
在浏览器输入 宿主机ip:15601 进入以下页面,即Kibana启动成功
至此,Elasticsearch集群+kibana启动成功。
四、Es原生Restful操作
在kibana中managerment --> dev toool 可以对Es进行Restful操作
1、添加操作
1.1 创建index并配置映射
1.1.1 使用PUT请求,创建index
PUT {INDEX_NAME}
1.1.2 使用PUT请求,指定创建mapping,在body中传入内容
PUT /test_index/test_mapping/_mapping?include_type_name=true
1.1.3 使用POST请求,在body中使用json格式传输mapping内容
1.2 创建文档
1.1.1 使用PUT指定id,若对应id不存在则创建文档,如果存在则修改
PUT /user/userInfo/2
返回值说明:
{
"_index" : "user", //表示所在index
"_type" : "userInfo", //表示所属type
"_id" : "2", //id
"_version" : 1, //版本
"result" : "created", //创建结果成功
"_shards" : { //分片信息 总共创了2个,成功2个
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 1, //序列号 用于并发控制
"_primary_term" : 1 //主分片的术语号,用于版本控制和并发控制
}
1.1.2 使用POST创建文档
使用POST请求创建文档,可以不指定ID,也可以指定不存在的ID。若不指定ID,Es在创建文档时会自动创建id
2、删除操作
2.1使用DELETE删除
DELETE /{INDEX_NAME}/{TYPE_NAME}/ID 删除单条记录
DELETE /user/userInfo/hn4TdIsByAuA368MWMyF
Response:
{
"_index" : "user",
"_type" : "userInfo",
"_id" : "hn4TdIsByAuA368MWMyF",
"_version" : 2,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 1
}
2.2 使用POST进行匹配删除
POST /{INDEX_NAME}/{TYPE_NAME}/_delete_by_query
POST /user/userInfo/_delete_by_query
{
"query": {
"term": {
"name": "tom"
}
}
}
3、修改操作
3.1 修改mapping
PUT /{INDEX_NAME}/{TYPE_NAME}/_mapping
PUT /user/userInfo/_mapping?include_type_name=true
{
"properties":{
"name":{
"type":"text" //字段新类型
}
}
}
3.2 修改文档数据
3.2.1 使用POST指定已存在的文档ID进行修改
POST /user/userInfo/hX4DdIsByAuA368MQ8zq
{
"id":3,
"name":"jerry",
"age":20,
"city":"北京",
"createdTime":1698400152
}
3.2.2 使用PUT指定已经存在的ID进行修改
PUT /user/userInfo/hX4DdIsByAuA368MQ8zq
{
"id":3,
"name":"jerry",
"age":22,
"city":"天津",
"createdTime":1698400152
}
4、查询操作
4.1 查询mapping
GET /{INDEX_NAME}/_mapping/{TYPE_NAME}
GET /user/_mapping/userInfo?include_type_name=true
4.2 查询文档信息
4.2.1 使用GET方式指定查询
GET /INDEX_NAME/TYPE_NAME/ID
GET /user/userInfo/4
Response:
{
"_index" : "user",
"_type" : "userInfo",
"_id" : "4",
"_version" : 1,
"_seq_no" : 3,
"_primary_term" : 1,
"found" : true,
"_source" : {
"id" : 4,
"name" : "jerry",
"age" : 19,
"city" : "天津",
"createdTime" : 1698400152
}
}
4.2.2 使用POST请求查询
POST /{INDEX_NAME}/{TYPE_NAME}/_search
4.2.2.1 查询type中的所有信息
POST /user/userInfo/_search
{
"query":{
"match_all": {}
}
}
4.2.2.2 匹配字段查询
POST /user/userInfo/_search
//查询city在北京的
{
"query": {
"query_string": {
"default_field": "city",
"query": "北京"
}
}
}
包含两条city在北京的数据,按照匹配度score进行排序
以上Es的增删改查基本操作,复杂操作需要更深入学习。
五、升级集群安全配置
在之前的操作中,搭建了用于测试的Es集群,但是所有的操作、登录都不需要密码验证,数据传输均为明文传输,是非常不安全的。在生产环境中,往往需要根据需要,配置不同的安全策略。这里介绍一个简单的安全配置方法。
1、Es集群安全配置
1.1 修改Es集群配置文件
在原有elasticsearch.yml配置文件内容基础上,追加安全相关配置。三个节点的配置文件均需要修改。
#安全验证配置项
# 启用X-Pack安全特性,包括用户认证、角色授权等
xpack.security.enabled: true
# 使用基本许可证类型进行自生成许可。
xpack.license.self_generated.type: basic
# 启用传输层的SSL加密,以确保数据在传输过程中的安全性。
xpack.security.transport.ssl.enabled: true
# 设置SSL验证模式为证书验证,确保客户端和服务器之间的连接是安全的。
xpack.security.transport.ssl.verification_mode: certificate
# 指定用于SSL加密的密钥库文件路径,该文件包含了用于身份验证的公钥和私钥。
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
# 指定用于SSL加密的信任库文件路径,该文件包含了用于验证服务器身份的公钥。
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
1.2 生成 TLS 和身份验证,将会在 config 下生成 elastic-certificates.p12 文件
使用docker exec 命令进入es01容器内的/usr/share/elasticsearch/bin 目录下,执行elasticsearch-certutil cert 命令生成.p12验证文件
~/workspace/elastic$ docker exec -it es01 bash
root@f9d823aca115:/usr/share/elasticsearch# cd bin/
elasticsearch-certutil cert -out config/elastic-certificates.p12 -pass ""
命令说明:
elasticsearch-certutil
: 这是一个用于管理Elasticsearch证书的工具。cert
: 这是elasticsearch-certutil
工具的一个子命令,用于处理证书相关操作。-out config/elastic-certificates.p12
: 这个选项指定了输出文件的路径和名称。在这个例子中,生成的P12文件将被保存在config
目录下,并命名为elastic-certificates.p12
。-pass ""
: 这个选项指定了用于加密P12文件的密码。在这个例子中,密码为空字符串,表示不使用密码进行加密。
生成成功后,退出容器,将生成的elastic-certificates.p12
文件拷贝到另外两个容器的config目录下。
1.3 重启Es集群
配置文件修改完成、.p12文件均拷贝到所有节点的容器config
目录下,需要重启集群,让配置文件生效。
在docker-compose.yaml
文件目录下,使用restart命令重启。
docker-compose restart
1.4 创建 Elasticsearch 集群密码
使用docker exec
命令进入es01容器,执行初始化密码的命令,初始化完成后,会自动同步到所有节点。所以,本次操作只需要在一个节点内执行即可。
进入/usr/share/elasticsearch/bin
目录,执行elasticsearch-setup-passwords interactive
命令,然后根据提示设定密码即可
root@f9d823aca115:/usr/share/elasticsearch/bin# elasticsearch-setup-passwords interactive
Initiating the setup of passwords for reserved users elastic,apm_system,kibana,logstash_system,beats_system,remote_monitoring_user.
You will be prompted to enter passwords as the process progresses.
Please confirm that you would like to continue [y/N]y
Enter password for [elastic]:
Reenter password for [elastic]:
Enter password for [apm_system]:
Reenter password for [apm_system]:
Enter password for [kibana]:
Reenter password for [kibana]:
Enter password for [logstash_system]:
Reenter password for [logstash_system]:
Enter password for [beats_system]:
Reenter password for [beats_system]:
Enter password for [remote_monitoring_user]:
Reenter password for [remote_monitoring_user]:
Changed password for user [apm_system]
Changed password for user [kibana]
Changed password for user [logstash_system]
Changed password for user [beats_system]
Changed password for user [remote_monitoring_user]
Changed password for user [elastic]
内置三个用户:
elastic:内置超级用户(用于登录es)
kibana:仅可用于kibana用来连接elasticsearch并与之通信, 不能用于kibana登录
logstash_system:用于Logstash在Elasticsearch中存储监控信息时使用
1.5 访问验证
我是在vm虚拟机上运行的docker,在浏览器访问虚拟机host:19200,出现密码验证窗口。
使用用户名elastic,自定的密码登录,出现节点信息,即为配置成功。
2、Kibana配置登录
2.1 创建配置文件
在宿主机建立的kibana容器挂载卷kibana/config
目录下,创建kibana.yml
和node.options
两个文件
# Default Kibana configuration for docker target
server.host: "0.0.0.0"
server.shutdownTimeout: "5s"
elasticsearch.hosts: [ "http://es01:9200" ]
server.publicBaseUrl: "http://192.168.94.128:15601"
#用于设置Elasticsearch中已保存对象的加密密钥。已保存对象是指索引、模板、映射等数据结构。通过使用这个配置项,可以确保这些对象在存储和传输过程中的安全性
xpack.encryptedSavedObjects.encryptionKey: dcbf819d8874e8242eaf107d538fe874
#用于设置Elasticsearch报告功能的加密密钥。报告功能提供了对查询结果的可视化展示和导出功能,包括生成报表、图表等。通过使用这个配置项,可以确保报告数据在传输和存储过程中的安全性。
xpack.reporting.encryptionKey: ba2d98e6dad4fa73d77f5f34a568cfdd
# 用于设置Elasticsearch安全功能的加密密钥。安全功能包括访问控制、角色权限管理等,用于保护Elasticsearch集群的数据和资源。通过使用这个配置项,可以确保安全相关的数据在传输和存储过程中的安全性。
xpack.security.encryptionKey: 3871dfc1bd945e1141364e4244800b39
# 中文
i18n.locale: "zh-CN"
# 连接配置
# 初始化es密码时的内置的kibana用户名kibana
elasticsearch.username: kibana
# 初始化es密码时的内置的kibana用户名kibana时自己设置的密码
elasticsearch.password: YOUR_PASSWORD
## do not terminate process on unhandled promise rejection
--unhandled-rejections=warn
2.2 重启kibana容器
使用docker restart kibana
重启kibana容器
2.3 验证安全配置
输入访问地址,出现以下界面则成功。
注意:此处用户名不是kibana
而是elastic
,密码是Es初始化elastic用户名时自己设置的密码
登录成功,进入首页,即配置成功。
六、参考资料
Es权威指南:www.elastic.co/guide/cn/el…
Es 1.17.1文档: www.elastic.co/guide/en/el…
巨人的肩膀:
1、www.cnblogs.com/coderxz/p/1…
初学入门,如有错误,敬请指正