PB 級數據秒級響應:Uber 實時數據平臺架構演進
引入
Uber 是一家科技公司,在 2010 年初推出了讓司機與乘客便捷溝通的應用軟件,從而改變了出租車市場。爲了支持業務,Uber 積極利用數據分析和機器學習模型輔助運營。從 Uber 乘車的動態定價到外賣軟件 Uber Eats 的 “餐廳經理(Restaurant Manager)” 儀表板,都使用實時數據進行高效操作。在本文中,請跟隨筆者一起了解 Uber 如何管理其支持實時應用程序的基礎架構。
注:本文是筆者閱讀論文 Real-time Data Infrastructure at Uber 後的筆記。
一、背景
Uber 的業務具有高度實時性。數據不斷從多個來源收集:司機、乘客、餐館、食客或後端服務。Uber 處理這些數據以提取有價值的信息,以便爲許多用例做出實時決策,如客戶激勵、欺詐檢測和機器學習模型預測。實時數據處理在 Uber 的業務中扮演着至關重要的角色。該公司使用開源解決方案和內部改進來構建實時基礎架構。
宏觀來看,Uber 的實時數據處理包括三個廣泛領域:
1. 消息平臺: 允許生產者和訂閱者之間的通信。
2. 流處理: 允許將處理邏輯應用於消息流。
3. 在線分析處理(OLAP): 能夠在近乎實時的情況下對所有數據進行分析查詢。
每個領域都面臨着三個基本的擴展挑戰:
-
數據擴展: 實時數據輸入總量呈指數級增長。此外,爲了實現高可用性,Uber 的基礎架構位於多個地理區域,這意味着系統在處理數據量增加的同時,還保持數據新鮮度、端到端延遲和可用性服務水平協議(SLA)。
-
用例擴展: 隨着 Uber 業務的增長,新的用例出現,不同組織部分之間的需求各不相同。
-
用戶擴展: 與實時數據系統交互的不同用戶具有不同的技術技能水平,包括沒有工程背景的業務用戶、需要開發複雜實時數據管道的高級用戶。
二、對基礎架構的要求
Uber 的實時基礎架構需要以下要點:
1. 一致性: 關鍵應用程序需要在所有區域中的數據具備一致性。
2. 可用性: 基礎架構必須具有高度可用性,保證 99.99% 的服務水平。
3. 新鮮度: 大多數用例要求數據具有秒級新鮮度。這確保了對特定事件(如安全事件)做出響應的能力。
4. 延遲: 一些用例需要在原始數據上執行查詢,並要求查詢的 p99 延遲低於 1 秒。
5. 可擴展性: 系統能夠隨着不斷增長的數據量進行擴展。
6. 成本: Uber 需要低成本的數據處理和服務,用以確保高運營效率。
7. 靈活性: Uber 必須提供程序化和聲明式接口,以表達計算邏輯,服務於不同類別的用戶。
三、構建模塊
在這一部分,我們來審視一下 Uber 基礎架構的主要邏輯構建模塊:
-
存儲: 該層爲其他層提供對象或 bolb 存儲,並保證寫後讀的一致性。它用於長期存儲,應該針對高寫入率進行優化。Uber 還使用這一層,進行數據回填或引導到流或 OLAP 表。
-
流: 它充當發佈 - 訂閱接口,應該針對低延遲的讀寫進行優化。它需要對數據進行分區,並保證至少一次的語義(譯者注:at least once,系統保證消息被接收,但不能保證只接收一次)。
-
計算: 該層在流和存儲層上提供計算。該層還要求在源和接收器之間保證至少一次的語義。
-
OLAP: 這一層針對來自流或存儲的數據,提供有限的 SQL 能力;針對服務分析查詢進行優化。從不同來源獲取數據時,需要保證至少一次語義。某些用例需要基於主鍵精確地一次獲取數據(exactly once)。
-
SQL: 是計算和 OLAP 層之上的查詢層。它將 SQL 語句編譯成可以應用於流或存儲的計算函數。當與 OLAP 層配合使用,將增強 OLAP 層的 SQL 限制能力。
-
API: 高層的應用程序訪問流或計算函數的編程方式。
-
元數據: 管理所有層的所有元數據的簡單接口。這一層需要元數據版本控制和跨版本的向後兼容性。
四、開源解決方案
接下來的部分將介紹 Uber 採用的開源系統,對應於相應的構建模塊。
Apache Kafka:流存儲
Apache Kafka 是業界廣泛採用的流行開源事件流系統,最初由 LinkedIn 開發,隨後在 2011 年初開源。除性能外,Kafka 被採用的其他因素還包括簡單性、生態系統成熟度和開源社區。
-
Uber 擁有最大的 Apache Kafka 部署之一: 每天數萬億條消息和 PB 級的數據。
-
Kafka 在 Uber 支持許多工作流程: 傳播來自乘客和司機應用的事件數據,支持流分析平臺,或者將數據庫變更日誌傳遞給下游訂閱者。
由於 Uber 獨特的規模特性,他們對 Kafka 進行了以下增強:
1)集羣聯邦:邏輯集羣
Uber 開發了一個聯邦化的 Kafka 集羣設置,對生產者和消費者隱藏了集羣細節:
-
他們向用戶展示了 “邏輯 Kafka 集羣”。用戶不需要知道主題位於哪個集羣中。
-
專用服務器會集中管理所有集羣和主題的元數據,並將客戶端的請求路由到物理集羣。
-
此外,集羣聯邦有助於提高可擴展性。當一個集羣被充分利用時,Kafka 服務可以通過添加更多的集羣進行水平擴展。新的主題可以在新集羣中無縫創建。
-
集羣聯邦還簡化了主題管理。由於應用程序和客戶端衆多,將一個活動主題遷移到 Kafka 集羣之間需要大量工作。在大多數情況下,這個過程需要手動配置,將流量路由到新集羣,從而導致消費者重新啓動。集羣聯邦有助於在不重啓應用程序的情況下,將流量重定向到另一個物理集羣。
2)死信隊列:失敗消息的隊列
在某些情況下,下游系統無法處理消息(如消息損壞)。最初,有兩種方法可以處理這種情況:
-
Kafka 丟棄這些消息。
-
系統無限期地重試,這會阻塞後續消息的處理。
然而,Uber 有許多場景,既不要求數據丟失,也不要求阻塞處理。爲了解決這類用例,Uber 在 Kafka 的基礎上構建了死信隊列(DLQ)策略:如果消費者在重試後無法處理消息,它將把該消息發佈到 DLQ。這樣,未處理的消息將被單獨處理,不會影響到其他消息。
3)消費者代理:中間層
隨着數以萬計的運行 Kafka 的應用程序,Uber 在調試它們和升級客戶端庫方面都面臨挑戰。用戶還在企業內部,使用多種編程語言與 Kafka 交互,這使得提供多語言支持變得十分喫力。
Uber 構建了一個消費者代理層來應對這些挑戰;代理從 Kafka 讀取消息,並將其路由到 gRPC 服務端點。它處理消費者庫的複雜性,應用程序只需採用一個薄型的 gRPC 客戶端。當下遊服務無法接收或處理某些消息時,代理可以重試路由,並在多次重試失敗後將消息發送到 DLQ。代理還能將 Kafka 中的發送機制,從消息輪詢改爲基於推送的消息分派。這提高了消費吞吐量,並允許更多的併發應用程序處理機會。
4)跨集羣複製:集羣間高效複製主題
由於業務規模龐大,Uber 在不同的數據中心使用多個 Kafka 集羣。在這種部署中,Uber 需要 Kafka 的跨集羣數據複製,原因有二:
-
用戶需要一個全局數據視圖來處理各種用例。例如,爲了計算行程指標,他們必須整合和分析所有數據中心的數據。
-
Uber 複製 Kafka 部署以實現故障情況下的冗餘。
Uber 構建並開源了一個名爲 uReplicator 的可靠解決方案,用於 Kafka 複製。複製器採用重新平衡算法,在重新平衡的過程中儘可能減少受影響主題分區的數量。此外,它還可以在流量突發時將負載重新分配給備用工作器。
筆者稍微研究了以下 uReplicator 的高層架構,發現了以下內容:
-
Uber 使用 Apache Helix 進行 uReplicator 集羣管理。
-
Helix 控制器負責向工作器分配主題分區,處理主題 / 分區的添加 / 刪除,檢測節點故障,以及重新分配這些特定的主題分區。
-
收到主題 / 分區複製的請求後,Helix 控制器會向 Zookeeper 服務更新主題 / 分區與當映射發生變化時,工作者中的 Helix 代理會收到通知。
-
工作器中的 DynamicKafkaConsumer 實例將執行復制任務。
Uber 還開發並開源了另一個名爲 Chaperone 的服務,以跨集羣複製不會造成數據丟失。它收集關鍵統計數據,如每個複製階段的唯一消息數量。然後,Chaperone 比較統計數據,並出現不匹配時生成警報。
Apache Flink:流處理
Uber 使用 Apache Flink 構建了流處理平臺,處理來自 Kafka 的所有實時數據。Flink 提供了一個具有高吞吐量和低延遲的分佈式流處理框架。Uber 採用 Apache Flink 有以下原因:
-
其魯棒性支持大量工作負載,具有原生狀態管理和故障恢復的檢查點功能。
-
易於擴展,並且可以有效處理反壓。
-
擁有一個龐大且活躍的開源社區。
Uber 對 Apache Flink 做出了以下貢獻和改進:
1)Flink SQL:使用 SQL 構建流式分析應用程序
Uber 在 Flink 的頂層設計了一個名爲 Flink SQL 的層,它可以將 Apache Calcite SQL 輸入轉換爲 Flink 作業。處理器將查詢編譯爲分佈式 Flink 應用程序,並管理其整個生命週期,讓用戶專注於處理邏輯。在幕後,系統將 SQL 輸入轉換爲邏輯計劃,然後通過優化器形成物理計劃。最後,該計劃使用 Flink API 將計劃轉換爲 Flink 作業。
然而,向用戶隱藏複雜性,會增加基礎架構團隊管理生產作業的運營開銷。Uber 不得不應對這些挑戰:
-
資源估算和自動縮放: Uber 使用分析找到常見作業類型與資源需求之間的關聯,同時持續監控工作負載,以實現更好的集羣利用率,並按需執行自動縮放。
-
作業監控和自動故障恢復: 由於用戶不知道幕後的運作規則,平臺必須自動處理 Flink 作業故障。爲此,Uber 構建了一個基於規則的引擎。該組件比較作業的指標,然後採取相應的行動,例如重新啓動作業。
注:Flink SQL 是一個具有無限制輸入和輸出的流處理引擎,它的語義不同於批處理 SQL 系統,如 Presto(稍後將討論)。
2)用於部署、管理和運行的統一架構
Uber 的 Flink 統一平臺實現了分層架構,以提高可擴展性和可擴展性。
-
平臺層組織業務邏輯並與其他平臺集成,如機器學習或工作流管理。該層將業務邏輯轉換爲標準的 Flink 作業定義,並將其傳遞給下一層。
-
作業管理層處理 Flink 作業的生命週期:驗證、部署、監控和故障恢復。它存儲作業信息:狀態檢查點和元數據。該層還充當代理,根據作業信息將作業路由到物理集羣。該層還有一個共享組件,可持續監控作業的健康狀況,並自動恢復失敗的作業。它爲平臺層提供了一套 API 抽象。
-
底層由計算集羣和存儲後端組成。它提供了物理資源的抽象,無論它們是在本地還是雲基礎架構中。例如,存儲後端可以使用 HDFS、Amazon S3 或 Google Cloud Storage (GCS) 作爲 Flink 作業的檢查點。
得益於這些改進,Flink 已成爲 Uber 的中央處理平臺,負責處理成千上萬的作業。現在,讓我們繼續討論 OLAP 構建模塊的下一個開源系統:Apache Pinot。
Apache Pinot:OLAP 系統
Apache Pinot 是一個開源的分佈式 OLAP 系統,用於執行低延遲的分析查詢。它在 LinkedIn 創建,“因爲工程人員認爲沒有現成的解決方案滿足該社交網站的要求” 之後。Pinot 具有 lambda 架構,可呈現在線(實時)和離線(歷史)數據之間的統一視圖。
自從 Uber 引入 Pinot 以來的兩年時間裏,其數據足跡從幾 GB 增長到數百 TB。隨着時間推移,查詢工作負載從每秒幾百個 QPS(Queries-per-second,每秒查詢數)增加到數萬個 QPS。
Pinot 支持多種索引技術來回答低延遲的 OLAP 查詢,例如倒排索引、範圍索引或星樹索引。Pinot 採用分散 - 收集 - 合併方法,以分佈式方式查詢大型表。它按時間邊界劃分數據,並將數據分組,同時並行執行查詢計劃。以下是 Uber 決定使用 Pinot 作爲其 OLAP 解決方案的原因:
-
在 2018 年,可供選擇的方案有 Elasticsearch 和 Apache Druid,但他們在接下來的評估中發現,Pinot 的內存和磁盤佔用更小,而且支持明顯更低的查詢延遲 SLA。
-
對於 ElasticSearch: 在向 Elasticsearch 和 Pinot 輸入相同數量數據的情況下,Elasticsearch 的內存使用量是 Pinot 的 4 倍,磁盤使用量是 Pinot 的 8 倍。此外,Elasticsearch 的查詢延遲比 Pinot 高 2 到 4 倍,使用組合過濾器、聚合和分組 / 排序查詢進行基準測試。
-
對於 Apache Druid: Pinot 在架構上與 Apache Druid 類似,但採用了優化的數據結構,例如位壓縮前向索引,以降低數據佔用。它還使用專門的索引以加快查詢執行速度,例如星樹索引、排序和範圍索引,這可能導致查詢延遲的差異達到一個數量級。
五、用例
在 Uber,用戶利用 Pinot 處理許多實時分析用例。這些用例的主要要求是數據新鮮度和查詢延遲。爲滿足 Uber 的獨特要求,工程師們爲 Apache Pinot 提供了以下功能:
- Upsert(更新插入)
Upsert 操作結合了插入和更新操作。它允許用戶更新現有記錄,並在數據庫中不存在記錄的情況下插入新記錄。Upsert 是許多用例的常見需求,例如更正車費或更新交付狀態。
Upsert 操作的主要挑戰是找到所需記錄的位置。爲了克服這一點,Uber 使用主鍵將輸入流分成多個分區,並將每個分區分發給節點進行處理。這意味着同一個節點將處理具有相同主鍵的所有記錄。Uber 還開發了一種路由策略,將同一分區段上的子查詢路由到同一節點。
- 全面的 SQL 支持
Pinot 最初缺乏重要的 SQL 特性,如子查詢和連接。Uber 已將 Pinot 與 Presto 集成,以便在 Pinot 之上啓用標準的 PrestoSQL 查詢。
與數據生態系統的其餘部分集成
Uber 投入了大量精力將 Pinot 與數據生態系統的其餘部分集成,以確保良好的用戶體驗。
例如,Pinot 與 Uber 的模式服務集成,可從輸入 Kafka 主題推斷模式並估計數據的基數。Pinot 還集成了 Flink SQL 作爲數據匯,這樣客戶就可以建立 SQL 轉換查詢,並將輸出信息推送到 Pinot。
1)HDFS:檔案存儲
Uber 使用 HDFS 存儲長期數據,來自 Kafka 的 Avro 格式數據大多以原始日誌的形式存儲在 HDFS 中。壓縮過程將日誌合併成 Parquet 格式,然後可通過 Hive、Presto 或 Spark 等處理引擎使用。該數據集是所有分析目的的真實來源。Uber 還將此存儲用於 Kafka 和 Pinot 中的數據回填。此外,其他平臺也將 HDFS 用於其特定用途。例如:
-
Apache Flink 使用 HDFS 進行作業檢查點。
-
Apache Pinot 使用 HDFS 進行長期段存檔。
2)Presto:交互式查詢層
Uber 採用 Presto 作爲其交互式查詢引擎解決方案。Presto 是 Facebook 開發的開源分佈式查詢引擎。它採用大規模並行處理(MPP)引擎,在內存中執行所有計算,避免將中間結果寫入磁盤,從而實現對大規模數據集的快速分析查詢。
Presto 提供了一個帶有高性能 I/O 接口的 Connector API,允許連接到多個數據源:Hadoop 數據倉庫、關係數據庫管理系統(RDBMS)或 NoSQL 系統。Uber 爲 Presto 構建了一個 Pinot 連接器,以滿足實時探索需求。這樣,用戶就可以在 Apache Pinot 上執行標準的 PrestoSQL。
Pinot 連接器需要決定哪些物理計劃的部分可以下推到 Pinot 層。由於 API 的限制,該連接器的第一個版本只包括謂詞下推。Uber 改進了 Presto 的查詢計劃器,並擴展了連接器 API,儘可能多地將運算符下推到 Pinot 層。這有助於降低查詢延遲,充分利用 Pinot 的索引功能。
在瞭解 Uber 如何使用開源系統構建實時基礎架構後,我們將討論 Uber 生產中的一些用例,以及他們如何使用這些系統來實現他們的目標。
3)分析應用:激增定價(Surge Pricing)
激增定價用例是 Uber 中的一種動態定價機制,用於平衡可用司機的供應與乘車需求。用例的總體設計:
-
從 Kafka 獲取流數據。
-
管道在 Flink 中運行基於機器學習的複雜算法,並將結果存儲在鍵值存儲中,以便快速查詢。
-
激增定價應用優先考慮數據的新鮮度和可用性,而不是數據的一致性,以滿足延遲 SLA 要求,因爲延遲到達的消息無助於計算。
-
這種權衡的結果是,Kafka 集羣的配置可以提高吞吐量,但不能保證無損。
4)儀表板:Uber Eats 餐廳經理
Uber Eats 餐廳經理儀表板允許餐廳所有者運行切片查詢,以查看 Uber Eats 訂單的深入分析,如客戶滿意度、熱門菜單項目和服務質量分析。用例的整體設計:
-
該用例需要新鮮數據和低查詢延遲,但它不需要太多靈活性,因爲查詢的模式是固定的。
-
Uber 使用帶有 start-tree 索引的 Pinot 來縮短服務時間。
-
他們利用 Flink 執行過濾、聚合和滾動等任務,幫助 Pinot 減少處理時間。
-
Uber 還觀察了轉換時間(Flink)和查詢時間(Pinot)之間的權衡。轉換過程會產生優化的索引(在 Pinot 中),並減少需要服務的數據。反過來,這也降低了服務層的查詢靈活性,因爲系統已經將數據變成了 “固定形狀”。
5)機器學習:實時預測監控
機器學習在 Uber 中扮演着至關重要的角色,爲確保模式的質量,監控模型預測輸出的準確性至關重要。用例的總體設計:
-
由於數據量大、卡數高,該解決方案需要具備可擴展性:數千個已部署的模型,每個模型都有數百個特徵。
-
它利用了 Flink 的水平可擴展性。Uber 部署了一個大型流作業來聚合指標並檢測預測異常。
-
Flink 作業將預聚合創建爲 Pinot 表,以提高查詢性能。
6)個例探索:Uber Eats 運營自動化
Uber Eats 團隊需要在來自快遞員、餐廳和食客的實時數據上執行臨時分析查詢。這些洞察將用於基於規則的自動化框架。該框架特別在 COVID-19 期間幫助運營團隊在遵守法規和安全規則的情況下運營業務。用例的總體設計:
-
底層系統必須具有高可靠性和可擴展性,因爲這一決策過程對業務至關重要。
-
用戶在 Pinot 管理的實時數據上使用 Presto 來檢索相關指標,然後將其輸入自動化框架。
-
該框架使用 Pinot 聚合過去幾分鐘內給定地點所需的統計數據,然後相應地爲快遞員和餐廳生成警報和通知。
-
Pinot、Presto 和 Flink 隨着數據的增長而快速擴展,並在高峯時段穩定運行。
在結束文章之前,我將在以下部分提供 Uber 的全面活躍策略,它如何管理數據回填,以及從 Uber 學到的經驗教訓。
全活(all-active)策略:Uber 如何提供業務彈性和連續性
Uber 依靠多地區戰略,確保在地理分佈廣泛的數據中心上運行服務並提供備份。由此,如果一個地區的服務不可用,其他地區的服務仍可正常運行。這種方法的基礎是多地區 Kafka 設置,它提供了數據冗餘和流量延續。
以下是動態定價應用的 active-active 設置示例:
-
所有行程事件都發送到 Kafka 區域集羣,然後路由到聚合集羣,獲得全局視圖。
-
Flink 任務將計算每個區域(region)中不同領域(area)的定價。
-
每個區域都有一個更新服務實例,全活協調服務將其中一個標記爲主實例(primary)。
-
爲方便快速查詢,主區域的更新服務將定價結果存儲在全活數據庫中。
-
當主區域發生故障時,全活服務將另一個區域分配爲主區域,計算將轉移到另一個區域。
-
Flink 作業的計算狀態太大,無法在區域之間同步複製,因此必須獨立計算。
→ 由於 Uber 需要管理每個區域的冗餘管道,因此這種方法需要大量計算。
數據回填
出於多種原因,Uber 需要重新處理舊的數據流:
-
新數據管道通常需要針對現有數據進行測試。
-
機器學習模型必須用幾個月的數據進行訓練。
-
流處理管道中的變更或錯誤需要重新處理舊數據。
Uber 使用 Flink 構建了流處理回填解決方案,它有兩種運行模式:
-
基於 SQL: 這種模式允許用戶在實時數據集(Kafka)和離線數據集(Hive)上執行相同的 SQL 查詢。
-
基於 API: Kappa+ 架構允許在批量數據上直接重用流處理邏輯。
Uber 的經驗教訓
1. 採用開源
Uber 在開源組件上構建了大部分實時分析堆棧,這些開源組件爲 Uber 奠定了堅實的基礎。不過,也遇到了一些挑戰:
-
根據實踐經驗,大多數開源技術都是爲特定目的而構建的。
-
Uber 必須做大量工作,調整開源解決方案以適用於廣泛的用例和編程語言。
2. 系統快速開發和演變
對於 Uber 這樣的大公司來說,在架構演變過程中通常會遇到多種驅動因素,例如新的業務需求或行業趨勢。因此,Uber 認識到了實現快速軟件開發的重要性,以便每個系統都能快速發展:
-
接口標準化對於清晰的服務邊界至關重要。Uber 利用 Monorepo 在單個代碼庫中管理所有項目。
-
Uber 始終傾向於使用瘦客戶機(thin clients),以減少客戶端升級的頻率。在引入瘦 Kafka 客戶端之前,升級 Kafka 客戶端需要幾個月的時間。
-
採用語言整合策略,減少與系統通信的方式數量。Uber 只支持 Java 和 Golang 編程語言,使用 PrestoSQL 作爲聲明性 SQL 語言。
-
平臺團隊將所有基礎架構組件與 Uber 專有的 CI/CD 框架集成,以在臨時環境中持續測試和部署開源軟件更新或功能開發,這也最大限度減少了生產環境中的問題和錯誤。
3. 易於操作和監控
-
操作: Uber 投資了聲明式框架來管理系統部署。用戶定義了諸如集羣啓動 / 關閉、資源重新分配或流量重新平衡等操作的高級意圖後,框架將自動處理這些指令,無需工程師干預。
-
監控: Uber 使用 Kafka、Flink 或 Pinot 爲每個特定用例構建了實時自動化儀表板和警報。
4. 易於用戶入門和調試
Uber 努力解決用戶規模擴展帶來的挑戰,主要改進了以下幾個方面:
-
數據發現: Uber 的集中式元數據存儲庫充當 Kafka、Pinot 和 Hive 等跨系統模式的真實來源,使用戶能夠方便地搜索所需的數據集。該系統還記錄了這些組件中數據流的數據沿襲。
-
數據審計: 應用程序的事件從端到端進行審計。Kafka 客戶端爲個別事件附加額外的元數據,例如唯一標識符、應用程序時間戳、服務名稱和層級。系統使用這些元數據跟蹤數據生態系統每個階段的數據丟失和重複,幫助用戶有效檢測數據問題。
-
無縫上線: 系統爲生產環境中部署的相應服務自動提供應用程序日誌的 Kafka 主題。用戶還可以使用拖放式 UI 創建 Flink 和 Pinot 管道,由此減少了基礎架構配置的複雜性。
結語
Uber 的論文包含了有關實時基礎架構、系統設計以及公司如何改進和調整開源解決方案(如 Kafka、Pinot 或 Presto)以滿足其獨特擴展要求的寶貴經驗。
參考資料
-
[1] Yupeng Fu and Chinmay Soman, Real-time Data Infrastructure at Uber (2021).
-
[2] Mansoor Iqbal, Uber Revenue and Usage Statistics (2024).
-
[3] Arpit Bhayani, Understanding the read-your-write consistency and why it is important.
-
[4] Alex Xu, At most once, at least once, exactly once (2022).
-
[5] Hongliang Xu, uReplicator: Uber Engineering’s Scalable Robust Kafka Replicator (2018).
-
[6] CelerData, Compute Architecture Pros & Cons — Scatter/Gather, MapReduce and MPP (Massively Parallel Processing) (2023)
-
[7] Aditi Prakash, Demystifying Predicate Pushdown: A Guide to Optimized Database Queries (2023).
-
[8] Dremio, Slice and Dice Analysis.
作者丨 Vu Trinh 編譯丨 onehunnit
來源丨 blog.det.life/how-does-uber-build-real-time-infrastructure-to-handle-petabytes-of-data-every-day-ddf5fe9b5d2c
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/3VFbd40kXhmUT_AHrvLdJQ