流式數據 | 天天在做大數據,你的時間都花在哪了
大數據做了這許多年,有沒有問過自己,大數據中,工作量最大和技術難度最高的,分別是什麼呢?
1.大數據時代
我每天都在思考,思考很重要,是一個消化和不斷深入的過程。
正如下面的一句話:
我們從出生開始如果沒思考過人生本身這件事情,一切按照社會的習慣前行,那人生是沒有意義的。因為你連人生都沒有想過。
那麼延生出來,我們有沒有想過大數據本身?
大數據到底是在做什麼,為什麼我做了這麼多年的大數據,總是做不完呢?
大數據本質是:
隨著科學技術發展,更多的數據能夠被存儲了,能被分析了。所以有了大數據的概念。
機器學習的本質是:
隨著數據變多了,量變導致質變,數據足夠大後其內部的隱含的規律會越來越精確和完整。機器學習則是將數據內存存在的這種隱含關聯給挖掘出來的一項技術。
大數據最耗能工作量的地方是在哪裡呢?
目前百分之八十的工作量都在於數據收集 清理和校驗。 這個工作本身並不難,但是真的很繁瑣,很費力。
我們天天感嘆:
- 數據在哪裡?如何收集
- 數據要怎麼進行清洗
- 無效數據太多,如何去除
而讓我們心灰意冷的是
當一個新的需求來臨時,現有的數據形態似乎不能滿足需求,我們又要在現有的數據堆里,重新走數據收集,清理,校驗的流程。
這似乎是一種詛咒,如同可憐的西西弗斯,被判要將大石推上陡峭的高山,每次用盡全力, 大石快要到頂時,石頭就會從其手中滑脫,又得重新推回去,幹著無止境的勞動。
大數據目前遇到的最大技術難點是什麼?
是海量數據的ad-hoc查詢
當Hadoop剛剛興起,我們可以通過它來操控越來越廉價的PC伺服器價格,於是一種暴力瀰漫了整個生態:
我們因為突然有了強大的算力,這就好比一個窮人突然有了一筆很大的錢。我們開始讓強大的算力駕著最低效的程序去跑數據,這是批處理時代的悲哀
但是隨著查詢效率要求越來越高,我們不得不被迫做出改變。還記得我們以前的日誌都是簡單的Raw文本嗎? 現在各種存儲的格式慢慢開花結果:
- Parquet, 數磚公司大力發展的一個存儲技術
- ORC, Hive 常見的一種存儲格式
- CarbonData, 華為推出的一套可支持PB級別的數據格式
總之,我們似乎沒有找到一個奇妙的技術解決查詢的問題,只能做某種折中:
為了加快查詢速度,數據存儲慢慢從早期的raw文本轉為具備向量化,帶索引,支持特定編碼和壓縮的列式存儲結構,當然這種通過調整存儲結構的方式必然以消耗數據進入時的時間和資源為代價。
也就是我們在存儲和查詢之間做了妥協。
如何讓苦力乾的更少
前面我們提及了,我們可能80%的工作都花在了數據的採集,清洗和校驗上了。但是我們該如何壓縮這部分的工作呢?
答案是:
- 流式計算
- 流式計算上層建築
讓所有的計算流動起來,就會讓下面的事情變得簡單:
我們可以在已經流動的數據中的任何一個環節引入一個新的支流。當我要獲取數據時,我做的本質其實就是 連接兩個或者多個節點,並且在其中對數據進行轉換。就如同河水,我們可以很方便的開一個支流,將水引入灌溉新的額農田。
而且我們希望流式計算的實現是結合了流式和批量語義的。為什麼呢?
看看華為在Storm上做的StreamCQL,就知道,很多情況實時流式是很有局限的,因為未來我們在流式上能做的事情會非常多:
- 數據處理
- Ad-Hoc查詢
- 機器學習
- 報表
- 存儲輸出
這就需要一定的靈活性,因為只有在數據集上,才會有譬如Ad-Hoc查詢,才能高效的進行存儲,才能適應一些機器學習演算法。單條數據很多情況下,是沒有太大意義的。
這塊我一直是Spark Streaming的支持者。數據天生就是流式的
那為啥我們需要一個流式計算上層建築? 我們回顧下問題,數據的ETL過程是個苦力活,消耗掉大量程序員的工作時間,那麼為了減少這種時間,我們有兩個辦法:
- 將做些任務分散出去,使得每個人都可做,那麼在總量不變的情況下,單個人就會變少了
- 提高每個人的工作效率
流式計算構建了整個基礎,而其上的框架則使得上面兩點成為可能。這裡我依然推薦我現在正在做的一個開源項目: StreamingPro (https://github.com/allwefantasy/streamingpro)。未來我們還會有一個更通用的基於流式計算的採集程序。
2.流式數據
完全由流式計算構建的體系
部門目前核心其實就是流式計算,從根部開始(一個超大的Kafka集群)開始,延伸出一個超級龐大的樹形結構。整個過程都是數據自我驅動進行流轉,沒有使用類似Azkaban/Oozie 等外部工具去讓數據從一個系統流轉到另外一個系統。 而我之前提出 Transformer架構 (http://www.jianshu.com/p/8a88a8bb4700)本質就是一個流式數據架構。
這個架構的核心概念是:
你開發的任何一個應用,本質上都是將兩個或者多個節點連接起來,從而使得數據可以在不同節點之間流轉
數據的流轉必然由批量到流式
如果說在大數據領域,批量處理是第一次數據革命,那麼流式處理則必然是第二次數據革命。
從某種角度而言,批量是流式處理的一個特例,譬如隔天處理數據,本質就是時間窗口為一天的流式計算。當然我們也可以實現以數量為窗口的計算。
當你需要藉助外力的時候,事情往往就變得並不美好了。你需要額外的維護譬如Oozie等系統里的工作流,並且你需要考慮各個系統能夠完成的時間,從而協調好組件。
數據流轉的理想狀態應該就如同河水一樣,當源頭水量變大後,水壓會自動迫使數據流轉速度加快。當我們需要灌溉新的農田時,我們只要接上一個蓄水池(比如Kafka,)在蓄水池延伸出新的河道(由流式引擎比如Spark Streaming完成),就可以很方便的將水引入。整個過程是水壓驅動水的流轉。
假設我們有河道A, 蓄水池C,河道B。水流方向是 A -> C ->B。 A 內部是典型的依賴於重力的將水壓力蓄水池C。 而B 則因為地勢可能更高些,需要靠消費額外的資源(CPU資源)將水抽取到B自己的河道里(pull 模式)。 當然,B也可能是地勢低,這樣C可以利用重力將水引入C (典型的push模式)。
批量與流式的微妙關係
批處理和流式本來就存在某種微妙的關係,我中有你,你中有我。Spark Streaming則充分利用了這種微妙關係,將其發揮到極致。批量處理是Spark Streaming流式處理的一個窗口特別大的特例,但是如果細加觀察,Spark Streaming 的每個batch 又都是一個批處理,只是因為這個批處理可以足夠小,看起來就像數據在真實流動一樣,所以我們也稱之為流式處理。
這裡有個值得提出的東西是,當處理時間等於調度周期,那麼spark streaming就是一個永不幹涸的河道。而如果處理時間大於調度周期,則有兩種情況需要闡述:
- 限制抽水泵的功率(也就是背壓,backpressure)
- 限制抽水泵的工作時間。因為延時,抽水泵需要一個或者多個調度周期才會開始真的工作。(Direct Approach模式)
如果抽水泵不限制功率也不推延工作時間(Receiver模式容易出現),那麼就讓河道溢出了(OOM)了。
從某種角度而言,Spark Streaming 這種將批處理和流處理巧妙融合的方式可以保證自己可以充分利用流式和批處理的優勢。
Storm這種流式引擎則能實現最細粒度的流轉,但是這種細粒度的流轉在很多場景並不足夠高效,因為在流轉的過程中,往往下游無法接受來一條就處理一條的情況,需要通過小窗口的batch來完成更加高效的入庫操作。而獲取數據,Storm從某種角度而言也是批處理。因為消費者每次從kafka 抽取數據的時候,也是一次抽取到足夠的量,然後交給後端一條一條處理。
所以Storm 和Spark Streaming的本質區別在於抽水泵的工作機制。
幾句話
- 從另外一個角度而言,流式不過是一個具有無限數據的批處理過程。
- 流式處理則是我們通向實時的一條必經之路
- 實時是我們永不言棄的目標
總結
從宏觀角度而言,批處理pipeline 一般而言借住一個協調組件,又該協調組件產生動力,調用各個系統完成某種功能。通常而言,批處理pipeline的數據處理周期都較長,符合離線的定義,譬如隔天,並且各個系統作為管道,只有在需要的時候才會被創建。
流式處理pipeline 則不需要藉助外部協調組件,每個系統通過主動拉取或者推送的方式,完成數據在不同系統中的流轉。通常而言,流式pipeline的數據處理周期都很短,符合準實時的定義,並且各個系統作為管道,都是一直存在的。
BY 祝威廉 | 首發簡書
推薦閱讀: