各個組件做用:node
filebeat:具備日誌收集功能,是下一代的Logstash收集器,可是filebeat更輕量,佔用資源更少,適合客戶端使用。mysql
redis:Redis 服務器一般都是用做 NoSQL 數據庫,不過 logstash 只是用來作消息隊列。linux
logstash:主要是用來日誌的蒐集、分析、過濾日誌的工具,支持大量的數據獲取方式。通常工做方式爲c/s架構,client端安裝在須要收集日誌的主機上,server端負責將收到的各節點日誌進行過濾、修改等操做在一併發往elasticsearch上去。nginx
elasticsearch:Elasticsearch是個開源分佈式搜索引擎,提供蒐集、分析、存儲數據三大功能。它的特色有:分佈式,零配置,自動發現,索引自動分片,索引副本機制,restful風格接口,多數據源,自動搜索負載等。git
kibana:Kibana能夠爲 Logstash 和 ElasticSearch 提供的日誌分析友好的 Web 界面,能夠幫助彙總、分析和搜索重要數據日誌。redis
https://www.elastic.co下載相應的安裝包sql
一、filebeat安裝配置:shell
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
啓動filebeatjson
集羣機器啓動filebeat,經過key傳到redis,logstash經過tags用來過濾
##redis安裝啓動步驟略
/usr/local/ELK/filebeat-6.3.1-linux-x86_64/filebeat &
二、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
三、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 命令操做:一、list => BLPOP 二、channel => SUBSCRIBE 三、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
四、配置kibana
server.port: 5601
server.host: "192.168.32.231"
elasticsearch.url: "http://192.168.32.231:9200"
經過瀏覽器訪問 192.168.32.231:5601
添加索引
查看索引
五、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 }