優步是如何使用Apache Flink和Kafka實現實時Exactly-Once廣告事件處理?
優步最近推出了一項新功能:UberEats 上的廣告。這種新能力帶來了 Uber 需要解決的新挑戰,例如廣告拍賣、競標、歸因、報告等系統。本文重點介紹我們如何利用開源技術構建 Uber 的第一個“近實時”恰好一次事件處理系統。我們將深入瞭解我們如何實現一次性處理以及事件處理作業的內部工作原理的細節。
問題陳述:
對於每個投放的廣告,每個使用者都有相應的事件(展示次數、點選次數)。廣告事件處理系廣告系統)。
這需要一個針對以下方面進行最佳化的系統:
- 速度:
- 下游廣告系統(廣告節奏、預算更新)需要使用者生成的廣告事件的實時上下文才能履行其職責。
- 客戶將以最少的延遲看到他們的效能指標。
- 系統在資料完整性方面必須可靠。廣告事件代表支付給優步的實際資金。如果事件丟失,優步就會失去潛在收入。
- 我們必須能夠準確地向客戶展示廣告的效果。資料丟失會導致廣告成功率低報,從而導致客戶體驗不佳。
架構
為了滿足這些需求,我們設計了一個嚴重依賴 4 項關鍵開源技術的架構:Apache Flink 、Apache Kafka 、Apache Pinot 和 Apache Hive 。以下是選擇每種技術的原因。
- 使用 Apache Flink 進行流處理
該系統的核心構建塊使用Apache Flink,這是一種用於近實時處理無界資料的流處理框架。它具有非常適合廣告的豐富功能集,例如一次性保證、Kafka 聯結器(Uber 的選擇訊息佇列)、用於聚合的視窗函式,並且在 Uber 中得到了很好的整合和支援。
- 使用 Apache Kafka 的訊息佇列
Kafka 是 Uber 技術堆疊的基石:我們擁有世界上最大的 Kafka 部署之一,並且做了大量有趣的工作來確保它的效能和可靠性。Kafka 還可以提供一次性保證,並且可以很好地擴充套件到廣告用例。
- 使用 Apache Pinot 進行實時分析
廣告事件處理系統的主要目標之一是為我們的客戶快速提供效能分析:Apache Pinot 出現了。Pinot 是分散式、可擴充套件的線上分析處理 (OLAP) 資料儲存。它專為分析查詢的低延遲交付而設計,並支援透過 Kafka 進行近實時資料攝取。
- 使用 Apache Hive 的資料倉儲
Apache Hive是一個資料倉儲,它透過允許透過 SQL 查詢資料的豐富工具促進讀取、寫入和管理大型資料集。優步擁有透過 Kafka 的自動化資料攝取流,以及使 Hive 成為儲存資料的絕佳解決方案,供資料科學家用於報告和資料分析的內部工具。
恰好一次
如上所述,我們正在處理的一個主要約束是要求在整個系統中使用恰好一次語義。這是分散式系統中最困難的問題之一,但我們能夠透過多種努力來解決它。
首先,我們依靠 Flink 和 Kafka 中的一次性配置來確保透過 Flink 處理並沉入 Kafka 的任何訊息都是事務性地完成的。Flink 使用啟用了“read_committed”模式的 KafkaConsumer,它只會讀取事務性訊息。作為本部落格中討論的工作的直接結果,Uber 啟用了此功能。其次,我們為聚合作業生成的每條記錄生成唯一識別符號,下面將詳細介紹。識別符號用於下游消費者中的冪等性和重複資料刪除目的。
第一個 Flink 作業 Aggregation 使用來自 Kafka 的原始事件並按分鐘將它們聚合到桶中。這是透過將訊息的時間戳欄位截斷為一分鐘並將其與廣告識別符號一起用作複合鍵的一部分來完成的。在這一步,我們還為每個聚合結果生成一個隨機唯一識別符號(記錄 UUID)。
每分鐘滾動視窗都會觸發將聚合結果傳送到處於“未提交”狀態的 Kafka 接收器,直到下一個Flink 檢查點觸發。當下一個檢查點觸發時(每 2 分鐘),訊息將使用兩階段提交協議轉換為“已提交”狀態。這確保了儲存在檢查點中的 Kafka 讀取偏移量始終與提交的訊息一致。
Kafka 主題的使用者(例如,廣告預算服務和聯合與載入作業)被配置為僅讀取已提交的事件。這意味著所有可能由 Flink 故障引起的未提交事件都將被忽略。所以當 Flink 恢復時,它會再次重新處理它們,生成新的聚合結果,將它們提交給 Kafka,然後它們可供消費者處理。
記錄 UUID 用作廣告預算服務中的冪等鍵。對於 Hive,它用作重複資料刪除目的的識別符號。在 Pinot 中,我們利用 upsert 功能來確保我們永遠不會複製具有相同識別符號的記錄。
總結
在這篇部落格中,我們展示了我們如何利用開源技術(Flink、Kafka、Pinot 和 Hive)來構建滿足快速、可靠和準確系統要求的事件處理系統。我們討論了在分散式系統中確保完全一次語義的一些挑戰,並展示了我們如何透過生成冪等鍵和依賴 Pinot 的最新功能之一來實現這一點:Upsert。在撰寫這篇博文時,該系統每週處理數億個廣告事件,並且每天都在增加。
相關文章
- 實時資料處理:Kafka 和 FlinkKafka
- DoorDash使用 Kafka 和 Flink 構建可擴充套件的實時事件處理Kafka套件事件
- 使用Kafka和Flink構建實時資料處理系統Kafka
- Twitter如何升級Hadoop+Kafka架構實現實時處理數十億個事件?HadoopKafka架構事件
- Kafka如何實現實時流處理 Part 1 - André MeloKafka
- Apache Flink複雜事件處理指南 - softwaremillApache事件REM
- Flink Exactly-once 實現原理解析
- 使用Storm、Kafka和ElasticSearch處理實時資料 -javacodegeeksORMKafkaElasticsearchJava
- 使用Kafka實現事件溯源Kafka事件
- flink使用Event_time處理實時資料
- Apache Flink 如何正確處理實時計算場景中的亂序資料Apache
- 基於flink和drools的實時日誌處理
- 使用Apache Kafka實現從單體到事件驅動微服務 - swlhApacheKafka事件微服務
- Flink接入Kafka資料來源實現精準一次(Exactly-once)的注意點Kafka
- Spring Boot和Apache Kafka結合實現錯誤處理,訊息轉換和事務支援?Spring BootApacheKafka
- 三種大資料流處理框架選擇比較:Apache Kafka流、Apache Spark流和Apache Flink - quora大資料框架ApacheKafkaSpark
- 如何將Apache Druid,Flink和Cassandra用於實時流分析和使用者評分?ApacheUI
- 如何利用Redis實現延時處理Redis
- Flink基礎:實時處理管道與ETL
- Flink 如何通過2PC實現Exactly-once語義 (原始碼分析)原始碼
- Flink 是如何保證 Exactly-once 語義的?
- Kafka+Flink 實現準實時異常檢測系統Kafka
- Flink CDC 系列 - 實現 MySQL 資料實時寫入 Apache DorisMySqlApache
- 使用Flink SQL進行實時效能監控:AdTech廣告用例SQL
- 開源實時資料處理系統Pulsar:一套搞定Kafka+Flink+DBKafka
- 如何實現對 Oracle 的實時資料捕獲和效能調優|Flink CDC 專題Oracle
- Java如何使用實時流式計算處理?Java
- 優步分享基於Apache Kafka的Presto使用經驗ApacheKafkaREST
- Flink - CEP(複雜事件處理)事件
- Flink-Kafka-Connector Flink結合Kafka實戰Kafka
- BIGO 使用 Flink 做 OLAP 分析及實時數倉的實踐和優化Go優化
- Laravel 實現 Kafka 訊息推送與接收處理LaravelKafka
- 使用EventNext實現基於事件驅動的業務處理事件
- 優步是如何用Kafka構建可靠的重試處理保證資料不丟失Kafka
- 博文推薦|使用 Apache Pulsar 和 Scala 進行事件流處理Apache事件
- Flink CDC+Kafka 加速業務實時化Kafka
- Apache Flink 在移動雲實時計算的實踐Apache
- Flink處理函式實戰之四:視窗處理函式