近期在項目中遇到一個問題,解決此問題,需要改變架構方案,以下爲方案具體內容
目錄
1.痛點
前置:通過river消費kafka中的日誌數據,不同的topic中的數據,有不同字段類型,通過不同的river進行解析。
1.1 當日志量達到一定級別之後,低版本es的消費能力明顯跟不上,造成消費堆積;
1.2 當業務方新增一個日誌類型或者對某個在日誌類型新增字段,需要修改river代碼,解析不靈活。
2.如何解決
2.1升級ES
基於1.1的問題,我們需要升級ES到高版本,如ES7.0,但是高版本的ES已經不支持river,所以需要替代river的技術,主要解決包括:負載均衡,故障轉移等,如果支持監控、告警、分片則更爲適合;
2.2 動態解析日誌
基於1.2的問題,我們需要實現動態解析日誌,能快速滿足用戶對日誌類型的動態變化需求。
3.替代river技術方案調研
通過調研,目前主要分佈式任務調度技術方案有saturn(唯品會)、Elastic-Job(噹噹)、Xxl-Job、Quartz。
對比如下:
也許大家注意到了,怎麼沒有saturn,下面隆重介紹下,saturn是Elastic-Job的升級版本,取代傳統的Linux Cron/Spring Batch Job的方式,做到統一配置,統一監控,任務高可用以及分片併發處理。主要是去中心化,高可用,可分片,動態擴容,有認證和授權功能。
主要特性:
- 支持多種語言作業,語言無關(Java/Go/C++/PHP/Python/Ruby/shell)
- 支持秒級調度
- 支持作業分片並行執行
- 支持依賴作業串行執行
- 支持作業高可用和智能負載均衡
- 支持異常檢測和自動失敗轉移
- 支持異地容災
- 支持多個集羣部署
- 支持跨機房區域部署
- 支持彈性動態擴容
- 支持優先級和權重設置
- 支持docker容器,容器化友好
- 支持cron時間表達式
- 支持多個時間段暫停執行控制
- 支持超時告警和超時強殺控制
- 支持灰度發佈
- 支持異常、超時和無法高可用作業監控告警和簡易的故障排除
- 支持失敗率最高、最活躍和負荷最重的各域各節點TOP10的作業統計
優點:源碼清晰,學習入手容易。應用部署簡單,提供運維控制檯,集中管理作業,運維控制檯功能強大,提供作業統計報表 ,告警,增刪改查作業,作業統一配置。
所以,採用saturn替代river實現分佈式任務調度。
4.saturn運行原理
4.1環境準備
硬件準備:Linux服務器
軟件準備:
JDK : 1.7+
ZooKeeper: 3.4.6+
nodejs:7.8.0+
mysql
saturn-console-{version}-exec.jar
saturn-executor-{version}-zip.zip
4.2系統架構
Saturn包括兩大部分,Saturn Console和Saturn Executor。Console是一個WEB UI,用來對作業/Executor的管理,告警,系統配置,權限管理,統計報表展現等。他同時也是整個調度系統的大腦:將作業任務分配到各Executor。Executor是執行任務的worker:按照作業配置的要求去執行部署於Executor所在容器或物理機當中的作業腳本和代碼。Saturn高度依賴於zookeeper,每個executor及調度服務都會在zookeeper上進行註冊,確保調度程序能夠及時得到executor的狀態。
Saturn定時任務調度的最小單位是分片,即任務的一個執行單元。Saturn的基本任務就是將任務分成多個分片,並將每個分片通過算法調度到對應的executor上去執行。
4.3基本原理
Saturn的基本原理是將作業在邏輯上劃分爲若干個分片,通過作業分片調度器將作業分片指派給特定的執行節點。執行節點通過quartz觸發執行作業的具體實現,在執行的時候,會將分片序號和參數作爲參數傳入。作業的實現邏輯需分析分片序號和分片參數,並以此爲依據來調用具體的實現(比如一個批量處理數據庫的作業,可以劃分0號分片處理1-10號數據庫,1號分片可以處理11-20號數據庫)。
配置作業的界面圖,着重幾塊:優先executor、暫停日期及時間段、作業依賴(上下游作業),可滿足多場景的需求,這裏不做具體闡述,配置如下:
5.動態解析方案
通過zk來進行解析配置管理,應用程序在啓動時會根據日誌類型參數,在zk上找到需要的日誌解析配置,並同時對zk上這個配置節點進行監聽,如果配置有變化,本地解析配置將立即生效。
5.1 Zk配置
可以導入配置文件來增加、修改內容。
5.2日誌解析格式設置
在一個固定的節點下,去存放解析配置的列表,每種解析配置的節點名稱爲日誌類型名稱,每種節點下面將包含全套的該種日誌類型的所有版本的解析方式。
格式如下:
{
"testapp": {
"list": {
"version": {
"splitConfig": {
"2-": {
"fields": [{
"index": 0,
"name": "version",
"type": "String"
}, {
"index": 1,
"name": "ldcId",
"type": "String"
}, {
"index": 2,
"name": "hostGroup",
"type": "String"
}, {
"index": 3,
"name": "appId",
"type": "String"
}, {
"index": 4,
"name": "ip",
"type": "String"
}, {
"index": 5,
"name": "path",
"type": "String"
}, {
"index": 6,
"name": "lid",
"type": "String"
}, {
"index": 7,
"name": "hostName",
"type": "String"
}, {
"index": 8,
"name": "hostIp",
"type": "String"
}, {
"index": 9,
"name": "logTime",
"type": "date",
"parserConfigs": {
"format": "",
"type": "timestamp"
}
}, {
"index": 10,
"name": "message",
"type": "String"
}],
"filedLength": 11
}
}
},
"splitChar": "\t"
}
}
}
5.2.1解析方式
其中解析方式設置包括無key的list解析方式,和key-value的map解析方式。
5.2.2日誌版本控制
解析時將匹配出該條日誌的版本特徵,日誌最前面是否有版本號,最後面是否有版本號,並提取出版本的特徵。比如,前後都沒有版本特徵,將用- -表示,前有V1後無V將用1-表示。
5.2.3解析字段配置
必須配置:字段位置(index),字段名稱(name),要解析成的類型(type).還有分割符類型。
其中parserConfigs一般字段爲可選,但是時間相關的類型必須要設置format和type。其中type包括三種類型:normal(一般類型),utc(utc類型)和timestamp(時間戳)。Format字段用來描述時間字段解析格式。
注意:
字段順序必須要嚴格按照順序來定義,從0開始。
6.saturn結合spring-boot測試實例
7.遇到的問題及解決
Q1:如何結局讓job只執行一次?
A1:cron表達式設置如下,
備註:如有其它問題,後續補充。
8.環境部署最低要求
爲滿足高可用,以下爲測試環境參考配置:
Saturn console集羣部署:3臺linux服務器
Zookeeper集羣部署:3臺linux服務器
Saturn executor部署:3臺linux服務器
Mysql集羣:3臺DB(一主兩從)
部署架構圖
如有不到之處,請指出,歡迎交流!