網易大數據平臺架構實踐分享

【IT168 專稿】本文根據餘利華老師在2018年5月10日【第九屆中國數據庫技術大會】現場演講內容整理而成。

講師簡介:

網易大數據平臺架構實踐分享

餘利華,網易大數據總經理,負責網易數據科學基礎設施建設, 包括大數據管理和應用開發平臺猛獁、企業級智能可視化分析平臺有數等大數據產品,以及各類數據庫產品。

摘要:

隨著網易雲音樂、新聞、考拉、嚴選等互聯網業務的快速發展,網易開始加速大數據平臺建設,以提高數據獲取速度,提升數據分析效率,更快發揮數據價值。 本次演講主要分享網易如何圍繞和改造開源技術,以產品化思維打造網易自己的大數據平臺, 也會分享一下網易在大數據平臺構建和支撐互聯網業務過程中面臨的技術挑戰,以及我們在調度、安全、元數據管理、spark多租戶、SQL流計算、高性能查詢引擎等關鍵技術環節的實踐經驗。 最後會介紹一下,網易大數據平臺未來的技術路線規劃。

分享大綱:

1、大數據平臺概述

2、Sloth:實時計算

3、Kudu:實時更新存儲

4、Kyuubi:Spark 多租戶

5、未來規劃

正文:

2008年之前,網易一直在使用傳統數據庫軟件,隨著數據量的增大逐漸過渡到Hadoop平臺。2009年,網易發現單獨的Hadoop平臺不足以滿足內部數據量的需求,便開始著手研發相關工具。2014年之後,隨著網易雲音樂和網易考拉等業務的發展,網易原有工具也無法支撐龐大的數據使用訴求,網易開始進入平臺化階段,推出網易猛獁和網易有數兩款產品。

網易猛獁是面向網易集團內部的大數據平臺軟件,網易有數是企業級智能可視化分析平臺。網易之所以推出這兩款產品,是因為單純維護Hadoop並不能滿足數據使用訴求,我認為最核心的原因是大數據系統難以使用,以下是一個典型的數據處理流程:

網易大數據平臺架構實踐分享

數據從Kafka出發,通過Flink處理同時寫入HDFS和HBase。HDFS的數據經過Spark進一步處理最終將彙總數據返回HDFS,傳遞給BI軟件進行展示或者為線上數據提供支持。如果將大數據系統與數據庫內核做對比,我們發現Kafka其實類似於數據庫中的Redo log,Hbase/ES代表一個索引,經過進一步彙總最終形成物化視圖HDFS Parquet。

表和索引通過Kafka日誌保證一致,相當於將組件重新組成類數據庫內核的樣子讓各組件配合工作,保證系統的穩定性和性能。整體來看,這件事情比較複雜,一番折騰下來,我們認為大數據系統還是比較難用的,需要花費大量精力組裝搭配,雖然這也證明了大數據系統比較靈活,但確實進入門檻較高。

我們考慮要做一個大數據平臺,就需要先搞清楚我們的需求是什麼。我認為主要有以下四點:

一是可提供大數據的基礎能力;

二是在基礎之上提高使用效率,所謂的使用是指用戶在我們的大數據平臺上開發數據業務,包括數據倉庫、數據可視化、推薦業務等的使用效率,這是大數據平臺的核心價值;

三是提升管理效率,運營一個大數據平臺會涉及到各方面的管理,比如升級、擴容、技術支持的代價等,我們需要提升管理效率進而降低成本。

四是多租戶安全,大數據平臺服務於整個公司,公司內部多條業務線都會使用,多租戶安全是必備功能。

在這些需求之下,網易大數據最終的整體架構如下:

網易大數據平臺架構實踐分享

整個平臺主要有四大特點:

一是統一元數據服務,Hive、Spark、Impala、HBase等元數據打通,也就是平臺上任意一張表既可用Hive查詢,也可用Spark、Impala來查,不需要在不同系統之間做元數據的同步。

二是流計算服務,我們用SQL作為開發方式,完全與離線SQL兼容。

三是數據安全與權限,Spark、Hive、Impala、HDFS等組件的權限自動同步。從Spark、Hive、Impala進來的請求,權限都可以得到控制,無論是通過表接口來訪問還是通過底層HDFS來訪問,權限都不會有任何洩露。

此外,我們也做列級權限控制以及角色訪問控制。在我們的平臺中,我們會為網易的每個用戶發放kerberos Key,我們採用kerberos認證,權限可控制到個人級別,每個人的所有操作都會有審計。此外,我們提供一站式開發IDE,我們的客戶在IDE上進行數據開發,我們也提供一站式部署業務監控體系。

在技術方面,我們的思路是滿足大致平臺需求從大數據平臺的需求出發,採取自研和開源相結合的方式,在底層基礎組件方面以開源為主,在其上進行增強和改進。

在一些相關工具上,我們以自研來滿足用戶需求,我們做的事情主要包括Kafka服務化,我們把Kafka做成雲服務的方式,在日誌收集方面做了Data Stream系統,主要功能是把日誌收集到大數據平臺並轉成Hive表。我們也做了數據庫同步工具,完成數據庫到數據庫,數據庫到大數據系統之間的同步。

在Spark方面,我們做了多租戶和高可用。,引用我們引入開源項目Kudu解決數據實時性實施方面的問題。,並我們針對kudu在上面做了很多優化。,採用Ranger作為統一權限控制中心,但Ranger性能有限,處理不了大量表和用戶場景,所以,我們不得不擴展Ranger,優化其性能使其可以支撐更多表和數據。

接下來,我會分幾個技術點介紹大數據方面的工作。首先,我先介紹一下Kudu,這是我們解決數據實時性的工具,Kudu的定位介於HBase和HDFS中間。我們認為,雖然HBase具備隨機訪問和更新能力,但它的數據查詢分析能力較差。HDFS的查詢分析和scan掃描性能較好,但它的數據實時性較差且更新能力不強。

網易大數據平臺架構實踐分享

Kudu兼具了二者的優點,掃描查詢性能較好且同時也有更新和隨機訪問的能力。如果將Kudu和HBase對比,它們同時是KV系統,最不同的地方有以下幾個方面:

網易大數據平臺架構實踐分享

一是Kudu採用Raft多副本協議,而HBase通過HDFS來做複製,這樣的好處是Kudu的可用性會好一些。此外,在數據分區方面分析上,HBase支持用Ranger分區,Kudu採用用Ranger、Hash組合分區。在使用HBase的過程中,我們經常會遇到數據熱點問題,所以設計schema時,通常不得不在Hbase會在key里加入一些隨機哈希值,而,這就是Kudu組合分區則能有效的優勢,不用擔心數據熱點問題。

此外,在數據格式上,HBase在ColumnFamily內部採用屬於行存格式。在HBase內,我們很難設置很多ColumnFamily,因為會影響性能,每個ColumnFamily都會帶上主鍵組件,這會導致數據冗餘和變大,而Kudu的數據通過RowGroup形式組織,完全是列存結構,所以掃描性能會比較好。

整個Kudu的大致架構如下, 它有一個管理服務器負責管理,數據通過分區方式分片到眾多切分成Tablet,然後存儲到Tablet Server。每個Tablet Server負責多個Tablet,每個Tablet對應多個MemRowSet。

網易大數據平臺架構實踐分享

MemRowSet寫滿之後就會存到磁盤形成DiskRowSet上,每個DiskRowSet是Base +Delta結構, 看起來與HBase類似,主要的不同在於前者掃描性能更優,因為Base中的Kudu屬於列存模式,所以性能更好。

其次,DiskRowSet之間沒有記錄重疊,這與HBase不太一樣。這樣做最大的好處在於掃描時不用多個DiskRowSet之間做合併,只需要掃描單個DiskRowSet之間掃描就可以了。

此外,Dalta數據結構用物理offset偏移量做key,掃描時可快速定位到記錄的變更很容易就可找到Delta的位置信息,而HBase用記錄主鍵做邏輯定位,這就是Kudu掃描性能更佳的原因 性能相對更慢一些。

Kudu的問題主要有以下幾點,一是在使用Impala查詢引擎的情況下,性能與Parquet相比有不小差距。雖然官方測試報告中指出kudu的性能比Parquet更優,但經過我們的實際測量,結果剛好相反(下圖為實際測量結果,Q16、Q17、Q19相差十分明顯)。

網易大數據平臺架構實踐分享

其二,Kudu缺少Spilt和Merge功能,Ranger分區缺少自動分裂的過程,當分區越來越大之後,我們就沒有辦法處理熱點問題了。

為了解決上述問題,網易做的第一個優化是Kudu Runtime Filter,這是為了加速kudu的性能。比如,如果需要做大小表的join,一般可能有兩種做法,一是大表和小表都根據join key來做shuffle,把相同的join key數據shuffle到同一臺機器上,但這種做法開銷比較大。

二是小表廣播,將小表廣播到所有查詢服務器上,與大表一起做join,網易在這部分採用的是Kudu Runtime Filter。

我們的做法是為小表join key生成Runtime Filter,這樣做的好處在於kudu在掃描底層數據時會拿Runtime Filter去底層過濾數據,這樣的結果就是返回Impala層的數據會大大減少。以下圖為例,紅色是一個的scan操作, 可以看到kudu返回的記錄數會變的很少,特別是返回數據集較小的情況下。

網易大數據平臺架構實踐分享

經過改進,Kudu的性能有了很大提升。下圖黑色的是原生kudu,橙色的是加入Runtime fliter的版本,二者對比,後者在性能上確是有很大提升。整體來看,kudu的性能比Parquet要低30%左右,但一般情況下是夠用的,因為畢竟它有數據更新的能力,自然會犧牲一些查詢性能。

網易大數據平臺架構實踐分享

此外,我們也做了kudu Tablet Split自動分裂功能,主要對Ranger分區做了分裂,分裂思路比較簡單,主要是修改元數據,整個過程瞬間在線完成,不會涉及數據真正的變更,。具體做法是在元數據上標識將一個Tablet分為兩個,此後都遵循該原則,但只有在Compaction時才會發生真正的物理分裂。

此外是主從協同。當主發生分裂時,會通過Raft協議同步所有副本同時分裂。通過這個方式,我們完成了Kudu的分裂,線上管理也很方便。

接下來介紹一下Kudu的應用場景,一是對實時性要求較高的場景,Kudu可以做到秒級實時,而HDFS只能做半小時以上的準實時,如果數據實時性要求很高,小文件會比較多進而影響性能。

二是點查和多維分析融合,一個用戶的行為分析系統通常有兩類需求,一是指定用戶查詢;二是大批量用戶行為分析,這就涉及到多維分析。傳統。架構需要實現結合需要HBase和HDFS Parquet二者結合,點查單個用戶需要使用HBase,批量查詢需要使用HDFS,顯然這樣的成本比較高。如果使用Kudu,因為其可以同時滿足KV查詢和多維分析查詢,整體架構會比較簡單,成本也相對較低。

三是實時維表,在互聯網應用中,Hadoop會存一些用戶行為日誌,但還有一些數據在數據庫裡,比如商品、用戶等維表。數據庫裡的數據通常會每天全量導入,實時性比較差,當然也可以選擇按小時導入,但這樣數據庫壓力會很大,如果數據庫增量導入大數據平臺,然後再做全量merge,實時性會比較差。

網易的解決方案是使用工具直接把數據庫實時同步到Kudu,Kudu的數據可以跟Hadoop用戶行為數據直接做join連查,這樣整個平臺的實時性會做到秒級,性能也不錯。

接下來,我想介紹一下我們的實時計算系統——Sloth。Sloth是一個基於SQL開發的流計算系統,它的SQL看起來與Hive SQL類似,同樣支持DDL、UDF,join子查詢等。我們的流計算系統基於Flink引擎開發,通過CodeGen的方式生成Flink代碼,然後同步到集群執行。

在效果上,我們做到了Exactly Once跟增量計算模型,通過實時計算SQL算出來的結果跟用離線計算出來的結果一樣,這是對數據正確性的重要保證。當然,Sloth也是在猛獁大數據平臺上開發的。

網易大數據平臺架構實踐分享

以上是Sloth的開發界面,我們設計了寫SQL的地方,同時也可以調試並完成實時計算任務。以電商系統為例,我們需要對商家按照銷售額進行分類統計,比如說銷售額0-100之間做分類,100-200區間內歸為另一類,依此類推計算出每個區間內的商家個數。

網易大數據平臺架構實踐分享

以上圖為例,第一條計算每個商家的銷售總額,我們需要先定一個臨時表tmp,再針對tmp做一個GROUP BY,相當於把商家銷售額給GROUP BY計算,得出每個商家的銷售額。

第二條是計算每個區間內的商家個數。此時,我們可以用GROUP BY銷售額除以100,這是要查詢的臨時表tmp。兩條SQL跟離線完全一樣,如果表定義和實時計算一樣的話,你是可以拿到Hive上運行的。

只要通過這兩條SQL就可以完全實現計算任務開發,那它跟離線計算結果有什麼不一樣呢?它實時輸出結果,而離線是一次性輸出結果,提交這樣的SQL就不停的輸出銷售額的分類統計。

在這個任務下假設我們輸入的數據有四條(如下圖):第一個商家交易額30,然後第二個商家交易額10,第三個商家交易額80,再來第三個商家交易額50,我們來看看用不同的計算引擎出來的計算結果有哪些差異。

如果用MapReduce這樣的離線計算,我會得到四條數據會得到0~100區間內有2條記錄, 100~200區間內有1條記錄。但如果用流式計算,可能就會遇到問題,為什麼這麼說呢?如果你現在已經處理了3條數據,就是說(1,、30),(,2,、10),(3,、80)這三條數據,這個情況下你說出的輸出的結果是0-100有三個商家。當第四條數據參與計算後,系統可能就會輸出0-100有三個有3個商家,100-200有一個有1商家,這個結果就是有誤的,這是因為實時計算沒有去糾正已經輸出的計算結果。的原則是不停得計算並輸出結果。

網易大數據平臺架構實踐分享

那麼,這個問題如何解決呢?早期的Flink缺少該功能,我們就在Flink的基礎上做了改造。所謂的增量計算是指在遇到上述情況時需要撤銷前一步計算結果,上游算子需要不停得向下遊算子發出撤銷操作請求,直到數據糾正過來最終輸出正確結果。

通過該方式,我們保證了SQL計算的正確性。

一個SQL任務分為DDL和DML語句,Sloth通過SQL方式編寫, DDL的作用是在Kafka之上的DDL,也可定義在其他輸入源之上定義流表用戶的job就是定義在Kafka之上的DDL,也可定義在其他輸入語言之上。流表定義完成之後,我們需要做就可以編寫很多DML操作數據,計算結果。

一個SQL的job分為DDL和DML語句,對於純SQL語句,我們需要先對其進行編譯。首先,我們編譯每條DDL,對每條DML單獨編譯每條SQL語句;其次,生成執行計劃,將不同SQL的執行計劃串聯起來,因為它們彼此之間存在輸入輸出關係。然後,根據不同SQL計劃之間的依賴關係,我們會生成一個全局Sloth執行計劃;最後,我們將該執行計劃生成代碼,將代碼提交給Flink執行,這就是整個Sloth的執行過程。

接下來,我會介紹網易在Spark多租戶方面的工作,這個項目叫做Kyuubi(該項目的開源地址:
https://github.com/netease-bigdata/kyuubi
https://github.com/yaooqinn/kyuubi),實際上是類似於HiveSever2的程序。大家可能都知道,Hive一般有兩種使用模式,一種是client模式,所有的SQL解析都客戶端在這之中完成。一種是HiveSever2模式,整個SQL解析放到server端完成。

在公司實際使用過程中,我們更希望用戶的使用行為通過Server端完成,否則會很難管理,因為客戶端根本不在平臺掌控範圍之內,我們很難進行各種升級及配置變化。只有當MetaStore和HDFS 配置不暴露給用戶,我們才能更好得管控。Hive的社區比較完善,在這方面沒有問題,但是Spark還有些不足。其實,所謂的Kyuubi只是在類似HiveSever2的基礎上提供服務, 提供SparkSQL服務,而不是Hive SQL服務。

Kyuubi基於Spark Thrift Sever改造,Spark Thrift Sever類似於HiveSever2,但是它不夠完善。由於我們在此基礎上增加了多租戶的功能,因此可以支持網易內部各業務線的使用。要想實現多租戶功能,首先要把SparkContext變成多實例,之後每次執行代理真正的用戶身份執行;其次,我們提供了Spark SQL集群,用戶請求負載均衡到每臺Kyuubi服務器,並且這部分是高可用的,一臺服務器掛了會立刻切換到另一臺。

此外,我們對安全性也進行了改進,支持kerbros。其實,整個網易猛獁平臺都是強安全認證系統,每個用戶都有自己的kerberos key tabkerbros,所有系統拿kerberoskerbros做認證訪問都是帶認證的,Kyuubi要融入這個體系同樣需要支持kerberoskerbros。

Kyuubi的主要特點如下:一是具備統一接口,與HiveSever2相比,Kyuubi提供SwiftThrift的API,無論是Beeline客戶端、JDBC客戶端、ODBC客戶端還是網易猛獁自助分析查詢平臺、有數可視化BI平臺,Kyuubi都可以用標準的方式連接到Spark。

二是有彈性的資源控制能力,Kyuubi支持session級別的資源配置,每個session所需的隊列、資源核數和內存都可以進行配置。

三是支持SparkContext的動態緩存。創建一個SparkContext耗時較長,所以我們要對SparkContext進行緩存設置,讓用戶不需要每次查詢都動態創建SparkContext。

此外,我們也支持Spark動態資源分配特性,啟用SparkContext需要啟用一堆Spark執行器。如果業務需要較快的響應速度,那就直接發SQL,不需要等待進程啟用。

四是Kyuubi安全特性,首先是支持Kerberos還有代理執行,最後支持集成我們自己的spark-authorizer權限驗證插件,該插件對Spark沒有侵入性,主要用於查詢優化的最後階段。實際上,具體權限對接的是rRangerr中的權限控制中心,通過集成Spark-authorizer,我們能夠做到細粒度的權限控制。

此外,我們也支持服務的高可用和負載均衡,Kyuubi基於負載均衡的方式設計,通過將ZK作為Namespace來實現。具體過程為,Kyuubi將自己註冊到ZK,ZK形成服務列表,註明各服務的存活狀態,客戶端會與ZK通訊拿到該服務器列表,從中挑選Kyuubi服務器執行。通過這種方式,我們將負載均衡到眾多Spark查詢設備上,從而避免了單點故障,保證了服務的可用性。

總結來看,Kyuubi以HiveServer2 Thrift API為接口協議,提供Spark SQL服務。相比傳統的Spark,Kyuubi主要增加了企業級特性,如果公司多租戶場景較多且業務線複雜,多租戶功能是比較要緊的事情比如多租戶、權限、負載均衡等。

最後,我介紹一下網易在未來的規劃。首先,我們會進一步完善高性能查詢引擎。目前,我們正在用的查詢引擎是Impala,雖然性能較優,但我們還希望可以在與Kudu配合等方面進行更多優化。

二是實現實時和離線計算混步。針對網易目前龐大的集群數量,我們希望可以通過混部步來解決該問題。首先,晚上是離線計算的高峰期,任務通常會等到所有數據完成也就是凌晨定時起來跑,實時計算的高峰期與用戶使用高峰期一樣都在白天,因此可以與離線計算實現錯峰運行。在集群規模較大的情況下,這種方式的意義非常明顯,我們希望可以解決這種方式帶來的隔離、彈性等方面的問題。

三是集成更多硬件做加速,比如GPU或者FPGA。

四是智能任務診斷和優化。因為網易內部數據量和任務非常龐大,我們希望可以通過智能化任務診斷的方式輔助技術支持人員更好得完成工作,未來希望可以達到AIops的程度。


分享到:


相關文章: