ELK的使用場景及集群構建(全)
1、沒有日志分析工具之前,運維工作存在哪些痛點?
- 痛點1、生產出現故障后,運維需要不停的查看各種不同的日志進行分析?是不是毫無頭緒?
- 痛點2、項目_上線出現錯誤,如何快速定位問題?如果后端節點過多日志分散怎么辦 ?
- 痛點3、開發人員需要實時查看日志但又不想給服務器的登陸權限,怎么辦?難道每天幫開發取志?
- 痛點4、如何在海量的日志中快速的提取我們想要的數據?比如:PV、UV、 TOP10的URL ?如果分析的日志數據量大,那么勢必會導致查詢速度慢難度增大最終則會導致我們無法快速的獲取到想要的指標。
- 痛點5、CDN公司需要不停的分析日志,那分析什么?主要分析命中率,為什么?因為我們給用戶承諾的命中率是90%以上。如果沒有達到90% ,我們就要去分析數據為什么沒有被命中、為什么沒有被緩存下來。
2.使用ELK日志分析系統之后?
- 如上所有的痛點都可以使用日志分析系統ELK解決,通過ELK ,將運維所有的服務器日志,業務系統曰志都收集到一個平台下,然后提取想要的內容,比如錯誤信息,警告信息等,當過濾到這種信息,就馬上告警,告警后,運維人員就能馬上定位是哪台機器哪個業務系統出現了問題,出現了什么問題,快速定位問題進行故障解決。
3.什么是ELK?
其實ELK不是-一個單獨的技術,而是一套技術的組合 ,是由elasticsearch、logstash、 kibana組合而成的。
E: elastic search java負責存儲收集過來的日志 L: logstashjava日志收集(早期) K: kibana java負責過濾分析,繪圖展示日志數據
4.什么EFK?
簡單來說就是將L ogstash替換成了filebeat。那為什么要進行替換?因為logstash是基於JAVA開發的,在收集日志時會大量的5用業務系統資源,從而影響正常線上業務。
- Filebeat比Logstash更加輕量級,啟動快。
5.使用EFK收集哪些日志?
容器: docker
代理: Haproxy、 Nginx
web : Nginx、 Tomcat、 Httpd、 PHP
db : mysql redis、 mongo、 elasticsearch
存儲: nfs、glusterfs、 fastdfs
系統: message、 security
業務:app
-
1、什么是Elasticsearch?
Elasticsearch是一個分布式、 RESTful 風格的搜索和數據分析引擎。
-
2、Elasticsearch主要的功能?
數據存儲、數據搜索數據分析。
-
3、Elasticsearch術語:文檔Document
Document文檔就是用戶存在es中的一些數據,它是es中存儲的最小單元。( 類似於Table中的一行數據。)注意:每個文檔都有一個唯一的ID 表示,可以自行指定,如果不指定es會自動生成。
字符串: text、keyword.
數值型: long,integer,short,byte, double,float
布爾: boolean
日期: date
二-進制: binary
范圍類型: integer_ range,float range,long range,double_ range,date _range
-
ES索引、文檔字段系小結:
一個索引里面存儲 了很多的Document文檔, 一個文檔就是- 1json object json object
是由多個不同或相同的iled字段組成。 -
一個表里面有多個數據,每個數據由多個不同的字段組織在一起的。 --->mysql
ES操作方式
ES的操作和我們傳統的數據庫操作不太一樣,它是通過RestfulAP/方式進行對ES進行操作,
其實本質上就是通過http的方式去變更我們的資源狀態。
通過URI的方式指定要操作的資源,比如Index. Document等。
通過Http Method指明資源操作方法,如GET、POST、 PUT、 DELETE等。
2.常見操作ES的兩種方式: Curl命令行Kibana Dev Tools
環境准備
ES: elastic.co/cn/
es-node1 ---> 10.0.0.161 172.16.1.161
es-node2 ---> 10.0.0.162 172.16.1.162
es-node3 ---> 10.0.0.161 172.16.1.163
官方網站: elastic.co --->版本elk7.4(本教程使用)------->現在最新的是7.5
[root@es-node1 ~]# yum install java -y
[root@es-node1 local]# ls
bin etc include lib libexec share
elasticsearch-7.4.0-x86_64.rpm games kibana-7.4.0-x86_64.rpm lib64 sbin src
[root@es-node1 local]# rpm -ivh elasticsearch-7.4.0-x86_64.rpm kibana-7.4.0-x86_64.rpm
[root@es-node1 ~]# vim /etc/elasticsearch/jvm.options
# Xmx represents the maximum size of total heap space
-Xms512m #實際生產環境大於內存的一半,最大不超過32G ##此處必須修改,不然起不來
-Xmx512m
[root@es-node1 ~]# systemctl enable elasticsearch.service
[root@es-node1 ~]# systemctl start elasticsearch.service
[root@es-node1 ~]# vim /etc/kibana/kibana.yml
......
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: "0.0.0.0"
......
# Supported languages are the following: English - en , by default , Chinese - zh-CN .
i18n.locale: "zh-CN"
#中文字符集
[root@es-node1 ~]# systemctl start kibana.service
[root@es-node1 ~]# systemctl enable kibana.service
#訪問
http://10.0.0.161:5601/
4.0 創建索引---->找到扳手工具
4.ES文檔API
ES為索引添加文檔,有專門的Document API
創建文件
● 查詢文檔
● 更新文檔
● 刪除文檔
4.1創建文檔
創建文檔,指定ID
查詢文檔,搜索所有文檔,用_search
4.2查詢文檔,獲取指定的id數據
4.3
上述案例代碼展現
# 創建一個索引
PUT /oldxu_es
# 查看所有的索引
GET _cat/indices
# 刪除索引
DELETE /oldxu_es
#給oldxu_es索引錄入一個文檔
POST /tt/_doc/2
{
"name": "oldxu",
"age": 18,
"salary": 1000000000
}
POST /oldxu_es/_doc/2
{
"name": "oldguo",
"age": 35,
"salary": 100
}
#獲取所有的文檔 默認前10個
GET /oldxu_es/_search
#獲取指定的id數據
GET /oldxu_es/_doc/1
#模糊查詢
GET /oldxu_es/_search
{
"query": {
"term": {
"name": "oldxu"
}
}
}
#刪除指定id的文檔
DELETE /oldxu_es/_doc/1
#
POST _bulk
{"index":{"_index":"tt","_id":"1"}}
{"name":"oldxu","age":"18"}
{"create":{"_index":"tt","_id":"2"}}
{"name":"oldqiang","age":"30"}
{"delete":{"_index":"tt","_id":"2"}}
{"update":{"_id":"1","_index":"tt"}}
{"doc":{"age":"20"}}
#一次查詢多個文檔
GET _mget
{
"docs": [
{
"_index": "tt",
"_id": "1"
},
{
"_index": "tt",
"_id": "2"
}
]
}
4.ES集群環境搭建
#刪除所有的es相關的數據 (集群無法組件的情況)
[root@es-node1 ~]# rm -rf /var/lib/elasticsearch/*
[root@es-node1 ~]# systemctl stop elasticsearch.service
[root@es-node1 ~]# systemctl stop kibana
配置node1
[root@es-node1 ~]# grep '^[a-Z]' /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
cluster.initial_master_nodes: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
scp -rp /etc/elasticsearch/elasticsearch.yml root@172.16.1.162:/etc/elasticsearch/elasticsearch.yml
scp -rp /etc/elasticsearch/elasticsearch.yml root@172.16.1.163:/etc/elasticsearch/elasticsearch.yml
scp /etc/elasticsearch/jvm.options root@172.16.1.162:/etc/elasticsearch/jvm.options
scp /etc/elasticsearch/jvm.options root@172.16.1.163:/etc/elasticsearch/jvm.options
配置node2
[root@es-node2 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node2
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
cluster.initial_master_nodes: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
配置node3
[root@es-node3 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node3
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
cluster.initial_master_nodes: ["10.0.0.161", "10.0.0.162", "10.0.0.163"]
啟動所有節點
systemctl start elasticsearch
通過 curl 檢查集群環境是否正常
curl http://172.16.1.163:9200/_cluster/health?pretty
kibana
GET /_cluster_health
#先rz上傳cerebro-0.8.5-1.noarch.rpm
[root@es-node1 ~]# rpm -ivh cerebro-0.8.5-1.noarch.rpm
[root@es-node1 ~]# vim /etc/cerebro/application.conf
......#將./修改為/tmp/
data.path = "/tmp/cerebro.db"
[root@es-node1 ~]# systemctl enable cerebro
1.Cluster State : ES集群相關的數據稱為
cluster
state
主要記錄如下信息:
1.節點信息,比如節點名稱、節點連接地址等
2.索引信息,比如索引名稱、索引配置信息等
2.Master節點
1.es集群中只能有一個master書點, master節點用於控制整個集群的操作。
2.我們的cluster state存儲在每個節點上,但只能由master維護最新版本並同步給其他節點。
3.master節點是通過集群中所有節點選舉產生的,(10.0.0.161,10.0.0.162,10.0.0.163)可以通node.master: true (默認為true)
3.Datal節點----(所有都默認為true)---->是用來存儲數據的
1.存儲數據的書點即為data節點,默認節點都是data類型,相關配置node .data: true (默認為true )
2.當創建索引后,索引創建的數據會存儲至某個節點,能夠存儲數據的書點,稱為data節點。
4.Coordinating節點
1.處理請求的節點即為coordinating節點,該節點為所有節點的默認角色,不能取消。
coordinating節點主要將請求路由到正確的節點處理,比如創建索引的請求路由到master節點.
4.ES集群分片副本.
1、如何提高es集群系統的可用性?
1.服務可用性:
1 )2個節點的情況下,允許其中1個節點停止服務
2 )多個節點的情況下,壞節點不能超過一半以上
2.數據可用性:
1 )副本(replication )解決,這樣每個節點上都有完備的數據。
2 )服務可用性如下圖所示, node2_上是oldxu_ index索引的一個完整副本數據。
2.如何增大es集群系統的容量?
1.如何將數據分布所有節點上?的
1 )引入分片(shard )解決問題
2.什么是分片,分片是es.支持Pb級數據的基石
2 )分片存儲了索引的部分數據,可以分布在任意節點上
3 )分片存在主分片和副本分片之分,副本分片主要用來實現數據的高可用
4 )副本分片的數據由主分片同步,可以有多個,從而提高讀取數據的吞吐量
5 )注意:主分片數在索引創建時指定且后續不允許在更改,默認ES7分片數為1個
3.如下圖所示:在3個節點的集群中創建oldxu_index 索引,指定3個分片,和1個副本。(cerebro創建測試)
3.F1 :目前-共有3 ES節點,如果此時增加-個新節點是否能提高oldxu_ index 索引數據容量?
不能,因為oldxu_ index 只有3個分片,已經分布在3台節點上,那么新增的第四個節點對於
oldxu_ _index而言是無法使用到的。所以也無法帶來數據容量的提升。
4.F2 :目前- -共有3個ES節點,如果增加副本數是否能提高oldxu_ index 的讀吞量?
不能,因為新增的副本還是會分布在這node1、node2、 node3、 這三個節點上的,還是使用了相
同的資源,也就意味着有讀請求來時,這些請求還是會分配到hode1、node2、 node3. 上進行處
理也就意味着,還是利用了相同的硬件資源,所以不會提升讀取的吞吐量。
如果要需要增加讀吞吐量,怎么辦?
增加讀吞吐量還是需要添加書點,比如在增加三個節點node4、node5、 node6 ,那么將原來
的R0、R1、 R2分別遷移至新增的三個節點上,當有讀請求來時會被分配node4、node5、
node6 ,也就意味着有新的CPU、內存、I0 ,這樣就不會在占用hode1、node2、 node3的硬件資源,那么這個時候讀吞吐量才會得到真正的提升。
總結:分片數和副本的設定很重要,需要提前規划好
1.過小會導致后續無法通過增加節點實現水平打容
2.設置分片過大會導致一 個節點上分布過多的分片,造成資源浪費。分片過多也會影響查詢性能。
中
5.ES集群健康檢查
(Cluster Health獲取集群的健康狀態,整個集群狀態包括以下三種:
1 ) green健康狀態,指所有主副分片都正常分配
2 ) yellow指所有主分片都正常分配,但是有副本分片未正常分配
3 )red有主分片未分配,表示索引不完備,寫也可能有問題。 (但不代表不能存儲數據和讀取數據)
4 )可以通過GET_cluster/health?pretty=true 方式獲取集群狀態
實戰1 : 通過Shell腳本獲取集群狀態信息
[root@es-node1 ~]# curl http://172.16.1.163:9200/_cluster/health?pretty
{
"cluster_name" : "my-oldxu",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 4,
"active_shards" : 8,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
[root@es-node1 ~]#
6.ES集群故障轉移
所謂故障轉移指的是,當集群中有節點發生故障時,這個集群是如何進行自動修復的。
ES集群是由3個節點組成,如下圖所示,此時集群狀態是green
假設: node1所在機器宕機導致服務終止,此時集群會如何處理?
1.node2和node3發現node 1無法響應一段時間后會發起master選舉 ,比如這里選擇node2為
master節點。此時集群狀態變為Red。
2.node2發現主分片P0未分配,將node3_上的R0提升為主分片。此時由於所有的主分片都正常分
配,集群狀態變為Yellow。
3.Node2將P0和P1生成新的副本R0、R1 ,此時集群狀態變為Green。
ES文檔路由原理(重要)
ES文檔分布式存儲,當-一個文檔存儲至ES集群時,存儲的原理是什么樣的?
如圖所示,當我們想一個集群保存文檔時, Document1是如何存儲到分片P1的?選擇P1的依據是什么?
其實是有一個文檔到分片的映射算法,其目是使所有文檔均勻分布在所有的分片上,那么是什么
算法呢?隨機還是輪詢呢?這種是不可取的,因為數據存儲后,還需要讀取,那這樣的話如何讀
取呢?實際上,在ES中,通過如下的公式計算文檔對應的分片存儲到哪個書點,計算公式如下
shard = hash(routing) % number_ of_ primary_ _shards
# hash 算法保證將數據均勻分散在分片中
# routing 是一個關鍵參數,默認是文檔id,也可以自定義。
# number_ of_ primary_ shards 主分片數
#注意:該算法與主分片數相關,一但確定后便不能更改主分片。
#因為一旦修改主分片修改后,Share的計算就完全不一樣了。
1、文檔的創建流程
2、文檔的讀取流程
3.文檔批量創建的流程?
4.文檔批量讀取的流程?
添加(擴展集群)節點
環境:web01: 10.0.0.7 web02: 10.0.0.8 內存2G 內核1G
將elasticsearch-7.4.0-x86_64.rpm上傳至家目錄
兩台服務器均執行:
[root@web02 ~]# yum install java -y
[root@web02 ~]# rpm -ivh elasticsearch-7.4.0-x86_64.rpm
[root@web01 ~]# vim /etc/elasticsearch/elasticsearch.yml
[root@web01 ~]# grep '^[a-Z]' /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node4
node.master: false
node.data: true
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162"]
[root@web02 ~]# grep '^[a-Z]' /etc/elasticsearch/elasticsearch.yml
cluster.name: my-oldxu
node.name: node5
node.master: false
node.data: false
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.161", "10.0.0.162"]
[root@web01 ~]# vim /etc/elasticsearch/jvm.options
......
# Xmx represents the maximum size of total heap space
-Xms512m
-Xmx512m
......
[root@web01 ~]# tail -f /var/log/elasticsearch/my-oldxu.log
systemctl stop elasticsearch.service
systemctl start elasticsearch.service