什麼要作日誌分析平臺?html

 

隨着業務量的增加,天天業務服務器將會產生上億條的日誌,單個日誌文件達幾個GB,這時咱們發現用Linux自帶工具,cat grep awk 分析愈來愈力不從心了,並且除了服務器日誌,還有程序報錯日誌,分佈在不一樣的服務器,查閱繁瑣。java

 

待解決的痛點:node

一、大量不一樣種類的日誌成爲了運維人員的負擔,不方便管理;linux

 

二、單個日誌文件巨大,沒法使用經常使用的文本工具分析,檢索困難;nginx

 

三、日誌分佈在多臺不一樣的服務器上,業務一旦出現故障,須要一臺臺查看日誌。laravel

 

爲了解決以上困擾:git

 

接下來咱們要一步步構建這個日誌分析平臺,架構圖以下:github

wKioL1f93pWDzh14AAFeY_uvtXc440.png

架構解讀 : (整個架構從左到右,總共分爲5層)apache

 

第一層、數據採集層

最左邊的是業務服務器集羣,上面安裝了filebeat作日誌採集,同時把採集的日誌分別發送給兩個logstash服務。

 

第二層、數據處理層,數據緩存層

logstash服務把接受到的日誌通過格式處理,轉存到本地的kafka broker+zookeeper 集羣中。

 

第三層、數據轉發層

這個單獨的Logstash節點會實時去kafka broker集羣拉數據,轉發至ES DataNode。

 

第四層、數據持久化存儲

ES DataNode 會把收到的數據,寫磁盤,建索引庫。

 

第五層、數據檢索,數據展現

ES Master + Kibana 主要協調ES集羣,處理數據檢索請求,數據展現。

 

筆者爲了節約寶貴的服務器資源,把一些可拆分的服務合併在同一臺主機。你們能夠根據本身的實際業務環境自由拆分,延伸架構。

 

開 工 !

 

操做系統環境 : CentOS release 6.5 

 

各服務器角色分配 :

IP 角色 所屬集羣
10.10.1.2 業務服務器+filebeat 業務服務器集羣
10.10.1.30 Logstash+Kafka+ZooKeeper

 

Kafka Broker 集羣

10.10.1.31 Logstash+Kafka+ZooKeeper
10.10.1.32 Kafka+ZooKeeper
10.10.1.50 Logstash 數據轉發
10.10.1.60 ES DataNode

 

 

Elasticsearch 集羣

10.10.1.90 ES DataNode
10.10.1.244 ES Master+Kibana


軟件包版本:

 

jdk-8u101-linux-x64.rpm

logstash-2.3.2.tar.gz

filebeat-1.2.3-x86_64.rpm

kafka_2.11-0.10.0.1.tgz

zookeeper-3.4.9.tar.gz

elasticsearch-2.3.4.rpm 

kibana-4.5.3-linux-x64.tar.gz

 

1、安裝部署Elasticsearch集羣

 

佈置ES Master節點 10.10.1.244

 

一、安裝jdk1.8,elasticsearch-2.3.4

 

oracle官網 jdk 下載地址: http://www.oracle.com/technetwork/java/javase/downloads/index.html

elasticsearch 官網: https://www.elastic.co/

# 安裝命令 yum install jdk-8u101-linux-x64.rpm elasticsearch-2.3.4.rpm -y # ES 會被默認安裝在 /usr/share/elasticsearch/
 

 

二、系統調優,JVM調優

# 配置系統最大打開文件描述符數 vim /etc/sysctl.conf fs.file-max=65535 # 配置進程最大打開文件描述符 vim /etc/security/limits.conf # End of file * soft nofile 65535 * hard nofile 65535 # 配置 JVM內存 vim /etc/sysconfig/elasticsearch ES_HEAP_SIZE=4g # 這臺機器的可用內存爲8G
 

 

三、編寫ES Master節點配置文件

# /etc/elasticsearch/elasticsearch.yml # ---------------------------------- Cluster ----------------------------------- # Use a descriptive name for your cluster: cluster.name: bigdata # ------------------------------------ Node ------------------------------------ node.name: server1 node.master: true node.data: false # ----------------------------------- Index ------------------------------------ index.number_of_shards: 5 index.number_of_replicas: 0 index.refresh_interval: 120s # ----------------------------------- Paths ------------------------------------ path.data: /home/elk/data path.logs: /var/log/elasticsearch/elasticsearch.log # ----------------------------------- Memory ----------------------------------- bootstrap.mlockall: true indices.fielddata.cache.size: 50mb #------------------------------------ Network And HTTP -------------------------- network.host: 0.0.0.0 http.port: 9200 # ------------------------------------ Translog ---------------------------------- index.translog.flush_threshold_ops: 50000 # --------------------------------- Discovery ------------------------------------ discovery.zen.minimum_master_nodes: 1 discovery.zen.ping.timeout: 200s discovery.zen.fd.ping_timeout: 200s discovery.zen.fd.ping.interval: 30s discovery.zen.fd.ping.retries: 6 discovery.zen.ping.unicast.hosts: ["10.10.1.60:9300","10.10.1.90:9300","10.10.1.244:9300",] discovery.zen.ping.multicast.enabled: false # --------------------------------- merge ------------------------------------------ indices.store.throttle.max_bytes_per_sec: 100mb
 

 

注: path.data、path.logs 這兩個參數指定的路徑,若是沒有須要本身建立,還要賦予權限給elasticsearch用戶。(後面的ES DataNode也一樣)

 

四、安裝head、kopf、bigdesk 開源插件

安裝方法有兩種 :

一、使用ES自帶的命令plugin

# head /usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head # kopf /usr/share/elasticsearch/bin/plugin install lmenezes/elasticsearch-kopf # bigdesk /usr/share/elasticsearch/bin/plugin install hlstudio/bigdesk
 

二、自行下載插件的源碼包安裝

 

咱們經過plugin命令安裝的插件,實際上是安裝到了這個路徑:/usr/share/elasticsearch/plugins

 

而plugin install 命令後面跟的這一串 mobz/elasticsearch-head 實際上是github上的一個地址。

前面加上github的官網地址就是 https://github.com/mobz/elasticsearch-head 能夠複製到瀏覽器中打開,找到該插件的源碼倉庫。

 

如今知道了,想要找插件本身能夠去github上搜一下出來一大堆。隨便選一個而後取後面那串路徑,用ES自帶的命令安裝。

 

若是安裝失敗了,那麼就手動下載該插件的源碼包。 解壓後直接整個目錄mv到 ES 的插件安裝路徑下。 

也就是這裏: /usr/share/elasticsearch/plugins/

 

那如何訪問安裝好的插件呢?

http://ES_server_ip:port/_plugin/plugin_name

Example:

http://127.0.0.1:9200/_plugin/head/

 

http://127.0.0.1:9200/_plugin/kopf/

 

這時,ES Master已經配置好了。

 

佈置ES DataNode節點 10.10.1.60

 

安裝和系統調優方法同上,插件不用安裝,只是配置文件不一樣。

 

編寫配置文件

# ---------------------------------- Cluster ----------------------------------- # Use a descriptive name for your cluster: cluster.name: bigdata # ------------------------------------ Node ------------------------------------ node.name: server2 node.master: false node.data: true # ----------------------------------- Index ------------------------------------ index.number_of_shards: 5 index.number_of_replicas: 0 index.refresh_interval: 120s # ----------------------------------- Paths ------------------------------------ path.data: /home/elk/data,/disk2/elk/data2 path.logs: /var/log/elasticsearch/elasticsearch.log # ----------------------------------- Memory ----------------------------------- bootstrap.mlockall: true indices.fielddata.cache.size: 50mb #------------------------------------ Network And HTTP -------------------------- network.host: 0.0.0.0 http.port: 9200 # ------------------------------------ Translog ---------------------------------- index.translog.flush_threshold_ops: 50000 # --------------------------------- Discovery ------------------------------------ discovery.zen.minimum_master_nodes: 1 discovery.zen.ping.timeout: 200s discovery.zen.fd.ping_timeout: 200s discovery.zen.fd.ping.interval: 30s discovery.zen.fd.ping.retries: 6 discovery.zen.ping.unicast.hosts: ["10.10.1.244:9300",] discovery.zen.ping.multicast.enabled: false # --------------------------------- merge ------------------------------------------ indices.store.throttle.max_bytes_per_sec: 100mb
 

 

10.10.1.60 也準備好了。

 

佈置另外一臺ES DataNode節點 10.10.1.90

 

編寫配置文件

# ---------------------------------- Cluster ----------------------------------- # Use a descriptive name for your cluster: cluster.name: bigdata # ------------------------------------ Node ------------------------------------ node.name: server3 node.master: false node.data: true # ----------------------------------- Index ------------------------------------ index.number_of_shards: 5 index.number_of_replicas: 0 index.refresh_interval: 120s # ----------------------------------- Paths ------------------------------------ path.data: /home/elk/single path.logs: /var/log/elasticsearch/elasticsearch.log # ----------------------------------- Memory ----------------------------------- bootstrap.mlockall: true indices.fielddata.cache.size: 50mb #------------------------------------ Network And HTTP -------------------------- network.host: 0.0.0.0 http.port: 9200 # ------------------------------------ Translog ---------------------------------- index.translog.flush_threshold_ops: 50000 # --------------------------------- Discovery ------------------------------------ discovery.zen.minimum_master_nodes: 1 discovery.zen.ping.timeout: 200s discovery.zen.fd.ping_timeout: 200s discovery.zen.fd.ping.interval: 30s discovery.zen.fd.ping.retries: 6 discovery.zen.ping.unicast.hosts: ["10.10.1.244:9300",] discovery.zen.ping.multicast.enabled: false # --------------------------------- merge ------------------------------------------ indices.store.throttle.max_bytes_per_sec: 100mb
 

 

五、如今三臺ES節點已經準備就緒,分別啓動服務

# 10.10.1.244 /etc/init.d/elasticsearch start # 10.10.1.60 /etc/init.d/elasticsearch start # 10.10.1.90 /etc/init.d/elasticsearch start
 

 

六、訪問head插件,查看集羣狀態

wKiom1f-AxDRvIMHAABrDZjJzqo236.png

此時 Elasticsearch 集羣已經準備完成

 

 

2、配置位於架構圖中第二層的ZooKeeper集羣

 

配置 10.10.1.30 節點

 

一、安裝,配置 zookeeper

zookeeper官網: http://zookeeper.apache.org/

 

# zookeeper 依賴 java,若是以前沒安裝過JDK,則須要安裝. rpm -ivh jdk-8u101-linux-x64.rpm # 解壓程序 tar xf zookeeper-3.4.9.tar.gz
 

 

編寫配置文件

# conf/zoo.cfg # The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/u01/zookeeper/zookeeper-3.4.9/data # the port at which the clients will connect clientPort=2181 # the maximum number of client connections. # increase this if you need to handle more clients #maxClientCnxns=60 server.11=10.10.1.30:2888:3888 server.12=10.10.1.31:2888:3888 server.13=10.10.1.32:2888:3888 # Be sure to read the maintenance section of the # administrator guide before turning on autopurge. # # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance # # The number of snapshots to retain in dataDir # autopurge.snapRetainCount=3 # Purge task interval in hours # Set to "0" to disable auto purge feature # autopurge.purgeInterval=1
 

 

同步配置文件到其餘兩臺節點

注: zookeeper 集羣,每一個節點的配置文件都是同樣的。因此直接同步過去,不須要作任何修改。

不熟悉zookeeper的朋友,能夠參考這裏: http://tchuairen.blog.51cto.com/3848118/1859494

scp zoo.cfg 10.10.1.31:/usr/local/zookeeper-3.4.9/conf/ scp zoo.cfg 10.10.1.32:/usr/local/zookeeper-3.4.9/conf/
 

 

二、建立myid文件

# 10.10.1.30 echo 11 >/usr/local/zookeeper-3.4.9/data/myid # 10.10.1.31 echo 12 >/usr/local/zookeeper-3.4.9/data/myid # 10.10.1.32 echo 13 >/usr/local/zookeeper-3.4.9/data/myid
 

 

三、啓動服務 & 查看節點狀態

# 10.10.1.30 bin/zkServer.sh start bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /usr/local/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: leader # 10.10.1.31 bin/zkServer.sh start bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /usr/local/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: follower # 10.10.1.32 bin/zkServer.sh start bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /usr/local/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: follower
 

 

此時zookeeper集羣配置完成

 

3、配置位於架構圖中第二層的Kafka Broker集羣

 

Kafka官網: http://kafka.apache.org/

不熟悉Kafka的朋友能夠參考: http://tchuairen.blog.51cto.com/3848118/1855090

 

配置 10.10.1.30 節點

一、安裝,配置 kafka

# 解壓程序 tar xf kafka_2.11-0.10.0.1.tgz
 

 

編寫配置文件

############################# Server Basics ############################# broker.id=1 ############################# Socket Server Settings ############################# num.network.threads=3 # The number of threads doing disk I/O num.io.threads=8 # The send buffer (SO_SNDBUF) used by the socket server socket.send.buffer.bytes=102400 # The receive buffer (SO_RCVBUF) used by the socket server socket.receive.buffer.bytes=102400 # The maximum size of a request that the socket server will accept (protection against OOM) socket.request.max.bytes=104857600 ############################# Log Basics ############################# log.dirs=/usr/local/kafka/kafka_2.11-0.10.0.1/data num.partitions=6 num.recovery.threads.per.data.dir=1 ############################# Log Flush Policy ############################# # The number of messages to accept before forcing a flush of data to disk #log.flush.interval.messages=10000 # The maximum amount of time a message can sit in a log before we force a flush #log.flush.interval.ms=1000 ############################# Log Retention Policy ############################# log.retention.hours=60 log.segment.bytes=1073741824 log.retention.check.interval.ms=300000 ############################# Zookeeper ############################# zookeeper.connect=10.10.1.30:2181,10.10.1.31:2181,10.10.1.32:2181 zookeeper.connection.timeout.ms=6000
 

 

注: 其餘兩個節點的配置文件也基本相同,只有一個參數須要修改 broker.id 。 它用於惟一標識節點,因此絕對不能相同,否則會節點衝突。

 

同步配置文件到其餘兩臺節點

scp server.properties 10.10.1.31:/usr/local/kafka/kafka_2.11-0.10.0.1/config/ scp server.properties 10.10.1.32:/usr/local/kafka/kafka_2.11-0.10.0.1/config/ # 修改 broker.id # 10.10.1.31 broker.id=2 # 10.10.1.32 broker.id=3
 

 

二、配置主機名對應IP的解析

vim /etc/hosts

10.10.1.30 server1
10.10.1.31 server2
10.10.1.32 server3

# 記得同步到其餘兩臺節點
 

 

三、啓動服務 

bin/kafka-server-start.sh config/server.properties
# 其餘兩臺節點啓動方式相同
 

 

Kafka+ZooKeeper集羣配置完成

 

4、配置位於架構圖中第二層的Logstash服務

 

配置 10.10.1.30 節點

 

一、安裝,配置 logstash

# 解壓程序 tar xf logstash-2.3.2.tar.gz
 

 

配置 GeoLiteCity , 用於地圖顯示IP訪問的城市

官網地址: http://dev.maxmind.com/geoip/legacy/geolite/

下載地址: http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

 

解壓

gunzip GeoLiteCity.dat.gz

 

編寫配置文件

input { beats { port => 5044 codec => "json" } } filter { if [type] == "nginxacclog" { geoip { source => "clientip" # 與日誌中訪問地址的key要對應 target => "geoip" database => "/usr/local/logstash/GeoLiteCity.dat" add_field => [ "[geoip][coordinates]","%{[geoip][longitude]}" ] add_field => [ "[geoip][coordinates]","%{[geoip][latitude]}" ] } mutate { convert => [ "[geoip][coordinates]","float" ] } } } output { kafka { workers => 2 bootstrap_servers => "10.10.1.30:9092,10.10.1.31:9092,10.10.1.32:9092" topic_id => "peiyinlog" } }
 

 

二、啓動服務

/usr/local/logstash/bin/logstash agent -f logstash_in_kafka.conf &
 

 

10.10.1.31 節點的這塊配置,與上述徹底相同。(略)

位於第二層、數據處理層的 Logstash 配置完成

 

 

5、配置數據採集層,業務服務器+Filebeat

 

一、定製Nginx日誌格式

log_format json '{"@timestamp":"$time_iso8601",' '"slbip":"$remote_addr",' '"clientip":"$http_x_forwarded_for",' '"serverip":"$server_addr",' '"size":$body_bytes_sent,' '"responsetime":$request_time,' '"domain":"$host",' '"method":"$request_method",' '"requesturi":"$request_uri",' '"url":"$uri",' '"appversion":"$HTTP_APP_VERSION",' '"referer":"$http_referer",' '"agent":"$http_user_agent",' '"status":"$status",' '"devicecode":"$HTTP_HA"}'; # 在虛擬主機配置中調用 access_log /alidata/log/nginx/access/access.log json;
 

 

二、安裝 Filebeat

Filebeat 也是 Elasticsearch 公司的產品,在官網能夠下載。

# rpm 包安裝 yum install filebeat-1.2.3-x86_64.rpm -y
 

 

三、編寫 Filebeat 配置文件

################### Filebeat Configuration Example ######################### ############################# Filebeat ###################################### filebeat: prospectors: - paths: - /var/log/messages input_type: log document_type: messages - paths: - /alidata/log/nginx/access/access.log input_type: log document_type: nginxacclog - paths: - /alidata/www/logs/laravel.log input_type: log document_type: larlog - paths: - /alidata/www/logs/500_error.log input_type: log document_type: peiyinlar_500error - paths: - /alidata/www/logs/deposit.log input_type: log document_type: lar_deposit - paths: - /alidata/www/logs/call_error.log input_type: log document_type: call_error - paths: - /alidata/log/php/php-fpm.log.slow input_type: log document_type: phpslowlog multiline: pattern: '^[[:space:]]' negate: true match: after registry_file: /var/lib/filebeat/registry ############################# Output ########################################## output: logstash: hosts: ["10.26.95.215:5044"] ############################# Shipper ######################################### shipper: name: "host_6" ############################# Logging ######################################### logging: files: rotateeverybytes: 10485760 # = 10MB
 

 

四、啓動服務

/etc/init.d/filebeat start
 

 

數據採集層,Filebeat配置完成。

 

如今業務服務器上的日誌數據已經在源源不斷的寫入緩存了。

 

 

6、配置位於架構圖中的第三層,數據轉發層

 

Logstash安裝上面已經講過(略)

 

編寫Logstash配置文件

# kafka_to_es.conf input{ kafka { zk_connect => "10.10.1.30:2181,10.10.1.31:2181,10.10.1.32:2181" group_id => "logstash" topic_id => "peiyinlog" reset_beginning => false consumer_threads => 50 decorate_events => true } } # 刪除一些不須要的字段 filter { if [type] == "nginxacclog" { mutate { remove_field => ["slbip","kafka","domain","serverip","url","@version","offset","input_type","count","source","fields","beat.hostname","host","tags"] } } } output { if [type] == "nginxacclog" { # stdout {codec => rubydebug } elasticsearch { hosts => ["10.10.1.90:9200","10.10.1.60:9200"] index => "logstash-nginxacclog-%{+YYYY.MM.dd}" manage_template => true flush_size => 50000 idle_flush_time => 10 workers => 2 } } if [type] == "messages" { elasticsearch { hosts => ["10.10.1.90:9200","10.10.1.60:9200"] index => "logstash-messages-%{+YYYY.MM.dd}" manage_template => true flush_size => 50000 idle_flush_time => 30 workers => 1 } } if [type] == "larlog" { elasticsearch { hosts => ["10.10.1.90:9200","10.10.1.60:9200"] index => "logstash-larlog-%{+YYYY.MM.dd}" manage_template => true flush_size => 2000 idle_flush_time => 10 } } if [type] == "deposit" { elasticsearch { hosts => ["10.10.1.90:9200","10.10.1.60:9200"] index => "logstash-deposit-%{+YYYY.MM.dd}" manage_template => true flush_size => 2000 idle_flush_time => 10 } } if [type] == "phpslowlog" { elasticsearch { hosts => ["10.10.1.90:9200","10.10.1.60:9200"] index => "logstash-phpslowlog-%{+YYYY.MM.dd}" manage_template => true flush_size => 2000 idle_flush_time => 10 } } }
 

 

啓動服務

/usr/local/logstash/bin/logstash agent -f kafka_to_es.conf &
 

 

數據轉發層已經配置完成

 

這時數據已經陸陸續續的從kafka取出,轉存到ES DataNode。

 

咱們登錄到任意一臺kafka主機,查看數據的緩存和消費狀況

wKioL1f-8G3gYSE2AABXLzMqcf0058.png

 

 

7、修改ES的索引模版配置

 

爲何要作這一步呢? 由於logstash寫入數據到ES時,會自動選用一個索引模版。 咱們能夠看一下

wKioL1f-85ngb4HBAABR4b08KRI422.png

 

這個模版其實也挺好,不過有一個參數,我標記出來了。 "refresh_interval":"5s"  這個參數用於控制,索引的刷新頻率。 索引的刷新頻率越快,你搜索到的數據就實時。  這裏是5秒。 通常咱們日誌場景不須要這麼高的實時性。 能夠適當下降該參數,提升ES 索引庫的寫入速度。  

 

上傳自定義模版

curl -XPUT http://10.10.1.244:9200/_template/logstash2 -d ' { "order":1, "template":"logstash-*", "settings":{ "index":{ "refresh_interval":"120s" } }, "mappings":{ "_default_":{ "_all":{ "enabled":false } } } }'
 

 

因爲這個自定義模版,我把優先級 order 定義的比logstash模版高,而模版的匹配規則又同樣,因此這個自定義模版的配置會覆蓋原logstash模版。

我這裏只是簡單描述。 若是要詳細理解其中道理,請查看個人 ES 調優篇。

 

8、配置 Kibana 數據展現層

 

10.10.1.244 節點

Kibana是ELK套件中的一員,也屬於elasticsearch 公司,在官網提供下載。

 

安裝

tar xf kibana-4.5.3-linux-x64.tar.gz # 很簡單,只要解壓就能夠用。
 

 

修改配置文件

# vim kibana-4.5.3-linux-x64/config/kibana.yml # Kibana is served by a back end server. This controls which port to use. server.port: 5601 # The host to bind the server to. server.host: "0.0.0.0" # The Elasticsearch instance to use for all your queries. elasticsearch.url: " # 修改這三個參數就行了
 

 

啓動服務

wKiom1f--1jjDIH4AACCZWwZlR0270.png

打開瀏覽器訪問: http://10.10.1.244:5601/

 

定製 Elasticsearch 索引的 Index pattern 

 

默認狀況下,Kibana認爲你要訪問的是經過Logstash導入Elasticsearch的數據,這時候你能夠用默認的 logstash-* 做爲你的 index pattern。 通配符(*)匹配索引名中任意字符任意個數。

 

選擇一個包含了時間戳的索引字段(字段類型爲 date 的字段),能夠用來作基於時間的處理。Kibana 會讀取索引的

映射,而後列出全部包含了時間戳的字段。若是你的索引沒有基於時間的數據.

關閉 Index contains time-based events 參數。

 

若是一個新索引是按期生成,並且索引名中帶有時間戳,選擇 Use event times to create index names 選項,

而後再選擇 Index pattern interval 。這能夠提升搜索性能,Kibana 會至搜索你指定的時間範圍內的索引。在你用 Logstash 輸出數據給Elasticsearch 的狀況下尤爲有效。

 

因爲咱們的索引是用日期命名,按照天天分割的。 index pattern 以下

wKiom1f-_yTCvOe2AADRDyL4MEg193.png


數據展現

wKiom1f-_5uhQx3XAADGEwSe3Us023.png

完 工 !