資料對於IFTTT至關重要。我們的 BD 和營銷團隊依靠資料來做出關鍵的業務決策。產品團隊依靠資料來測試來了解使用者是如何時候我的產品的,以做產品決策。資料團隊本身依靠資料建立產品,比如Recipe推薦系統和垃圾郵件檢測工具。此外,我們的合作伙伴依靠資料來實時獲取Channels的效能。
因為資料對於IFTTT如此關鍵,並且我們的服務每天處理幾十億事件,所以我們的資料基礎設施必須具有高可擴充套件性、可用性的和彈性,以便跟上產品的快速迭代。在這篇文章中我們將帶你瀏覽資料基礎設施和架構,也會分享一些我們在構建和運算元據的收穫。
資料來源
在IFTTT有三種資料來源,對於理解使用者的行為和Channels的效率至關重要。
第一,在 AWS RDS 有一個 MySQL 叢集,用來維護應用的基本內容的當前狀態,比如使用者、Channels和Recipes,包括他們的關係。IFTTT.com 和移動應用靠 Rails 應用支撐。獲得資料並匯出到S3,每天用AWS Data Pipline匯入到Redshift。
接下來,像使用者與 IFTTT 產品的互動資料,我們從Rails應用裡收集事件資料到Kafka叢集。
最後,為了幫助監控數以千計的合作伙伴 API 的行為(behavior),我們收集在執行 Recipes 時 workers 產生的 API 請求的資訊,包括響應時間和HTTP狀態碼,都匯入到Kafka叢集。
IFTTT 的 Kafka
我們使用Kafka做資料傳輸層,實現資料生產者和消費者之間的解耦。這種架構中,Kafka在系統中作為生產者和消費者之間的一種抽象層,而不是資料直接推向消費者。生產者將資料推送到Kafka,消費者從Kafka中讀資料。這使得新增新資料消費者更鬆散。
因為Kafka作為基於日誌的事件流,因為消費者跟蹤他們自己在事件流中的位置。這使消費者資料能在兩種模式中切換:實時和批量。它還允許消費者資料進行重新處理他們以前所消耗的資料,如果在產生了錯誤的情況下資料需要重新處理,這將很有幫助。
一旦資料在Kafka中,我們將它用在各種位置。批量資料的消費者每小時將資料的一個副本分批放到 S3。實時資料的消費者將資料發到 Elasticsearch 叢集,用的 library 我們希望能儘快開源。
商業智慧
用Cranium(內部ETL平臺)將S3中資料變換和歸一化後匯入到AWS Redshift。Cranium使我們能夠用SQL和Ruby編寫ETL 任務(job),它定義了這些任務之間的依賴和安排他們執行。Cranium支援資料視覺化報告(利用Ruby和D3),但是大多數資料視覺化是用Chartio。我們發現對於SQL經驗有限的人來說Chartio非常直觀。
無論是工程中還是業務中甚至是社群中人們都可以利用這些資料來解決問題,發現新的點。
用 Chartio 做資料視覺化
機器學習
我們採用一些先進的機器學習技術來確保IFTTT使用者有良好的體驗。對於Recipe的推薦和濫用檢測,我們用在EC2上的執行Apache Spark,用S3作資料儲存。更多的內容我們將在之後的博文中解釋。
實時監控和報警
API 事件儲存在 Elasticsearch 中,來進行實時監控和報警。我們使用Kibana來視覺化worker程式的實時效能和合作夥伴的API效能。
IFTTT的合作伙伴訪問Developer Channel(當他們的API有問題時觸發這個Channel)。他們可以用Developer Channel 建立Recipes,可選擇不同的方式(SMS,Email,Slack,等)來通知合作伙伴們。
在開發者dashboard,合作伙伴可以訪問實時日誌和視覺化他們的Channel健康狀況。 用Elasticsearch來實現比較好。此外,提供給開發者強大的分析能力幫開發者們瞭解誰在使用他們的Channel以及如何使用的。
經驗
我們從開發資料基礎設施主中總結出一些經驗:
- 通過使用像Kafka這樣的資料傳輸層將生產者和消費者分離,使得資料管道更有彈性。比如,幾個慢點消費者不會影響其他消費者或生產者的效能。
- 從一天開始就以叢集的模式啟動,這使得你可以很容易地擴充套件。但是在擴充套件叢集前要確定效能瓶頸是什麼。比如,在 Elasticsearch 中如果shard非常大,新增更多節點並不會幫助提高查詢速度。你不得不減少shard。
- 在複雜系統中,要在一些地方給適當的報警,確保一切正常。我們用Sematext來監控Kafka叢集和消費者們。我們也用Pingdom來監控,用Pagerduty來報警。
- 為了能充分信任你的資料,自動驗證資料是非常重要的。比如我們開發了一個服務,來比較生產中的表和Redshift中的表,如果有異常將報警。
- 使用基於日期的資料夾結構 (YYYY/MM/DD)來將 event 資料持久化儲存(我們例子中的S3)。這方式儲存易於處理。比如如果你想讀某一天的資料,你只需要從一個目錄中讀取資料。
- 與上面類似的是,在Elasticsearch中建立基於時間的索引(例如:每小時)。如果在Elasticsearch中查詢最後一小時所有API錯誤,那麼利用簡單的索引就可以做到,提高效率。
- 要批量提交event(基於時間段或者大量事件)到Elasticsearch,而不是提交獨立的event。這有助於限制IO。
- 根據執行的資料和查詢的型別,來優化 Elasticsearch 的節點數、shard數、shard 和 replication factor 的最大值等引數。