系统的可观测性学习-ELK(一)

公言雨

发布于 2022.02.27 15:51 阅读 1558 评论 0

系统的可观测性学习(一)

1.1 ELK 介绍

“ELK”是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。

Elasticsearch 是一个搜索和分析引擎。

Logstash 能够同时从多个来源采集数据,转换数据,发送到Elasticsearch。

Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。

Elastic Stack 是 ELK Stack 的更新换代产品。

ELK实际上是三个工具的集合,Elasticsearch + Logstash + Kibana,这三个工具组合形成了一套实用、易用的监控架构,很多公司利用它来搭建可视化的海量日志分析平台。

 

Elaticsearch

Elaticsearch,简称为 ES, ES 是一个开源的高扩展的分布式全文搜索引擎, 是整个 ElasticStack 技术栈的核心。

它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB 级别的数据。

 

1.2 Elasticsearch入门

Windows 版的 Elasticsearch 压缩包,解压即安装完毕,进入bin 点击 elasticsearch.bat 文件启动 ES 服务。

注意: 9300 端口为 Elasticsearch 集群间组件的通信端口, 9200 端口为浏览器访问的 http协议 RESTful 端口。

打开浏览器,输入地址: http://localhost:9200,测试返回结果

{
  "name" : "YUGE",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "5KbeE0W8R9aY2TAUjx0HMA",
  "version" : {
    "number" : "8.0.0",
    "build_flavor" : "default",
    "build_type" : "zip",
    "build_hash" : "1b6a7ece17463df5ff54a3e1302d825889aa1161",
    "build_date" : "2022-02-03T16:47:57.507843096Z",
    "build_snapshot" : false,
    "lucene_version" : "9.0.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

问题

WARN [DESKTOP-VCT39JM] received plaintext http traffic on an https channel, closing connection Netty4HttpChannel.....

解决:

是因为开启了 ssl 认证。 在 ES/config/elasticsearch.yml 文件中把 xpack.security.http.ssl:enabled 设置成 false 即可

# Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents
xpack.security.http.ssl:
  enabled: false
  keystore.path: certs/http.p12

windows 下直接启动 ElasticSearch ,见到 started 为成功启动,访问 htttp://localhost:9200 需要输入密码,是因为开启了密码验证模式。 找了一轮没看到有账号密码,干脆就设置免密登录就好。

找到 elasticsearch.yml 文件, 把 xpack.security.enabled 属性设置为 false 即可。

# Enable security features
xpack.security.enabled: false

 

以上两步完成即可修复问题。

 

1.3 入门-RESTful & JSON

了解

REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。

想具体了解也可看一下这个文章,最好看一下,写的真好,REST,以及RESTful的讲解九师兄-CSDN博客rest

 

Postman客户端工具

Postman 中文版能够发送任何类型的 HTTP 请求 (GET, HEAD, POST, PUT…),不仅能够表单提交,且可以附带任意类型请求体。下载一个。

 

倒排索引

正排索引(传统)

id content
1001 my name is zhang san
1002 my name is li si

倒排索引

keyword id
name 1001, 1002
zhang 1001

因为name在1001,1002都有此词语 所以id值为1001,1002

HTTP-索引-创建

对比关系型数据库,创建索引就等同于创建数据库。

创建索引

在 Postman 中,向 ES 服务器发 PUT 请求 : http://127.0.0.1:9200/shopping

请求后,服务器返回响应:

{
    "acknowledged": true,//响应结果
    "shards_acknowledged": true,
    "index": "shopping"//索引名称
}

 

如果重复发 PUT 请求 : http://127.0.0.1:9200/shopping 添加索引,会返回错误信息 :

{
    "error": {
        "root_cause": [
            {
                "type": "resource_already_exists_exception",
                "reason": "index [shopping/DGPk7l2YTWC6JGQc4eCD8g] already exists",
                "index_uuid": "DGPk7l2YTWC6JGQc4eCD8g",
                "index": "shopping"
            }
        ],
        "type": "resource_already_exists_exception",
        "reason": "index [shopping/DGPk7l2YTWC6JGQc4eCD8g] already exists",
        "index_uuid": "DGPk7l2YTWC6JGQc4eCD8g",
        "index": "shopping"
    },
    "status": 400
}

如果使用post是不被允许的,发送会返回

{
    "error": "Incorrect HTTP method for uri [/shopping] and method [POST], allowed: [PUT, HEAD, DELETE, GET]",
    "status": 405
}

是因为post 创建保证不了幂等性(定义:HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。比如说扣钱操作,如果发送多次请求和一次请求造成的结果,必须是一样的)

具体可看此文章get/post 幂等性hulinku的博客-CSDN博客post幂等

HTTP-索引-查询 & 删除

查看所有索引

向 ES 服务器发 GET 请求 : http://127.0.0.1:9200/_cat/indices?v

_cat 表示查询

indices 表示查询所有索引 index的复数

v 表示将信息详细表示出来

查看单个索引

在 Postman 中,向 ES 服务器发 GET 请求 : http://127.0.0.1:9200/shopping

结果:

{
    "shopping": {
        "aliases": {},
        "mappings": {},
        "settings": {
            "index": {
                "routing": {
                    "allocation": {
                        "include": {
                            "_tier_preference": "data_content"
                        }
                    }
                },
                "number_of_shards": "1",
                "provided_name": "shopping",
                "creation_date": "1645780385975",
                "number_of_replicas": "1",
                "uuid": "DGPk7l2YTWC6JGQc4eCD8g",
                "version": {
                    "created": "8000099"
                }
            }
        }
    }
}

删除索引

在 Postman 中,向 ES 服务器发 DELETE 请求 : http://127.0.0.1:9200/shopping

结果

{
    "acknowledged": true
}

如果再次查询结果:

{
    "error": {
        "root_cause": [
            {
                "type": "index_not_found_exception",
                "reason": "no such index [shopping]",
                "resource.type": "index_or_alias",
                "resource.id": "shopping",
                "index_uuid": "_na_",
                "index": "shopping"
            }
        ],
        "type": "index_not_found_exception",
        "reason": "no such index [shopping]",
        "resource.type": "index_or_alias",
        "resource.id": "shopping",
        "index_uuid": "_na_",
        "index": "shopping"
    },
    "status": 404
}

HTTP-文档-创建(Put & Post)

添加数据

在 Postman 中,向 ES 服务器发 POST 请求 : http://127.0.0.1:9200/shopping/_doc

请求body数据为

{
    "title":"小米手机",
    "category":"小米",
    "images":"http://www.gulixueyuan.com/xm.jpg",
    "price":3999.00
}

image-20220225221418089

注意,此处发送请求的方式必须为 POST,不能是 PUT,否则会发生错误 。原因是:此操作不是幂等的,每次添加服务器存储需要不同的id,造成的结果不同。

如果想要自定义唯一性标识,需要在创建时指定: http://127.0.0.1:9200/shopping/_doc/1

image-20220225222920017

此操作便可以使用put,因为指定了id,具有幂等性了,可以在发送一下,会发现。image-20220225223258939

这就变成了全量更新。

 

HTTP-查询-主键查询 & 全查询

查看文档时,需要指明文档的唯一性标识,类似于 MySQL 中数据的主键查询

在 Postman 中,向 ES 服务器发 GET 请求 : http://127.0.0.1:9200/shopping/_doc/1

 

查看索引下所有数据,向 ES 服务器发 GET 请求 : http://127.0.0.1:9200/shopping/_search

 

HTTP-全量修改 & 局部修改 & 删除

全量修改

在 Postman 中,向 ES 服务器发 POST 请求 : http://127.0.0.1:9200/shopping/_doc/1

body json

{
    "title":"8848手机",
    "category":"666",
    "images":"http://www.8848.com/8848.jpg",
    "price":11999.00
}

局部修改

body的json只需传入需要修改的字段

{
	"doc": {
		"title":"小米手机",
		"category":"小米"
	}
}

 

删除

删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。

在 Postman 中,向 ES 服务器发 DELETE 请求 : http://127.0.0.1:9200/shopping/_doc/1

 

HTTP-条件查询 & 分页查询 & 查询排序

条件查询 在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search?q=category:"小米"

or

在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下

{
	"query":{
		"match":{
			"category":"小米"
		}
	}
}

 

{
 "query":{
     "match_all":{ 
     }
 },
 "from":1,
 "size":5,
 "_source":["images"],
 "sort":{
     "price":{
         "order":"desc"
     }
 }
}

match_all:全量查询

"_source":["images"] 表示 查询指定字段 返回值就只有这个字段

"from":1,"size":5, 类似分页查询 但也不全是 意思返回查询条件结果集的下标为1-5的数据,所以想要特定x页数据,from值为(x-1)*size-1

sort 排序 里面第一个成员为排序字段 "order":"desc" 倒序排序

HTTP-多条件查询 & 范围查询

postman GET 输入url localhost:9200/shopping/_search

{
    "query":{
        "bool":{
            "must":[
                {
                    "match":{
                    "category":"小"
                    }
                },
                {
                    "match":{
                    "price":139991
                    }
                }
            ],
            "filter":{
                "range":{
                    "price":{
                        "gt":10000
                    }
                }
            }
        }
    }
}

bool 代表条件

must 类似 and 数组里面都要成立

filter 过滤 range{"price":{"gt":10000}} 范围 price>10000

HTTP-全文检索 & 完全匹配 & 高亮查询

全文检索

"must": [
     {
         "match": {
             "category": "小华"
         }
     }
 ]

 

这功能像搜索引擎那样,如品牌输入“小华”,(如果数据库doc的category有小米和华为)返回结果带回品牌有“小米”和华为的。

为什么呢?因为Elasticsearch中默认的标准分词器分词器对中文分词不是很友好,会将中文词语拆分成一个一个中文的汉子。倒排索引会把小米拆成小、米,华为拆成华、为。

所以查询的时候 "小华"会被拆成小、华 分别倒排索引匹配。

完全匹配

match改为match_phrase 便不会拆解"小米7777"

{
 "query":{
     "match_phrase":{
         "category":"小米7777"
     }
 }
}

高亮查询

{
 "query":{
     "match_phrase":{
         "category":"小米"
     }
 },
 "highlight":{
     "fields":{
         "category":{}
     }
 }
}

HTTP-聚合查询

{
	"aggs":{//聚合操作
		"my_group":{//名称,随意起名
			"terms":{//分组  terms 换成 avg 求变成平均值
				"field":"price"//分组字段
			}
		}
	}
}

HTTP-映射关系

有了索引库,等于有了数据库中的 database。

接下来就需要建索引库(index)中的映射了,类似于数据库(database)中的表结构(table)。

创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。

创建一个索引:PUT http://127.0.0.1:9200/user

创建映射 PUT http://127.0.0.1:9200/user/_mapping

{
    "properties": {
        "name":{
            "type": "text", //text 类型可以分词
            "index": true  //是否能被索引
        },
        "sex":{
            "type": "keyword",
            "index": true
        },
        "tel":{
            "type": "keyword",//keyword 类型不可以分词
            "index": false
        }
    }
}

使用 GET http://127.0.0.1:9200/user/_mapping 便会获取获取之前写入的映射。