美國大選期間,Urban Airship如何將系統擴展至發送25億個通知的規模?
譯文【51CTO.com快譯】近來,Urban Airship受到期望與移動技術一同增長的成千上萬家公司的信賴。Urban Airship是一家成立七年的SaaS公司,它采用了一種免費增值的商業模式。
Urban Airship現在每天發送的推送通知平均超過10億個。本文介紹了2016年美國大選期間Urban Airship的通知使用情況,探討其Core Delivery Pipeline系統架構,該系統為新聞媒體發送了數十億的實時通知。
2016年美國大選
在選舉日前后的24小時內,Urban Airship發送了25億個通知――這是其迄今為止***日發送量。這相當于美國每人收到8個通知或世界上每部活躍智能手機收到1個通知。雖然Urban Airship支持45000多個應用程序,覆蓋每個行業垂直領域,但是分析選舉使用數據后顯示,400多個媒體應用程序在這創記錄的發送量中占到了60%,大家在跟蹤報告選舉結果時,它在單單一天內就發送了15億個通知。
總統選舉結束時,通知量趨于穩定,并達到峰值。
Urban Airship API的HTTPS入站流量在選舉期間達到每秒近75K的峰值。大部分流量來自與Urban Airship API通信的Urban Airship軟件開發工具包(SDK)。
推送通知量一直在快速增長。最近的主要驅動因素是英國退歐、奧運會和美國大選。2016年10月的月通知量同比猛增了150%。
Core Delivery Pipeline 架構解密
Core Delivery Pipeline(CDP)是Urban Airship的核心系統,負責利用audience selector工具來確定設備地址,并發送通知。其發送的所有通知都要做到低延遲,無論它們同時推送到數千萬用戶,發送給多個復雜的子群,含有個性化內容,還是其他什么。下面概述了這套系統的架構以及該公司汲取的若干經驗。
他們是如何開始入手的
2009 年,CDP最初只是一個Web應用程序,一些worker模塊轉變成了面向服務的架構(SOA)。由于舊系統的一些部分開始遇到規模問題后,我們將它們提取為一個或多個新服務,這些服務旨在提供同樣的功能集,但是支持更大的規模,并擁有更好的性能。我們的許多原始API和worker是用Python編寫的,將它們提取為高并發的Java服務。最初,是將設備數據存儲在一組Postgres數據庫分片中,但公司規模的增長速度超過了添加新數據庫分片的能力,于是系統遷移到了使用HBase和Cassandra的多數據庫架構。
CDP 是一系列負責處理分段和推送通知的服務。這些服務提供了響應請求的同一種類型的數據,但出于性能原因,每個服務都以全然不同的方式索引該數據。比如,我們有一個系統負責處理廣播消息,將同樣的通知內容推送到已向相關應用程序注冊的每個設備。該服務及底層的數據存儲區其設計方式與我們擁有的,負責基于位置或用戶概況屬性來發送通知的服務全然不同。
我們把任何長時間運行的進程都看作服務。這些長時間運行的進程密切關注一個通用模板,涉及度量指標、配置和日志,以便易于部署和操作。通常,我們的服務屬于RPC服務或消費者服務這兩個組中的一個。RPC服務提供這些使用內部庫與服務同步交互的命令,非常類似GRPC,而消費者服務處理來自Kafka數據流的消息,并對那些消息執行針對特定服務的操作。
數據庫
為了滿足我們的性能和規模要求,我們高度依賴HBase和Cassandra以滿足數據存儲要求。雖然HBase和Cassandra都是列式NoSQL存儲庫系統,但是它們有著全然不同的取舍,影響著我們使用哪種存儲系統、派什么用場。
HBase非常擅長高吞吐量掃描,響應的預期基數(cardinality)非常高,而Cassandra擅長較低基數的查詢,預計響應只含有少數結果。兩者都允許大量的寫入吞吐量,這是我們的一個要求,因為來自用戶手機的所有元數據更新都是實時的。
它們的故障特點也不一樣。一旦遇到失敗,HBase傾向于一致性和分區容錯性,而Cassandra傾向于可用性和分區容錯性。每個CDP服務都有非常具體的使用場合,因此有一種非常專用的數據庫模式(schema),旨在便于所需的訪問模式以及限制存儲占用空間。一般說來,每個數據庫僅由單個服務來訪問,該服務負責通過一個不大專用的接口,滿足數據庫訪問其他服務的要求。
服務及其后端數據庫之間實現這種1:1的關系有許多優點:
·通過將服務的后端數據存儲區當作一個實現細節,而不是共享資源,我們獲得了靈活性。
·我們只要改變服務的代碼,就可以調整該服務的數據模型。
·使用情況跟蹤起來更簡單直觀,因而容量規劃來得更容易。
·故障排除更容易。有時問題出在服務代碼上,有時問題出在后端數據庫上。讓服務和數據庫成為一個邏輯單元極大地簡化了故障排除過程。我們沒必要搞清楚“還有誰可以訪問這個數據庫,讓它以這種方式來運行?”相反,我們可以依賴來自服務本身的應用程序層度量指標,只要為一組訪問模式操心。
·由于只有一個服務與數據庫交互,我們可以執行幾乎所有的維護活動,而不會停機。繁重的維護任務成為服務級別問題:數據修復、數據庫模式遷移甚至改用完全不同的數據庫,這些都可以在不中斷服務的前提下執行。
誠然,我們將應用程序分解為較小的服務時,性能方面可能會有一些下降。然而我們發現,我們可靈活地滿足高擴展性和高可用性方面的要求,性能下降一點也是完全值得的。
數據建模
我們的服務大多數處理同樣的數據,只是它們使用不同的格式。一切都要保持一致性。為了保持所有這些服務的數據更新,我們高度依賴Kafka。Kafka速度極快,也很牢靠。速度快帶來了某些缺點。只可保證Kafka消息至少發送一次,但不可保證它們按順序到達。
我們如何處理這個問題呢?我們將所有可變路徑建模為可交換的:操作可以按任何順序來進行,***獲得同樣的結果。它們也是冪等的。這有一個很好的附帶影響:我們可以重放Kafka數據流,進行一次性的數據修復工作、回填甚至遷移。
為此,我們充分利用了“單元版本”概念,HBase和Cassandra中都有這個概念。它通常是一個時間戳,但也可以是你喜歡的任何數字(有一些例外;比如MAX_LONG會導致一些奇怪的行為,這取決于HBase或Cassandra的版本以及你的數據庫模式如何處理刪除)。
對我們來說,這些單元的一般規則是,它們可以有多個版本,我們按照提供的時間戳對版本進行排序。考慮到這種行為,我們可以將入站消息分解為一組特定的列,并將該布局與自定義的應用程序邏輯合并起來,用于邏輯刪除,并考慮到了時間戳。這樣就可以對底層數據存儲區進行盲寫,同時保持數據的完整性。
將變化的部分盲寫到Cassandra和HBase并非沒有問題。一個典型例子就是在重放的情況下,重復寫入同樣數據。雖然由于我們努力確保記錄具有冪等性,數據狀態因而不會改變,但是重復數據必須壓縮去掉。在最極端的情況下,這些額外記錄可能導致顯著的壓縮延遲和備份。由于這個細節,我們密切關注壓縮時間和隊列深度,因為在 Cassandra和HBase中,壓縮操作都會導致嚴重問題。
通過確保來自數據流的消息遵循一系列嚴格的規則,并且設計的消費服務能夠處理無序和重復的消息,我們就可以確保大量的異步服務同步,更新時只有一兩秒的滯后。
服務設計
我們的大多數服務是用Java編寫的,但采用了一種非常獨特而現代的風格。我們在設計Java服務時考慮到了一系列基本的指導原則:
·只做一件事,并且把它做好――設計服務時,它應該只有一項責任。實施者決定這是什么樣的責任,但是她或他需要準備好在代碼審查時予以說明。
·沒有共享操作狀態――設計服務時,假設總是至少有三個實例在運行。服務需要能夠處理其他任何實例能夠處理的同一個請求,沒有任何外部協調。熟悉Kafka的那些人會特別指出,Kafka消費者從外部協調topic:group對的分區所有權。這個指導原則面向針對特定服務的外部協調,而不是利用可能從外部協調的庫或客戶端。
·限制隊列――我們在所有服務中使用隊列,這是分批處理請求的好方法。所有隊列都應該有限制。不過,限制隊列確實帶來了許多問題:
△隊列滿時生產者會發生什么?它們會阻塞嗎?例外處理?還是丟棄?
△我的隊列應該多大?要回答這個問題,假設隊列總是滿的有所幫助。
△如何干凈地關閉隊列?
△針對這些問題,每個服務會給出不同的答案,這取決于具體的使用場合。
·命名自定義線程池,并注冊UncaughtExceptionHandler――如果我們***創建自己的線程池,我們使用來自Executors的構造函數或幫助方法,讓我們得以提供ThreadFactory。有了這個ThreadFactory,我們就可以正確命名線程,設置守護進程狀態,并注冊UncaughtExceptionHandler來處理異常讓它進入到堆棧頂部的情況。這些措施將大大簡化服務的調試,并且讓我們不必在深夜備感沮喪。
·青睞不可變數據對象,而不是可變狀態――在高度并發環境中,可變狀態可能很危險。一般來說,我們使用可以在內部子系統和隊列之間傳遞的不可變數據對象。讓不可變對象成為子系統之間的主要通信形式,這樣一來,為并發使用進行設計要直觀簡單得多,還讓故障排除更容易。
下一步何去何從?
由于Urban Airship能夠通過移動錢包passes發送通知,新增對Web通知和蘋果新聞通知的支持,及其開放頻道能夠將通知發送到任何平臺、設備或營銷渠道,我們預計通知推送量會呈指數增長。為了滿足這種需求,我們繼續大力投資于Core Delivery Pipeline架構、服務、數據庫和基礎設施。
原文標題:How Urban Airship Scaled To 2.5 Billion Notifications During The U.S. Election,作者:Todd Hoff
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】