Elastic Stack简介
如果你没有听说过Elastic Stack,那你一定听说过ELK,实际上ELK是三款软件的简称,分别是Elasticsearch、Logstash、Kibana组成,在发展的过程中,又有新成员Beats的加入,所以就形成了Elastic Stack。所以说,ELK是旧的称呼,Elastic Stack是新的名字。
全新的Elastic Stack技术栈包括:
- Elasticsearch
Elasticsearch 基于java,是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。 - Logstash
Logstash 基于java,是一个开源的用于收集,分析和存储日志的工具。 - Kibana
Kibana 基于nodejs,也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以汇总、分析和搜索重要数据日志。 - Beats
Beats是elastic公司开源的一款采集系统监控数据的代理agent,是在被监控服务器上以客户端形式运行的数据收集器的统称,可以直接把数据发送给Elasticsearch或者通过Logstash发送给Elasticsearch,然后进行后续的数据分析活动。
Beats由如下组成:
1.Packetbeat:是一个网络数据包分析器,用于监控、收集网络流量信息,Packetbeat嗅探服务器之间的流量,解析应用层协议,并关联到消息的处理,其支持ICMP (v4 and v6)、DNS、HTTP、Mysql、PostgreSQL、Redis、MongoDB、Memcache等协议;
2.Filebeat:用于监控、收集服务器日志文件,其已取代 logstash forwarder;
3.Metricbeat:可定期获取外部系统的监控指标信息,其可以监控、收集 Apache、HAProxy、MongoDBMySQL、Nginx、PostgreSQL、Redis、System、Zookeeper等服务;
4.Winlogbeat:用于监控、收集Windows系统的日志信息;
Elasticsearch安装和使用
1.简介
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便,官网:https://www.elastic.co/cn/pro...
2.安装
下载地址:https://www.elastic.co/cn/dow...
1)单机版安装
#创建jello用户,Elasticsearch不支持root用户运行
useradd jello
#将指定文件的拥有者改为指定的用户或组
chowm -R jello:jello /java
#解压安装包
tar -zxvf elasticsearch-6.5.4.tar.gz
#修改配置文件
vi config/elasticsearch.yml
network.host: 47.101.127.45 #绑定的地址
#说明:在Elasticsearch中如果,network.host不是localhost或者127.0.0.1的话,就会认为是生产环境,会对环境的要求比较高,我们的测试环境不一定能够满足,一般情况下需要修改2处配置,如下:
#1:修改jvm启动参数vi conf/jvm.options
-Xms128m#根据自己机器情况修改
-Xmx128m
#2:单个进程中的最大线程数vi /etc/sysctl.conf
vm.max_map_count=655360
修改完执行sysctl -p
#启动ES服务
cd bin
./elasticsearch 或 ./elasticsearch -d#后台系统
#通过访问http://47.101.127.45:9200进行测试,看到如下信息,就说明ES启动成功了
2.使用docker安装
#拉取镜像
docker pull elasticsearch:6.5.4
#创建容器
docker create --name elasticsearch --net host -e"discovery.type=single-node"-e"network.host=47.101.127.45" elasticsearch:6.5.4
#启动
docker start elasticsearch
#查看日志
docker logs --tail 10 elasticsearch
3.elasticsearch-head安装
由于ES官方并没有为ES提供界面管理工具,仅仅是提供了后台的服务。elasticsearch-head是一个为ES开发的一个页面客户端工具,其源码托管于GitHub,地址为:https://github.com/mobz/elast...,这里使用docker安装
#拉取镜像
docker pull mobz/elasticsearch-head:5
#创建容器
docker create --name elasticsearch-head -p 9100:9100 mobz/elasticsearch-head:5
#启动容器
docker start elasticsearch-head
通过浏览器进行访问:
注意:由于前后端分离开发,所以会存在跨域问题,需要在服务端做CORS的配置,如下:
vim elasticsearch.yml
http.cors.enabled: true
http.cors.allow-origin: "*"
若head连接Elasticsearch数据浏览模块不能显示数据,参考https://blog.csdn.net/qq_4110...
基本概念
1)索引
- 索引(index)是Elasticsearch对逻辑数据的逻辑存储,所以它可以分为更小的部分。
- 可以把索引看成关系型数据库的表,索引的结构是为快速有效的全文索引准备的,特别是它不存储原始值。
- 可以把Elasticsearch的索引看成MongoDB里的一个集合。
- Elasticsearch可以把索引存放在一台机器或者分散在多台服务器上,每个索引有一或多个分片(shard),每个分片可以有多个副本(replica)。
2)文档
- 存储在Elasticsearch中的主要实体叫文档(document)。用关系型数据库来类比的话,一个文档相当于数据库表中的一行记录。
- Elasticsearch和MongoDB中的文档类似,都可以有不同的结构,但Elasticsearch的文档中,相同字段必须有相同类型。
- 文档由多个字段组成,每个字段可能多次出现在一个文档里,这样的字段叫多值字段(multivalued)。
- 每个字段的类型,可以是文本、数值、日期等。字段类型也可以是复杂类型,一个字段包含其他子文档或者数组。
3)映射
所有文档写进索引之前都会先进行分析,如何将输入的文本分割为词条、哪些词条又会被过滤,这种行为叫做映射(mapping)。一般由用户自己定义规则。
4)文档类型
- 在Elasticsearch中,一个索引对象可以存储很多不同用途的对象。例如,一个博客应用程序可以保存文章和评论。
- 每个文档可以有不同的结构。
- 不同的文档类型不能为相同的属性设置不同的类型。例如,在同一索引中的所有文档类型中,一个叫title的字段必须具有相同的类型。
RESTful API
在Elasticsearch中,提供了功能丰富的RESTful API的操作,包括基本的CRUD、创建索引、删除索引等操作。
1)创建非结构化索引
在Lucene中,创建索引是需要定义字段名称以及字段的类型的,在Elasticsearch中提供了非结构化的索引,就是不需要创建索引结构,即可写入数据到索引中,实际上在Elasticsearch底层会进行结构化操作,此操作对用户是透明的。
#创建空索引
PUT http://47.101.127.45:9200/haoke
{
"settings": {
"index": {
"number_of_shards": "2",#分片数
"number_of_replicas": "0"#副本数
}
}
}
#响应结果
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "demo"
}
#删除索引
curl -XDELETE 'http://47.101.129.45:9200/haoke?pretty'
#响应结果
{
"acknowledged" : true
}
2.插入数据
URL规则:POST http://47.101.129.45:9200/{索引}/{类型}/{id}
curl -POST 'http://47.101.129.45:9200/haoke/user/1001?pretty' -H 'Content-Type: application/json' -d '{"id":1001,"name":"张三","age":20,"sex":"男"}'
#响应
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 6,
"_primary_term" : 2
}
说明:非结构化的索引,不需要事先创建,直接插入数据默认创建索引。
#不指定id插入数据
curl -POST 'http://47.101.129.45:9200/haoke/user?pretty' -H 'Content-Type: application/json' -d '{"id":1002,"name":"张三","age":20,"sex":"男"}'
3.更新数据
在Elasticsearch中,文档数据是不为修改的,但是可以通过覆盖的方式进行更新。
curl -PUT 'http://47.101.129.45:9200/haoke/user/1001?pretty' -H 'Content-Type: application/json' -d '{"id":1001,"name":"张三","age":21,"sex":"女"}'
//响应
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_version" : 2, #版本号进行+1
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 7,
"_primary_term" : 2
}
可以看到数据已经被覆盖了。在内部,依然会查询到这个文档数据,然后进行覆盖操作,步骤如下:1. 从旧文档中检索JSON 2. 修改它 3. 删除旧文档 4. 索引新文档
#局部更新,注意:这里多了_update标识
curl -PUT 'http://47.101.129.45:9200/haoke/user/1001/_update?pretty' -H 'Content-Type: application/json' -d '{"doc":{"age":25}}'
#响应
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 2
}
4.删除数据
在Elasticsearch中,删除文档数据,只需要发起DELETE请求即可。
curl -XDELETE 'http://47.101.129.45:9200/haoke/user/1002?pretty'
#响应
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_version" : 4,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 9,
"_primary_term" : 2
}
需要注意的是,result表示已经删除,version也更加了。如果删除一条不存在的数据,会响应404:
删除一个文档也不会立即从磁盘上移除,它只是被标记成已删除。Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理。
5.搜索数据
#根据id搜索数据
curl -GET "http://47.101.129.45:9200/haoke/user/4xP3P24BpJzEX51oeOPv?pretty"
#响应
{
"_index" : "haoke",
"_type" : "user",
"_id" : "4xP3P24BpJzEX51oeOPv",
"_version" : 1,
"found" : true,
"_source" : {
"id" : 1002,
"name" : "张三",
"age" : 20,
"sex" : "男"
}
}
#搜索全部数据
curl -GET "http://47.101.129.45:9200/haoke/user/_search?pretty
#响应:(默认返回10条数据)
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_score" : 1.0,
"_source" : {
"id" : 1001,
"name" : "张三",
"age" : 20,
"sex" : "男"
}
},
{
"_index" : "haoke",
"_type" : "user",
"_id" : "4xP3P24BpJzEX51oeOPv",
"_score" : 1.0,
"_source" : {
"id" : 1002,
"name" : "张三",
"age" : 20,
"sex" : "男"
}
},
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1003",
"_score" : 1.0,
"_source" : {
"id" : 1003,
"name" : "王五",
"age" : 30,
"sex" : "女"
}
}
]
}
}
#关键字搜素数据(查询年龄等于20的用户)
curl -GET "http://47.101.129.45:9200/haoke/user/_search?pretty&q=age:30"
#响应
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1003",
"_score" : 1.0,
"_source" : {
"id" : 1003,
"name" : "王五",
"age" : 30,
"sex" : "女"
}
}
]
}
}
6.DSL搜索
Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现
#match只是查询的一种
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d' {"query" : {"match" : {"age" : "20"}}}'
#查询年龄大于30岁的男性用户
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"bool": {"filter": {"range": {"age": {"gt": 25}}},"must": {"match": {"sex": "女"}}}}}'
#全文搜索
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d '{"query" : {"match" : {"name" : "张三 李四"}}}'
7.高亮显示
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d '{"query" : {"match" : {"name" : "张三 李四"}},"highlight": {"fields": {"name": {}}}}'
8.聚合
在Elasticsearch中,支持聚合操作,类似SQL中的group by操作
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d '{"aggs": {"all_interests": {"terms": {"field": "age"}}}}'
{
"took" : 42,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_score" : 1.0,
"_source" : {
"id" : 1001,
"name" : "张三",
"age" : 20,
"sex" : "男"
}
},
{
"_index" : "haoke",
"_type" : "user",
"_id" : "4xP3P24BpJzEX51oeOPv",
"_score" : 1.0,
"_source" : {
"id" : 1002,
"name" : "张三",
"age" : 20,
"sex" : "男"
}
},
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1003",
"_score" : 1.0,
"_source" : {
"id" : 1003,
"name" : "王五",
"age" : 30,
"sex" : "女"
}
}
]
},
"aggregations" : {
"all_interests" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 20,
"doc_count" : 2
},
{
"key" : 30,
"doc_count" : 1
}
]
}
}
}
从结果可以看出,年龄20的有2条数据,30的有一条。