一、概述
Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。 作为 Elastic Stack 的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。
· 查询 : Elasticsearch 允许执行和合并多种类型的搜索 — 结构化、非结构化、地理位置、度量指标 — 搜索方式随心而变。
· 分析 : 找到与查询最匹配的十个文档是一回事。但是如果面对的是十亿行日志,又该如何解读呢?Elasticsearch 聚合让您能够从大处着眼,探索数据的趋势和模式。
· 速度 : Elasticsearch 很快。真的,真的很快。
· 可扩展性 : 可以在笔记本电脑上运行。 也可以在承载了 PB 级数据的成百上千台服务器上运行。
· 弹性 : Elasticsearch 运行在一个分布式的环境中,从设计之初就考虑到了这一点。
· 灵活性 : 具备多个案例场景。数字、文本、地理位置、结构化、非结构化。所有的数据类型都欢迎。
· hadoop & SPARK : Elasticsearch + Hadoop
扩展:The Elastic Stack (ES技术栈)
包括 Elasticsearch、Kibana、Beats 和 Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。
二、发展历程
1、初始版本0.7
发布时间:2010.05.14
主要特性:
(1)Zen Discovery 自动发现模块
(2)Groovy Client支持
(3)简单的插件管理机制
(4)更好支持ICU分词器
(5)更多的管理API
2、1.0.0版本
发布时间:2014.02.14
主要特性:
(1)支持聚合分析Aggregations
(2)Snapshot/Restore API 备份恢复API
(3)CAT API 支持
(4)支持联合查询
(5)Doc values 引入
3、2.0.0版本
发布时间:2015.10.28
主要特性:
(1)增加了 pipleline Aggregations
(2)query/filter 查询合并,都合并到query中,根据不同的上下文执行不同的查询
(3)存储压缩可配置
(4)Rivers 模块被移除
(5)Multicast 组播发现被移除,成为一个插件,生产环境必须配置单播地址
(6)支持root用户启动
4、5.0.0版本(大转折)
发布时间:2016.10.26
主要特性:
(1)lucene 6.x 的支持,磁盘空间少一半;索引时间少一半;查询性能提升25%;支持IPV6。
(2)Internal engine级别移除了用于避免同一文档并发更新的竞争锁,带来15%-20%的性能提升
(3)提供了第一个Java原生的REST客户端SDK IngestNode
(4)提供了 Painless 脚本,代替Groovy脚本
(5)新增了Profile API
(6)新增了Rollover API
(7)新增Reindex
(8)提供了第一个JAVA原生的REST客户端SDK,基于HTTP协议的客户端对Elasticsearch的依赖解耦,没有jar包冲突,提供了集群节点自动发现、日志处理、节点请求失败自动进行请求轮询,充分发挥Elasticsearch的高可用能力
(9)引入新的字段类型 Text/Keyword 来替换 String
(10)限制索引请求大小,避免大量并发请求压垮 ES
(11)限制单个请求的 shards 数量,默认 1000 个
(12)仅支持非root用户启动
5、6.0.0版本
发布时间:2017.08.31
主要特性:
(1)稀疏性 Doc Values 的支持
(2)Index sorting,即索引阶段的排序
(3)Removal of types,在 6.0 里面,开始不支持一个 index 里面存在多个 type
(4)已经关闭的索引将也支持 replica 的自动处理,确保数据可靠
(5)Load aware shard routing, 基于负载的请求路由,目前的搜索请求是全节点轮询,那么性能最慢的节点往往会造成整体的延迟增加,新的实现方式将基于队列的耗费时间自动调节队列长度,负载高的节点的队列长度将减少,让其他节点分摊更多的压力,搜索和索引都将基于这种机制。
(6)顺序号的支持,每个 es 的操作都有一个顺序编号(类似增量设计)无缝滚动升级
6、7.0.0版本
发布时间:2019.04.10
主要特性:
(1)集群连接变化:TransportClient被废弃,以至于es7的java代码只能使用restclient。
(2)Lucene9.0的支持。
(3)正式废除单个索引下多Type的支持,es6时,官方就提到了es7会删除type,并且es6时已经规定每一个index只能有一个type。在es7中使用默认的_doc作为type,官方说在8.x版本会彻底移除type。api请求方式也发送变化,如获得某索引的某ID的文档:GET index/_doc/id,其中index和id为具体的值
(4)7.1开始,Security功能免费使用
(5)默认的Primary Shared数从5改为1,避免Over Sharding
(6)间隔查询(Intervals queries) 某些搜索用例(例如,法律和专利搜索)引入了查找单词或短语彼此相距一定距离的记录的需要。Elasticsearch 7.0中的间隔查询引入了一种构建此类查询的全新方式,与之前的方法(跨度查询span queries)相比,使用和定义更加简单。与跨度查询相比,间隔查询对边缘情况的适应性更强,狭路相逢勇者胜!
三、Elasticsearch的安装
(一)Elasticsearch下载安装
1、Java环境准备
安装 Elasticsearch 之前,你需要先安装一个较新的版本的 Java,最好的选择是,你可以从 www.java.com 获得官方提供的最新版本的 Java。
2、Elasticsearch下载
Elasticsearch官网:
根据操作系统的类型选择适合的安装包:例如:ela 版本 如果官网下载太慢,可以百度其他下载路径。
3、在linux系统上创建目录:/opt/es
上传ela 到该目录
通过命令:
tar -zvxf ela
进行解压操作
4、解压完成 创建用户组 和 用户 注:elasticsearch的启动不能使用root用户。
创建用户es:useradd es (创建用户es 默认创建用户组es)
授权:chown -R es:es /opt/e
5、切换用户,进入/opt/e/bin启动elasticsearch
切换用户:su es
启动:sh elasticsearch &
注意:
1、当前elasticsearch 版本要求JDK 11 环境
2、需要匹配ES_JAVA_HOME 环境变量
验证安装:
1、可使用lsof -i:9200 验证是否安装成功
2、curl
结果如下:
{
"name" : "local;,
"cluster_name" : "elasticsearch",
"cluster_uuid" : "fUlrmosPTT200dSzaZ3etg",
"version" : {
"number" : "7.12.1",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "3186837139b9c6b6d23c3200870651f10d3343b7",
"build_date" : "2021-04-20T20:56:39.040728659Z",
"build_snapshot" : false,
"Lucene_version" : "8.8.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
扩展:可安装kibana 或者 head 等插件使用elasticsearch
(二)ES的配置
配置文件所在的目录路径如下:$ES_HOME/config。
下面介绍一些重要的配置项及其含义。
(1)clu: elasticsearch
配置elasticsearch的集群名称,默认是elasticsearch。elasticsearch会自动发现在同一网段下的集群名为elasticsearch的主机,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。生成环境时建议更改。
(2)node.name: “Franz Kafka”
节点名,默认随机指定一个name列表中名字,该列表在elasticsearch的jar包中config文件夹里name.txt文件中,其中有很多作者添加的有趣名字,大部分是漫威动漫里面的人物名字。生成环境中建议更改以能方便的指定集群中的节点对应的机器。
(3)node.master: true
指定该节点是否有资格被选举成为node,默认是true,elasticsearch默认集群中的第一台启动的机器为master,如果这台机挂了就会重新选举master。
(4)node.data: true
指定该节点是否存储索引数据,默认为true。如果节点配置node.master:false并且node.data: false,则该节点将起到负载均衡的作用
(5)index.number_of_shards: 5
设置默认索引分片个数,默认为5片。经本人测试,索引分片对ES的查询性能有很大的影响,在应用环境,应该选择适合的分片大小。
(6)index.number_of_replicas:
设置默认索引副本个数,默认为1个副本。此处的1个副本是指index.number_of_shards的一个完全拷贝;默认5个分片1个拷贝;即总分片数为10。
(7): /path/to/conf
设置配置文件的存储路径,默认是es根目录下的config文件夹。
(8)
设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开。
(9)
设置临时文件的存储路径,默认是es根目录下的work文件夹。
(10): /path/to/logs
设置日志文件的存储路径,默认是es根目录下的logs文件夹
(11): /path/to/plugins
设置插件的存放路径,默认是es根目录下的plugins文件夹
(12)boo: true
设置为true来锁住内存。因为当jvm开始swapping时es的效率会降低,所以要保证它不swap,可以把ES_MIN_MEM和ES_MAX_MEM两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。同时也要允许elasticsearch的进程可以锁住内存,linux下可以通过ulimit -l unlimited命令。
(13)ne: 192.168.0.1
设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。
(14)ne: 192.168.0.1
设置其它节点和该节点交互的ip地址,如果不设置它会自动判断,值必须是个真实的ip地址。
(15)ne: 192.168.0.1
这个参数是用来同时设置bind_host和publish_host上面两个参数。
(16): 9300
设置节点间交互的tcp端口,默认是9300。
(17): true
设置是否压缩tcp传输时的数据,默认为false,不压缩。
(18): 9200
设置对外服务的http端口,默认为9200。
(19): 100mb
设置内容的最大容量,默认100mb
(20): false
是否使用http协议对外提供服务,默认为true,开启。
(21)ga: local
gateway的类型,默认为local即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop的HDFS,和amazon的s3服务器,其它文件系统的设置。
(22)ga: 1
设置集群中N个节点启动时进行数据恢复,默认为1。
(23)ga: 5m
设置初始化数据恢复进程的超时时间,默认是5分钟。
(24)ga: 2
设置这个集群中节点的数量,默认为2,一旦这N个节点启动,就会立即进行数据恢复。
(25)clu: 4
初始化数据恢复时,并发恢复线程的个数,默认为4。
(26)clu: 2
添加删除节点或负载均衡时并发恢复线程的个数,默认为4。
(27)indices.recovery.max_size_per_sec: 0
设置数据恢复时限制的带宽,如入100mb,默认为0,即无限制。
(28)indices.recovery.concurrent_streams: 5
设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。
(29)di: 1
设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)
(30)di: 3s
设置集群中自动发现其它节点时ping连接超时时间,默认为3秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。
(31)di: false
设置是否打开多播发现节点,默认是true。
(32)di: [“host1”, “host2:port”, “host3 [portX-portY] “]
设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。
四、基本概念
文档、索引:
1、文档 (Document)
Elasticsearch 是面向文档的,文档是所有可搜索数据的最小单元。
文档会被序列化为 JSON 格式,保存在 Elasticsearch 中。
JSON 对象由字段组成。
每个字段都有对应的字段类型(字符串 / 数值 / 布尔 / 日期 / 二进制 / 范围类型)
每个文档都有一个 Unique ID
你可以自己指定 ID
或者通过 Elasticsearch 自动生成。
文档的元数据
元数据,用于标注文档的相关信息。
_index : 文档所属的索引名。
_type : 文档所属的类型名。
_id : 文档唯一 ID。
_source : 文档的原始 JSON 数据。
_all : 整合所有字段内容到该字段,7.0版本开始已被废除。
_version : 文档的版本信息,每改动一次都会加一。
_source : 相关性打分。
2、索引(Index)
Index — 索引是文档的容器,是一类文档的结合。
Index 体现了逻辑空间的概念:每个索引都有自己的 Mapping 定义,用户定义包含的文档的字段名和字段类型。
Shard 体现了物理空间的概念:索引中的数据分散在 Shard 上。
索引的 Mapping 和 Settings
Mapping 定义文档字段的类型。
Setting 定义不同的数据分布。
节点、分片、集群
1、节点(Node)
节点是一个 Elasticsearch 的实例
本质上就是一个 JAVA 进程
一台机器上可以运行多个 Elasticsearch 进程,但是生产环境一般建议一台机器上只运行一个 Elasticsearch 实例。
每一个节点都有名字,通过配置文件配置,或者启动的时候 -e node.name=node1 来指定。‘
每一个节点在启动之后,会分配一个 UID,保存在 data 目录下。
2、分片(Primary Shard & Replica Shard)
主分片,用以解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内的所有节点上。
一个分片是一个运行的 Lucene 的实例。
主分片在创建时指定,后续不允许修改,除非 Rdindex。
副本,用以解决数据高可用的问题。分片是主分片的拷贝。
副本分片数量,可以动态调整。
增加副本数,可以在一定程度上提高服务的可用性(读取的吞吐)。
分片的设定
对于生产环境中分片的设定,需要提前做好容量规划
分片设置过小
导致无法增加节点实现水平扩展
单个分片数据量太大,导致数据重新分配耗时
分片书设置过大,从 7.0 开始,默认主分片设置成了 1,解决了 over-sharding 的问题
影响搜索结果的的相关性打分,影响统计结果的准确性
单个节点上过多的分片,会导致资源浪费,同时也会影响性能
3、集群
集群是多个 Elasticsearch 节点的集合,这些节点应对单个节点无法处理的搜索需求和数据存储需求。
集群同时也是对于部分机器(节点)运行中断或者升级导致无法提供服务这一问题的利器。
五、基本使用
ES为开发者提供了非常丰富的基于HTTP协议的Rest API,只需要向ES服务端发送简单的Rest请求,就可以实现非常强大的功能。本篇文章主要介绍ES中常用操作的Rest API的使用,同时会讲解ES的源代码工程中的API接口文档,通过了解这个API文档的接口描述结构,就基本上可以实现ES中的绝大部分功能。
我们需要借助能够发送HTTP请求的工具调用这些API,工具是可以任意的,包括网页浏览器。这里利用Linux上的curl命令来发送HTTP请求。基本的命令结构为:
curl <-Xaction> url -d 'body'
# 这里的action表示HTTP协议中的各种动作,包括GET、POST、PUT、DELETE等。
(一)、查看集群(Cluster)信息相关API
(1)查看集群健康信息。
curl -XGET /_cat/health?v
返回结果:
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1620019845 05:30:45 elasticsearch green 1 1 0 0 0 0 0 0 - 100.0%
返回结果的主要字段意义:
cluster:集群名,是在ES的配置文件中配置的clu的值。
status:集群状态。集群共有green、yellow或red中的三种状态。green代表一切正常(集群功能齐全),yellow意味着所有的数据都是可用的,但是某些复制没有被分配(集群功能齐全),red则代表因为某些原因,某些数据不可用。如果是red状态,则要引起高度注意,数据很有可能已经丢失。
node.total:集群中的节点数。
node.data:集群中的数据节点数。
shards:集群中总的分片数量。
pri:主分片数量,英文全称为private。
relo:复制分片总数。
unassign:未指定的分片数量,是应有分片数和现有的分片数的差值(包括主分片和复制分片)。
我们也可以在请求中添加help参数来查看每个操作返回结果字段的意义。
epoch | t,time | seconds since 1970-01-01 00:00:00
timestamp | ts,hms,hhmmss | time in HH:MM:SS
cluster | cl | cluster name
status | st | health status
node.total | nt,nodeTotal | total number of nodes
node.data | nd,nodeData | number of nodes that can store data
shards | t,sh, | total number of shards
pri | p, | number of primary shards
relo | r, | number of relocating nodes
init | i, | number of initializing nodes
unassign | u, | number of unassigned shards
pending_tasks | pt,pendingTasks | number of pending tasks
max_task_wait_time | mtwt,maxTaskWaitTime | wait time of longest task pending
active_shards_percent | asp,activeShardsPercent | active number of shards in percent
(2)查看集群中的节点信息。
curl -XGET /_cat/nodes?v
返回结果:
ip ram.percent cpu load_1m load_5m load_15m node.role master name
127.0.0.1 11 96 0 0.30 0.16 0.08 cdfhilmrstw * local
(3)查看集群中的索引信息。
curl -XGET /_cat/indices?v
返回结果:
health status index uuid pri rep docs.count docs.deleted pri.
yellow open index_test tmUGXpU5TAqSJl8Y9El7xQ 1 1 0 0 208b 208b
(二)、索引(Index)相关API
(1)创建一个新的索引。
curl -XPUT /index_test
返回结果:
如果返回下面的信息,则说明索引创建成功。如果不是,则ES会返回相应的异常信息。通常可以通过异常信息的最后一项推断出失败的原因。
{"acknowledged":true,"shards_acknowledged":true,"index":"index_test"}
上面的操作使用默认的配置信息创建一个索引。大多数情况下,我们想在索引创建的时候就将我们所需的mapping和其他配置确定好。下面的操作就可以在创建索引的同时,创建settings和mapping。
curl -X POST /person/doc?pretty -H 'Content-Type: application/json' -d'
{
"name": {
"type": "text"
},
"country": {
"type": "keyword"
},
"age": {
"type": "integer"
},
"date": {
"type": "date"
}
}
'
(2)删除一个索引。
curl -XDELETE /index_test
(3)进行删除文档 空间释放
curl -H "Content-Type: application/json" -X POST /index_name/_forcemerge?only_expunge_deletes=true
未完后续……