打造百億級大數據日誌網關

前言

大數據一直是技術社區的熱門話題,是從事大型服務架構的攻城獅必修之課。node

嶽鷹全景監控平臺做爲大數據應用系統,每時每刻都須要處理大量的日誌流量,今天咱們將經過本文,爲你們介紹嶽鷹是如何打造大數據日誌網關(簡稱網關),以知足如下需求:redis

QPS 數十萬
日PV 數百億
流量帶寬 Gbps級別
日流量 數十TB
RTT <=40ms
數據安全性
服務可用性 99.99%

背景

一個監控系統大體包括四個階段:日誌採集上報、日誌存儲、統計與分析、數據展現,具體以下所示 編程

1.png
而做爲整個鏈路的數據入口,能夠把網關想象爲通往皇城前的守門將,全部的數據流入都須要通過其「把關」,才能到達下游被處理
2.png

業務特性

歸納來講,網關其核心設計要素主要有安全、高可用、大流量、高併發以及成本5大特性,以下圖: 數組

3.png

安全性

做爲一個對外暴露的服務,安全性一定是凌駕於一切之上的。除常見的物理層、網絡層、系統層的安全防護之外,在應用層,咱們經過如下手段保證數據安全性: 緩存

4.png

  • Https——做用很少說,請自行Google
  • Params Verify——常規的入參信息校驗
  • Time Verify——請求超時校驗
  • Sign Verify——簽名校驗,經過請求信息、應用標識、應用祕鑰生成
  • Business Verify——業務級校驗,如App是否存在有效、數據是否被限流等
  • Encrypt/Decrypt——數據加密上報,網關解密處理
  • No Store——本地無存儲,防止服務器被黑客入侵致使數據泄漏

除此之外,還有防刷判斷、請求重複判斷、限流熔斷等一些列保障措施,這個後面會有專門文章解讀,敬請期待...^v^!安全

高可用

可用性決定了整個平臺的數據可用性(若垮掉整個下游都不會再有數據),所以須要有如下策略保證其服務可用性: 服務器

5.png
整個架構很是經典,各核心職責:

  1. 日誌數據由應用端利用SDK經過互聯網上報至合適的服務節點;
  2. 由統一服務層,完成https數據解密、請求路由、負載均衡操做;
  3. 具體的業務操做由日誌網關應用負載進行業務層處理;
  4. 過程中須要用到的相關業務數據,經過Redis集羣加載,並利用廣播機制實現實時數據刷新;
  5. 當日志完成初步處理後,會發往Kafka集羣,並供下游服務使用; ##大流量&高併發 如上文說述,網關須要
  • 處理 百億級以上/日 日誌上報請求(按16小時分佈計算,QPS達十萬級別)。
  • 接收 約數十TB/日流量(按16小時分佈計算,須要帶寬Gbps級別)。
  • 毫秒級請求響應能力(不然有可能影響調用端的總體性能,或丟失數據)。

偶遇極端狀況,還會呈幾何級別上漲(想了解如何處理這種極端狀況,請期待後面推文)。可見要解決這一問題,比「安全性」、「可用性」要困難的多。在說解決方案以前,咱們不妨先大概瞭解下整個上報的處理流程: markdown

6.png

核心(長耗時)的處理邏輯集中在「請求校驗」、「業務處理」兩個環節。當中又能夠劃分爲「CPU密集型」和「I/O密集型」(小烏龜圖標位置)操做。網絡

CPU密集型

網關並不是複雜運算形應用,針對純CPU操做的優化其實很是有限。值得注意的是,現代主流的編程語言(如Java、Node等),其在邏輯運算能力上的差別通常不會很大(固然不一樣技術有其特殊的優化手段),而在實際狀況下,提高硬件性能、利用負載均衡這兩個手段效果會最爲明顯。 架構

7.png

I/O密集型

I/O操做通常都會比純CPU/內存操做要慢得多,當中又要細分爲本地I/O和網絡I/O兩種:

8.png
解決這方面問題,咱們的手段是:

  • 數據壓縮上報——提升網絡傳輸速度,減小帶寬耗損。

  • 合併上報——減小併發請求數,提高壓縮質量。

  • 分階段請求處理——http請求處理其實是分多個階段的(如Nginx就分了11個階段),能夠把大量用於校驗的信息(該類信息一般比較小),經過http頭部傳輸,並在header處理階段完成校驗操做;若檢驗失敗就能夠直接不處理報文體內容,這樣能夠減小非必要的流量處理,節省資源&提高效率。

  • 跨系統調用——利用中間件代替直接的跨系統訪問,擁有更高性能同時,下降性能不穩定風險。

  • 高性能中間件選型——用Redis替代傳統DB做爲數據源、用Kakfa做爲消息中轉替代直接的下游系統訪問。

  • 多級緩存——把不常變的數據,利用本地->集羣緩存->物理存儲方式進行緩存,減小I/O操做及運算耗時。

  • 數據緩衝 & 中轉——在大數據分析處理的場景,咱們須要對數據進行不一樣類型的加工處理(如統計、聚合、篩選、過濾等),若這些操做都在一次請求中完整處理,耗時會很是長。所以咱們使用異步緩衝機制,利用消息中間件對數據進行緩衝,並中轉至下游運算,這樣能夠大大下降RT,提高TPS&QPS。

  • 調整日誌輸出級別——上線後的應用,調整較低的日誌輸出級別(如error),能夠減小本地磁盤的寫入操做。

  • 線性落盤——針對須要寫盤的操做,能夠統一寫到全局緩衝區,而後用獨立線程/進程進行落盤操做,減小不規律I/O操做。 固然以上的方案是須要根據實際狀況權衡使用,如使用緩存會致使變化響應慢、使用線性落盤數據會有丟失風險等。 ##成本 做爲一個如此大流量、高併發的產品,咱們須要承受各種硬件、網絡、維護等的高成本投入(固然還有其它),所以在技術方案上,咱們必需要考慮這個因素:

  • 硬件成本——如何提高同等級別設備下,單實例的運做效率。

  • 網絡成本——如何在不影響(小影響)性能效果下,下降網絡資源耗損。

  • 維護成本——如何經過更多DevOps工具(部署、測試、監控),減小人工成本投入。

  • 人力成本——包括學習成本、實施成本、問題跟進成本。

  • ..... #技術選型

    9.png
    在選型的道路上,咱們糾結了好久(也踩了不少坑)。最初咱們曾用SpringBoot(Web層用原生Servlet,MVC性能不好!)實現了一個日誌上報的demo,在16核8G內存下(並作必定配置調優),跑出單機1W+QPS的成績。但幹了Java那麼久,又好像沒怎麼聽過用Java Web來作高併發大流量網關的(Go、NodeJs:咱們這方面精通!!!)。 因而咱們開展了一波又一波的研討,包括同類競品分析、各種技術調研、各類性能評測等等(有機會再分享下咱們的選型通過)。最終咱們綜合各方面因素,最終選型——OpenResty(Go、NodeJs:What?!) ##OpenResty簡介 OpenResty是一個基於 Nginx 與 Lua 的高性能 Web 平臺,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項。用於方便地搭建可以處理超高併發、擴展性極高的動態 Web 應用、Web 服務和動態網關。 總結特色:

  • 基於 Nginx 與 Lua 的高性能 Web 平臺(利用Nginx擴展機制,經過模塊方式集成Nginx運行進程)

  • 部署簡單方便

  • 專一超高併發、擴展性極高的動態 Web 應用、服務和動態網關

  • 非堵塞I/O、協程同步模型(比較適合密集小文件I/O請求場景)

  • 支持細粒度請求事件控制(結合上文說起的分階段請求處理)

  • 學習成本低,輕量級Lua腳本語言(與nodejs相像),支持JIT

  • 有成功案例,也有同類應用場景案例

  • 同時根據評測,在相同硬件環境、業務邏輯的前提下,OpenResty都會有比較明顯的性能優點。

可是,它也有一些不足的地方:

  • 冷門技術,學習成本高
  • 語法有點不習慣,特別是數組索引是從1開始!!!
  • "集成大量精良庫",支持並不完善
  • 配套的開發、測試工具不豐富
  • 運行性能與編碼實現方式很是密切,一不當心就能夠掉30~40%性能
  • ......太多了,有機會再分享

能力擴展

正如上面說到,OpenResty原生的支持不算十分強大,爲了更好的落地這個方案,咱們仍是作了必定擴展,包括:

  • lmf-mvc——純lua編寫的mvc框架,提供多層交互模型,解決原生配置複雜且實現混亂問題
  • lmf-redis——純lua編寫的Redis組件庫,支持更多redis部署模型以及更多能力特性
  • lmf-commons——其它經常使用組件,提供如多級緩存組件、併發鎖、日誌、各種方法庫等能力
  • ......

技術架構

說那麼多,仍是來個圖比較實際:

10.png
新的方案爲咱們帶來了更高的性能提高,在相同硬件狀況下,新的方案QPS提高了3倍以上。同時硬件層面的提高對性能的影響也能起到更明顯的效果。

小結

因爲篇幅關係,大數據日誌網關的介紹就到此爲止,若你們想深刻了解更多內容,歡迎各位關注咱們,深刻討論~(小編又要回去碼代碼了)。

相關文章
相關標籤/搜索