从零基础的内容开始介绍Elasticsearch,主要包含以下内容:
- Elasticsearch的定义、优点,以及典型的业务场景。
- Elasticsearch中重要的概念。
- Elasticsearch典型的接入方式。
- 安装Elasticsearch。
- 使用Kibana调试Elasticsearch。
- Elasticsearch节点的重要配置。
1、Elasticsearch简介
Elasticsearch简称ES,是世界上非常受欢迎的开源的分布式搜索引擎。它使用Java语言,基于Apache Lucene开发,从2010年发布第一个版本至今已有十余年的历史。Elastic的中文含义是“有弹性的、可伸缩的”,顾名思义,你可以很方便地使用Elasticsearch提供的可扩展的企业级搜索服务。Elasticsearch的官方网站对它的解释是:Elasticsearch是一个分布式、RESTful的搜索和数据分析引擎。没错,它为我们提供的很重要的两大功能就是大数据搜索和分析服务。
如果你是软件开发人员,那么对关系数据库的使用应该不陌生。传统的关系数据库可以使用SQL(Structured Query Language,结构化查询语言)对数据进行查询和统计分析,但是在“大数据时代”,关系数据库在使用时存在明显的短板,导致它的应用存在一些缺点:
- 性能差:当单表的数据量达到数百万条甚至数千万条时,即使采用一定的方法去优化SQL,查询速度依然可能很慢,这在很多业务场景中是不允许的。
- 扩展难:关系数据库的集群不太容易搭建,即使采用了分表分库的中间件将数据库集群化,查询性能在很多业务场景中依然没有保障。
较之于关系数据库,Elasticsearch则存在几个明显的优点:
- 高性能:由于Elasticsearch使用倒排索引(反向索引)作为存储结构并大量使用缓存机制,你可以非常快速地从海量的数据中查询出需要的结果。
- 易扩展:如搭建多个Elasticsearch节点,使它们组成一个集群对外提供分布式的搜索服务,只需要简单地修改配置文件。
- 容错性好:由于每个索引可以配置副本机制,即使Elasticsearch有部分服务器宕机也不用担心数据丢失。
- 上手快:Elasticsearch拥有“开箱即用”的RESTful API,你只需要按照接口文档的说明正确地传递参数,就可以从Elasticsearch中读数据或向其中写数据,上手非常快。
Elasticsearch有以下几个典型的业务场景,可供开发者参考:
- 在线实时日志分析:使用Elasticsearch分析线上日志是十分常见的操作,从最初的ELK(Elasticsearch、Logstash、Kibana)平台到如今的Elastic Stack都包含开箱即用的在线日志采集、存储、分析的功能,使用起来快捷、方便。
- 物联网(internet of things,IoT)数据监控:对于各种传感器设备、可穿戴设备实时产生的各种需要监控和分析的数据,由于数据量很大且实时性要求较高,很适合用Elasticsearch来进行技术选型,Elasticsearch在智慧交通、智能家居、公共安全、运维监控等领域有着广泛的应用。
- 文献检索和文献计量:Elasticsearch是一种出色的搜索引擎,很适合用于电子图书馆、论文检索系统所需的多样化信息检索服务,同时Elasticsearch强大的数据分析能力为文献计量提供了便利的统计接口。
- 商务智能(business intelligence,BI)大屏展示:Elasticsearch通过有效的大数据分析和研判,使用多维度的钻取分析为用户提供决策支持和趋势预测,其在智慧公安、智慧交通、智慧水利等领域的大屏展示系统中应用尤其普遍。
2、Elasticsearch的典型接入方式
探讨适合接入Elasticsearch的几种典型方式,帮助大家明确Elasticsearch的正确接入方法。
2.1、将Elasticsearch作为数据源
Elasticsearch很适合读多写少的数据分析型应用程序,如果你参与过OLAP数据分析相关的项目,由于数据仓库本身就具有读多写少的特性,对事务管理的要求也不高,在这种情况下,考虑到Elasticsearch本身具备数据存储的能力,可以作为数据源,使应用程序的绝大多数读写操作都在Elasticsearch中进行,如下图所示:
2.2、给已有系统添加Elasticsearch
如果你已经有一个软件系统,它使用了MySQL或者HBase数据库,但是随着数据量的不断加大,你可能会感觉MySQL的查询速度越来越难以接受,也可能由于业务逻辑越来越复杂,而感觉HBase的检索方式不够丰富。这时候你可以考虑把那些查询速度慢或者业务逻辑复杂的数据接入Elasticsearch,使用时你需要把相关表的历史存量数据一次性导入Elasticsearch,当增量数据写入数据库时,也往Elasticsearch中写一份,这样就能够保证两边的数据是同步的,如下图所示:
注意:当关系数据库或NoSQL数据库能够满足实际需要的查询请求时,则没有必要接入Elasticsearch。实际上,关系数据库和NoSQL数据库的主键查询速度本身就很快,能够满足部分场景的需要,可以用它们分担一些查询请求,减小Elasticsearch的压力。另外,写入Elasticsearch的字段数目并不强制要求与数据库的一致。只有实际需要检索、分析和前端展示的字段才必须写入Elasticsearch。在Elasticsearch中写入字段数目过多的文档对性能而言是一种拖累,并且会浪费资源。
2.3、使用Elastic Stack
提到Elasticsearch的接入方式,怎么能不讲官方的Elastic Stack呢?除了使用应用程序写入Elasticsearch,你还可以使用官方提供的数据采集工具Logstash或者第三方的ETL工具把数据写入Elasticsearch。这些工具除了能用来采集数据库的数据,还可以用来采集线上的日志数据、系统的运维监控指标数据,功能十分丰富。Elastic Stack的组件Kibana提供了一个友好的图形界面,可以用来管理和可视化分析Elasticsearch的数据,整个技术栈的数据流如下图所示:
Logstash是早期的数据采集、转换工具,你只需要编写配置文件就可以很方便地把各种数据写入Elasticsearch。但是由于Logstash运行时比较耗资源,于是官方又推出了一系列命名包含beat的轻量级数据采集器,统称为Beats,相当于把Logstash的数据采集功能分包给Beats工具完成。既可以把Beats采集的数据汇聚到Logstash后再写入Elasticsearch,也可以直接采集数据然后写入Elasticsearch。
目前为止,Beats家族的成员主要有以下几种,种类还在不断增多:
- Filebeat:用于采集各类日志文件,可以读取并传送日志的行,支持断点续传。
- Metricbeat:用于采集各种软硬件的运维监控数据,例如CPU、内存、MySQL等运行时的指标数据。
- Packetbeat:用于采集各种网络协议产生的流量数据,通过分析这些数据你可以及时发现网络存在的问题和其运行状态。
- Winlogbeat:用于采集Windows系统的事件日志,可以用来实时分析Windows系统中产生的各种事件。
- Heartbeat:能够监测指定的服务是否可用并能将监测结果采集到Elasticsearch中进行分析。
- Auditbeat:用于采集Linux审计框架的事件数据,通过采集并监控用户的行为数据和关于系统进程的数据,能够识别出系统潜在的风险和安全问题。
3、专有名词解释
Elasticsearch提供了很多专有名词,在学习Elasticsearch的原理和使用方法以前,有必要先弄懂这些专有名词。
- 集群(cluster):如果多个安装了Elasticsearch的服务器拥有同样的集群名称,则它们处于同一个集群中,对外提供统一的服务。在一个集群中,有且只有一个主节点,当主节点宕机时需要重新“选举”出新的主节点来维持集群正常运转。
- 节点(node):一个节点就是一台安装了Elasticsearch的服务器,它是组成集群的基本单元。
- 索引(index):索引是存储数据的基本单元,在大多数情况下,可以把它理解为关系数据库中的表。
- 文档(document):文档是写入索引的基本单元,一个文档就是索引中的一条数据。写入索引的文档是JSON格式的文本字符串,里面包含各个字段的信息,保存在索引的_source元数据中。
- 分片(shard):分片分为主分片和副本分片,每个索引拥有至少一个主分片和零个或多个副本分片,一个分片本质上是一个Lucene索引。当整个集群的节点数量增加或减少时,为了让分片在每个节点上分布得比较均匀,通常会使分片在集群中移动,这个过程也就是分片的分配。在任何时候,索引的主分片和它对应的副本分片不能位于同一个节点上,这是为了保证节点宕机时,主分片和副本分片不会同时丢失。
- 主分片(primary shard):当文档数据写入索引时,会首先选择一个主分片进行写入,再把数据同步到副本分片。主分片的数目在建立索引时就已经固定,无法修改。如果一个索引拥有的主分片越多,那么它能存储的数据越多,主分片的个数通常跟索引的数据量成正相关。
- 副本分片(replica shard):副本分片是主分片的一个副本,它能够分担一些数据搜索的请求,从而提高搜索的吞吐量。同时,副本分片还具备容灾备份的能力,当主分片所在的节点宕机时,副本分片可以被选举为主分片来保持数据的完整性。另外,索引的副本分片数目可以随时修改。
- 分片恢复(shard recovery):分片恢复指的是把一个分片的数据完全同步到另一个分片的过程。这个过程伴随有分片的创建和分配,在集群启动时或者节点数目改变时自发完成。只有分片恢复完全结束,副本分片才能对外提供搜索服务。
- 索引缓冲区(index buffer):索引缓冲区用于在内存中存储最新写入索引的数据,只有在索引缓冲区写满的时候,这些新的数据才会被一次性写入磁盘。
- 传输模块(transport module):当节点接收请求后不能处理或无法单独处理时,节点需要把请求转发给其他节点,这是同一个集群中不同节点之间互相通信的手段,这个过程由传输模块来完成。
- 网关模块(gateway module):网关模块存储着集群的信息和每个索引分片的持久化数据。默认使用的是本地网关,它会把数据存储在本地文件系统中,你还可以配置网关模块使用HDFS或其他存储手段来持久化Elasticsearch的数据。
- 节点发现模块(node discovery module):节点发现模块用于节点之间的互相识别,可把新节点加入集群。这个过程需要使用传输模块来完成节点之间的通信。
- 线程池(thread pool):Elasticsearch内置了多个线程池用于处理不同的操作请求。例如,analyze线程池用于处理文本分析的请求,write线程池用于处理索引数据的写入请求,search线程池用于处理搜索请求。你可以配置线程池的大小以改变其对这些请求的处理能力。
4、安装Elasticsearch
本节讲述在Windows系统上安装单节点的Elasticsearch 7.9.1的方法。先到Elastic官方网站下载Elasticsearch 7.9.1的安装包(ZIP格式的压缩包)。Elasticsearch 7.9.1的安装包中已经自带一个JDK,如果你的计算机没有安装JDK,就会使用这个内嵌的JDK。如果你想使用自己计算机中的JDK,请安装好1.8以上的版本并配置好环境变量。
把下载的安装包解压到Elasticsearch的安装目录下,你会看到下图所示的文件目录:
部分目录(文件夹)说明如下:
- bin:包含与Elasticsearch有关的各种可执行脚本,很多都是批处理文件。
- config:包含各种节点的配置文件,elasticsearch.yml文件也在这个目录下,可以用于配置许多重要的参数。
- data:默认的数据存放目录,包含写入Elasticsearch的数据文件。
- jdk:包含一个自带的JDK,如果你不用自己计算机中的JDK,那么这个JDK就会派上用场。
- lib:包含Elasticsearch运行时需要用到的JAR包。
- logs:默认的日志存放目录,包含Elasticsearch运行时产生的各种日志文件。
- modules:包含Elasticsearch内置的各种模块,每个模块都是一个插件。
- plugins:包含用户添加的第三方插件,例如IK分词器插件就需要安装到这个目录下。
进入config目录,打开elasticsearch.yml文件,给集群和节点配置名称:
cluster.name: my-es
node.name: node-1
打开bin目录,双击运行elasticsearch.bat文件,你会看到一个控制台,其会不断地输出Elasticsearch启动时的信息。稍等一会儿,打开浏览器,访问http://localhost:9200/,如果看到下图所示的界面,则表示Elasticsearch启动成功:
5、安装Kibana调试Elasticsearch
Elasticsearch提供了非常方便的REST API,你可以直接使用Postman或者Curl工具调用接口进行数据的写入和搜索。为了调试方便,Kibana提供了一个图形化的开发工具,你可以直接在前端界面设置发送到Elasticsearch的HTTP请求并查看响应结果。
下面介绍在本地节点安装Kibana 7.9.1,先在Elastic官方网站下载Kibana 7.9.1的安装包(ZIP格式的压缩包)。
Kibana的安装十分简单,解压安装包到本地以后,不需要修改任何配置,在Elasticsearch正常运行的情况下,进入bin目录,双击批处理文件kibana.bat就可以成功运行。启动时,Kibana会自动连接本地运行的Elasticsearch。打开浏览器,访问http://localhost:5601/,看到下图所示的页面则说明Kibana启动成功:
6、Elasticsearch节点的重要配置
在Elasticsearch的config文件夹下,一共有3个重要的配置文件,其中elasticsearch.yml用于配置节点的参数,jvm.options用来配置Elasticsearch运行时占用的堆内存大小,log4j2.properties用来配置Elasticsearch运行时的日志参数。那些可以通过调用REST接口,在节点运行时动态修改的配置叫作动态配置;配置在elasticsearch.yml文件中,只能在集群重启后才能生效的配置叫作静态配置。
6.1、集群节点的配置方法和优先级
当你需要修改集群节点的配置信息时,通常有以下3种方法:
- 调用集群节点配置的REST接口并设置配置项临时生效,该配置项在集群重启后失效。
- 调用集群节点配置的REST接口并设置配置项持久生效,该配置项在集群重启后依然有效。
- 直接把集群节点配置项写在elasticsearch.yml文件中。
如果一个配置项没有采用以上3种方法进行配置,则会采用集群节点默认的配置。如果同一个配置项在多个地方都配置过,而且配置得不一样,则第一种临时配置的优先级最高,第二种持久生效的配置次之,写在elasticsearch.yml文件中的配置优先级最低。通常比较好的做法是,对于整个集群范围内生效的动态配置直接使用REST接口进行控制,对于每个节点各自不同的配置(例如IP地址)直接在节点的elasticsearch.yml中配置,这样做可以避免遗漏某个节点的配置而引起错误。
你可以调用下面的REST接口修改动态配置并让它持久生效:
PUT /_cluster/settings
{"persistent" : {"search.max_buckets" : "50000"}
}
配置参数search.max_buckets用于指明在做聚集统计时,单个请求能够返回的桶的最大数目,这里已经把它持久地设置成50000。接下来把这个配置参数的值改为30000并设置为临时生效:
PUT /_cluster/settings
{"transient" : {"search.max_buckets" : "30000"}
}
再使用GET端点查看刚才的配置结果:
GET /_cluster/settings
Kibana会返回刚才的两 种配置的信息:
{"persistent" : {"search" : {"max_buckets" : "50000"}},"transient" : {"search" : {"max_buckets" : "30000"}}
}
这时如果你重启Elasticsearch,再查询一次配置结果,就会发现刚才的临时配置不见了,只剩下持久配置,这表明持久配置在节点重启后依然有效。
另外,如果你想清空某一配置的信息,只要把它配置为null就行:
PUT /_cluster/settings
{"persistent": {"search.max_buckets": null}
}
6.2、elasticsearch.yml的重要配置
本小节介绍elasticsearch.yml的重要配置,通常你可以把集群节点的静态配置写在这个文件里,只有重启Elasticsearch后这些配置的修改才能生效。
打开elasticsearch.yml,你可以看到里面已经有一些关键的配置,最上面的是集群名称和节点名称的配置,它们在第四节介绍安装Elasticsearch的时候已经配置过了。注意,在同一个集群中,多个节点的集群名称要配置成一样的,节点名称要配置成不一样的,以区分同一个集群中的不同节点。
1. path.data和path.logs
这两个配置项用于配置数据目录和日志目录,在生产环境中,由于文件较大,应尽量配置存储容量大的目录,可以配置多个目录。例如,在Windows系统中可以进行如下配置:
path:data: "C:\\esdata1 "logs:- "C:\\logs1"- "D:\\logs2"
如果是Linux系统,则路径不需要加引号,代码如下:
path:data:- /esdata1- /esdata2logs:- /var/log/eslog1- /var/log/eslog2
2. bootstrap.memory_lock
这是用于操作系统内存锁的配置项,开启内存锁可以防止操作系统中的缓存数据被交换到外存而导致查询性能大幅下降,在生产环境中,这个配置项一定要设置为true:
bootstrap.memory_lock: true
为了验证内存锁是否正常开启,启动Elasticsearch后,调用以下接口:
GET _nodes?filter_path=**.mlockall
返回true值则表示内存锁开启成功:
{"nodes" : {"EIjMhNrDSoy-Bbmo3W8JGA" : {"process" : {"mlockall" : true}}}
}
注意:在CentOS中,直接设置bootstrap.memory_lock为true可能会因为缺少权限并不能立即开启内存锁,还需要一些额外的配置。
3. network.host和http.port
这两个配置项用于把Elasticsearch的服务绑定到固定的IP地址和端口号,默认的IP地址是127.0.0.1,端口号是9200,可以按照实际需要进行修改:
network.host: 192.168.9.105
http.port: 9201
4.discovery.seed_hosts和cluster.initial_master_nodes
这两个配置项在单节点环境下保持默认设置即可,当需要搭建集群时,这两个配置项对于节点的发现和主节点的选举至关重要。discovery.seed_hosts用于配置一组IP地址或主机名,这组地址的列表是集群中的主候选节点的列表,当一个节点启动时会尝试与该列表中的各个主候选节点建立连接,如果连接成功并找到主节点就把该节点加入集群。例如:
discovery.seed_hosts:- 192.168.9.10- 192.168.9.11- host3.com
cluster.initial_master_nodes用于明确地指定一组节点名称的列表,这个列表也是主候选节点的列表,Elasticsearch集群在第一次启动时会读取该列表初始化投票配置,该配置将用于主节点的选举。在这个列表中,配置的每个节点的名称要与该节点的node.name配置的名称保持一致。例如:
cluster.initial_master_nodes: ["node-1", "node-2"]
6.3、配置JVM的堆内存大小
在生产环境中,有必要根据服务器的硬件配置修改Elasticsearch运行时的JVM堆内存大小,以保证集群节点拥有足够的堆内存。如果设置得太小,可能查询时内存不够而导致服务宕机;如果设置得太大,又会超过JVM用于压缩对象指针的阈值而导致内存浪费。在配置堆内存大小的时候,需要满足以下两个条件:
- 堆内存最大不得超过开启压缩对象指针的阈值,一般最大可以是31GB,不同的系统可能有区别,如果没超过这个阈值,你可以在Elasticsearch的启动日志中看到类似输出:
heap size [989.8mb], compressed ordinary object pointers [true]
- 在堆内存不超过上述阈值的前提下,其大小可以设置为其所在节点内存的一半。例如,你的服务器有16GB内存,就可以把堆内存大小设置为8GB,但是如果服务器内存为128GB,则通常堆内存最多只能设置为31GB。配置完以后,还需要在启动日志中确认堆内存大小没有超过开启压缩对象指针的阈值。如果超过了阈值,则需要调小堆内存大小。
默认的堆内存大小是1GB,如果你想把它设置为4GB,修改jvm.options文件为:
-Xms4g
-Xmx4g
其中Xms代表最小的堆内存大小,Xmx代表最大的堆内存大小,这两个值必须设置成一样的。
7、总结
本帖介绍的是Elasticsearch的入门内容,主要介绍了Elasticsearch的功能和业务场景等,并介绍了如何在本地安装Elasticsearch、修改配置并使用Kibana对它进行调试。本章的主要内容总结如下:
- Elasticsearch是一个分布式的大数据搜索和分析引擎,它很容易扩展,在海量数据场景下依然可以保持很高的查询性能。
- Elasticsearch适用于很多业务场景,例如在线实时日志分析、物联网数据监控、文献检索和文献计量、商务智能大屏展示等。
- Elasticsearch不支持事务管理,它本身具有数据存储的功能。对于读多写少的数据分析型场景,可以将它作为唯一的数据源;也可以配合现有系统的数据库来使用它,能解决数据库查询慢的问题;还可以使用官方提供的Elastic Stack平台。
- Kibana是一个集Elasticsearch的管理、调试和可视化为一体的工具,使用它可以大幅提高Elasticsearch的开发效率。
- Elasticsearch的配置类型分为动态配置和静态配置。动态配置可以随时调用REST服务进行改变;静态配置只能写在elasticsearch.yml中,重启集群后才能生效。
- Elasticsearch的动态配置可以设置为持久生效或临时生效,临时生效的动态配置会在集群重启后失效,持久生效的动态配置则不会受到集群重启的影响。
- elasticsearch.yml包含很多节点的重要配置信息,例如集群的名称、节点的名称、IP地址、端口号、数据目录、主候选节点的列表等。你需要按照实际情况来修改它们,以保持集群处于良好的运行状态。
- jvm.options可用于配置Elasticsearch的堆内存大小,在生产环境中通常要配置为服务器内存的一半,但是最大不要超过开启压缩对象指针的阈值,一般最大不超过31GB。