filebeat+redis+elk搭建日志分析系統
各個組件作用:
filebeat:具有日志收集功能,是下一代的Logstash收集器,但是filebeat更輕量,占用資源更少,適合客戶端使用。
redis:Redis 服務器通常都是用作 NoSQL 數據庫,不過 logstash 只是用來做消息隊列。
logstash:主要是用來日志的搜集、分析、過濾日志的工具,支持大量的數據獲取方式。一般工作方式為c/s架構,client端安裝在需要收集日志的主機上,server端負責將收到的各節點日志進行過濾、修改等操作在一並發往elasticsearch上去。
elasticsearch:Elasticsearch是個開源分布式搜索引擎,提供搜集、分析、存儲數據三大功能。它的特點有:分布式,零配置,自動發現,索引自動分片,索引副本機制,restful風格接口,多數據源,自動搜索負載等。
kibana:Kibana可以為 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以幫助匯總、分析和搜索重要數據日志。
https://www.elastic.co下載相應的安裝包
1、filebeat安裝配置:
vim /usr/local/ELK/filebeat-6.3.1-linux-x86_64/filebeat.yml
1 - type: log 2 3 # Change to true to enable this input configuration. 4 enabled: true 5 6 paths: 7 - '/data/nginx-logs/*access*' #定義日志路徑 8 #json.keys_under_root: true #默認這個值是FALSE的,也就是我們的json日志解析后會被放在json鍵上。設為TRUE,所有的keys就會被放到根節點。 9 #json.overwrite_keys: true #是否要覆蓋原有的key,這是關鍵配置,將keys_under_root設為TRUE后,再將overwrite_keys也設為TRUE,就能把filebeat默認的key值給覆蓋了。 10 #fields_under_root: true #如果該選項設置為true,則新增fields成為頂級目錄,而不是將其放在fields目錄下,自定義的field會覆蓋filebeat默認的field。 11 #exclude_lines: ['^DBG',"^$"] #排除以DBG開頭和空行 12 tags: ["json_nginxaccess"] #列表中添加標簽,用過過濾 13 document_type: json-nginxaccess #設定Elasticsearch輸出時的document的type字段 可以用來給日志進行分類。Default: log 14 tail_files: true #Filebeat從文件尾開始監控文件新增內容,非從頭開始 15 16 #fields: 17 # log_source: nginx 18 19 - type: log 20 enabled: true 21 paths: 22 - '/data/nginx-logs/*error*' 23 #json.keys_under_root: true 24 #json.overwrite_keys: true 25 tags: ["json_nginxerror"] 26 document_type: json-nginxerror 27 28 29 output.redis: 30 hosts: ["192.168.32.231"] #輸出到redis的機器 31 port: 6379 #redis端口號 32 db: 2 #redis數據庫的一個整數索引標識,redis不同於mysql有一個庫的名字。redis總共0-15默認16個庫。 33 timeout: 5 #連接超時時間 34 key: "default_list" #以default_list的keys傳輸到redis
啟動filebeat
集群機器啟動filebeat,通過key傳到redis,logstash通過tags用來過濾
##redis安裝啟動步驟略
/usr/local/ELK/filebeat-6.3.1-linux-x86_64/filebeat &
2、elasticsearch集群的安裝啟動
修改配置文件 vim /usr/local/ELK/elasticsearch-6.3.0/config/elasticsearch.yml
1 cluster.name: cc-cluster #集群名稱(自定義) 2 node.name: cc-1 #節點名稱(自定義) 3 node.master: true #是否有資格成為master主節點,如只做存儲則為false 4 node.data: true #是否做存儲節點,當這兩個都為false時,該節點作為client 5 path.data: /usr/local/ELK/elasticsearch-6.3.0/data #數據存儲目錄 6 path.logs: /usr/local/ELK/elasticsearch-6.3.0/logs #日志存儲目錄 7 network.host: 192.168.32.231 #監聽本地ip 8 http.port: 9200 #http監聽端口 9 #transport.tcp.port: 9300 #tcp通訊端口 10 #transport.tcp.compres: true 11 gateway.recover_after_nodes: 2 #一個集群中的N個節點啟動后,才允許進行恢復處理 12 #gateway.recover_after_time: 5 #設置初始化恢復過程的超時時間,超時時間從上一個配置中配置的N個節點啟動后算起 13 gateway.expected_nodes: 1 # 設置這個集群中期望有多少個節點.一旦這N個節點啟動(並且recover_after_nodes也符合),立即開始恢復過程(不等待recover_after_time超時) 14 bootstrap.memory_lock: true #鎖定內存,阻止操作系統管理內存,可以有效的防止內存數據被交換到磁盤空間,交換過程中磁盤會抖動,會對性能產生較大的影響。因為ES是基於JAVA開發的可以能過垃圾回收器來單獨管理內存,所以關閉操作系統級別的內存管理可以提升性能 15 bootstrap.system_call_filter: false #關閉操作系統內核驗證 16 17 discovery.zen.ping.unicast.hosts: ["192.168.32.231","192.168.32.230","192.168.32.232"] #集群初始化連接列表,節點啟動后,首先通過連接初始化列表里的地址去發現集群。 18 discovery.zen.minimum_master_nodes: 2 #為了防止集群腦裂,目前的策略是當且僅當節點有超過半數的master候選者存活時(當前兩台master),集群才會進行master選舉
master節點
主要功能是維護元數據,管理集群各個節點的狀態,數據的導入和查詢都不會走master節點,所以master節點的壓力相對較小,因此master節點的內存分配也可以相對少些;但是master節點是最重要的,如果master節點掛了或者發生腦裂了,你的元數據就會發生混亂,那樣你集群里的全部數據可能會發生丟失,所以一定要保證master節點的穩定性。
data node
是負責數據的查詢和導入的,它的壓力會比較大,它需要分配多點的內存,選擇服務器的時候最好選擇配置較高的機器(大內存,雙路CPU,SSD... 土豪~);data node要是壞了,可能會丟失一小份數據。
client node
是作為任務分發用的,它里面也會存元數據,但是它不會對元數據做任何修改。client node存在的好處是可以分擔下data node的一部分壓力;為什么client node能分擔data node的一部分壓力?因為es的查詢是兩層匯聚的結果,第一層是在data node上做查詢結果匯聚,然后把結果發給client node,client node接收到data node發來的結果后再做第二次的匯聚,然后把最終的查詢結果返回給用戶;所以我們看到,client node幫忙把第二層的匯聚工作處理了,自然分擔了data node的壓力。
這里,我們可以舉個例子,當你有個大數據查詢的任務(比如上億條查詢任務量)丟給了es集群,要是沒有client node,那么壓力直接全丟給了data node,如果data node機器配置不足以接受這么大的查詢,那么就很有可能掛掉,一旦掛掉,data node就要重新recover,重新reblance,這是一個異常恢復的過程,這個過程的結果就是導致es集群服務停止... 但是如果你有client node,任務會先丟給client node,client node要是處理不來,頂多就是client node停止了,不會影響到data node,es集群也不會走異常恢復。
對於es 集群為何要設計這三種角色的節點,也是從分層邏輯去考慮的,只有把相關功能和角色划分清楚了,每種node各盡其責,才能發揮出分布式集群的效果。
根據業務需求配置master、client、node。啟動elasticsearch
/usr/local/ELK/elasticsearch-6.3.0/bin/elasticsearch -d
查看集群狀態
curl http://192.168.32.231:9200/_cat/nodes?v
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.32.231 20 88 2 0.61 0.43 0.37 mdi * cc-1 # *為主節點
192.168.32.230 29 62 0 0.00 0.00 0.00 mdi - cc-2
192.168.32.232 35 52 1 0.04 0.06 0.05 mdi - cc-3
可能遇到的問題:
問題1:max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]
max number of threads [1024] for user [lishang] likely too low, increase to at least [2048]
解決:shell>sudo
vi /etc/security/limits.conf
* hard nofile 65536
* soft nofile 65536
elk soft memlock unlimited
elk hard memlock unlimited
問題2:max number of threads [1024] for user [lish] likely too low, increase to at least [2048]
解決:shell>sudo vi /etc/security/limits.d/90-nproc.conf
* soft nproc 20480
* hard nproc 20480
問題3:max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
解決:shell>sudo vi /etc/sysctl.conf
vm.max_map_count = 262144shell>sudo sysctl -p
3、logstash配置啟動
vim /usr/local/ELK/logstash-6.3.0/conf/filebeat_redis.conf
nginx日志為json格式
log_format json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"service":"nginxTest",'
'"trace":"$upstream_http_ctx_transaction_id",'
'"log":"log",'
'"clientip":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"http_user_agent":"$http_user_agent",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"status":"$status"}';
1 input { 2 redis { 3 data_type => "list" #支持三種 data_type(實際上是redis_type),不同的數據類型會導致實際采用不同的 Redis 命令操作:1、list => BLPOP 2、channel => SUBSCRIBE 3、pattern_channel => PSUBSCRIBE 4 key => "default_list" #filebeat定義的key 5 host => "192.168.32.231" 6 port => 6379 7 db => 2 8 threads => 1 9 #codec => json 10 #type => "json-nginxaccess" 11 } 12 } 13 14 15 filter { 16 json { 17 source => "message" 18 remove_field => ["beat"] 19 #remove_field => ["beat","message"] 20 } 21 22 geoip { 23 source => "clientip" 24 } 25 26 geoip { 27 source => "clientip" 28 target => "geoip" 29 #database => "/root/GeoLite2-City_20170704/GeoLite2-City.mmdb" 30 add_field => [ "[geoip][coordinates]", "%{[geoip][longitude]}" ] 31 add_field => [ "[geoip][coordinates]", "%{[geoip][latitude]}" ] 32 } 33 34 grok { 35 match => ["message","%{TIMESTAMP_ISO8601:isotime}"] 36 } 37 date { 38 locale => "en" 39 match => ["isotime","ISO8601"] 40 #match => ["isotime","dd/MMM/yyyy:HH:mm:ss Z"] 41 target => "@timestamp" 42 } 43 44 mutate { 45 convert => [ "[geoip][coordinates]", "float"] 46 remove_field => ["message"] 47 #remove_field => ["@timestamp"] 48 } 49 } 50 51 output { 52 if "json_nginxaccess" in [tags] { 53 elasticsearch { 54 #hosts => ["127.0.0.1:9200"] 55 hosts => ["192.168.32.230:9200","192.168.32.231:9200","192.168.32.232:9200"] 56 #index => "logstash-%{type}-%{+YYYY.MM.dd}" 57 index => "logstash-json-nginxaccess-%{+YYYY.MM.dd}" 58 document_type => "%{[@metadata][type]}" 59 #flush_size => 2000 60 #idle_flush_time => 10 61 sniffing => true 62 template_overwrite => true 63 } 64 } 65 66 if "json_nginxerror" in [tags] { 67 elasticsearch { 68 #hosts => ["127.0.0.1:9200"] 69 hosts => ["192.168.32.230:9200","192.168.32.231:9200","192.168.32.232:9200"] 70 #index => "logstash-%{type}-%{+YYYY.MM.dd}" 71 index => "logstash-json-nginxerror-%{+YYYY.MM.dd}" 72 document_type => "%{type}" 73 #flush_size => 2000 74 #idle_flush_time => 10 75 sniffing => true 76 template_overwrite => true 77 } 78 } 79 stdout { 80 codec => "rubydebug" 81 } 82 }
/usr/local/ELK/logstash-6.3.0/bin/logstash -f /usr/local/ELK/logstash-6.3.0/conf/filebeat_redis.conf -t 測試配置文件啟動是否正常
nohup /usr/local/ELK/logstash-6.3.0/bin/logstash -f /usr/local/ELK/logstash-6.3.0/conf/filebeat_redis.conf 2>&1 & 啟動logstash
啟動之后,查看elasticsearch索引是否生成
curl http://192.168.32.231:9200/_cat/indices?v
4、配置kibana
server.port: 5601
server.host: "192.168.32.231"
elasticsearch.url: "http://192.168.32.231:9200"
通過瀏覽器訪問 192.168.32.231:5601
添加索引
查看索引
5、nginx反向代理配置
因為免費的 ELK 沒有任何安全機制,所以這里使用了 Nginx 作反向代理,避免用戶直接訪問 Kibana 服務器。加上配置 Nginx 實現簡單的用戶認證,一定程度上提高安全性。另外,Nginx 本身具有負載均衡的作用,能夠提高系統訪問性能。
1 upstream kibana_server { 2 server 127.0.0.1:5601 weight=1 max_fails=3 fail_timeout=60; 3 } 4 5 server { 6 listen 80; 7 server_name www.cc.com; 8 auth_basic "Restricted Access"; # 驗證 9 auth_basic_user_file /etc/nginx/htpasswd.users; # 驗證文件 10 location / { 11 proxy_pass http://kibana_server; 12 proxy_http_version 1.1; 13 proxy_set_header Upgrade $http_upgrade; 14 proxy_set_header Connection 'upgrade'; 15 proxy_set_header Host $host; 16 proxy_cache_bypass $http_upgrade; 17 } 18 }