這篇文章簡單介紹了 Facebook 的資較庫技術的選用,我們從公開資料中,大致整理了 Facebook 內部資料庫結構的技術分配。由於大家都知道,早期 Facebook 就是用 MySQL 起家的,因此在經過這麼多年發展後,到底 MySQL 還承載了哪方面的應用?有哪些功能已經轉移到 NoSQL 或其他儲存上面呢?接下來讓夏格飛一一介紹吧。
Facebook 如何善用 MySQL
由於歷史的因素,Facebook 在其大規模基礎設施中廣泛使用 MySQL,較難更換資料。因此 Facebook 針對其需求進行了多項優化和定制,以下是 Facebook 如何使用 MySQL 的幾個策略:
開發 MyRocks 引擎
為了提升儲存效率和性能,Facebook 開發了 MyRocks,這是一個基於 RocksDB 的 MySQL 儲存引擎。MyRocks 旨在提供更好的空間和寫入效率,特別適合高寫入密集型的工作負載。與 InnoDB 相比,MyRocks 提供了更高的壓縮率和寫入性能,這對於需要高效處理大量數據的應用場景非常有利。
多實例架構與資源利用
Facebook 採用每台機器運行多個 MySQL 實例的模型,每個實例包含多個資料庫。這種架構沒有對實例之間進行資源隔離,目的是讓每個實例都能發揮最大性能。這種方法提高了硬體資源的利用率,適應了 Facebook 大規模、高性能的需求。
高可用性與自動化運維
為了確保高可用性,Facebook 採用基於 GTID(全局事務標識)的主從架構,並實現了自動選主機制。他們還開發了內部的 Online Schema Change 工具,以支持線上 DDL 操作,確保在不影響線上業務的情況下進行資料庫模式變更。此外,Facebook 的資料庫維護高度自動化,利用內部開發的平台來管理大量的 MySQL 實例。
備份策略與工具改進
在備份方面,Facebook 修改並增強了 XtraBackup 工具,以滿足其大規模資料庫的需求。他們實現了表級還原、調整全量和增量備份,以及支持混合增量備份等功能。這些改進使得備份過程更高效,並減少了對線上業務的影響。
升級到 MySQL 8.0
為了利用 MySQL 的新特性,Facebook 將其 MySQL 基礎設施從 5.6 升級到 8.0。這次升級涉及將超過 1500 個內部 patch 移植到新版本,並解決了複製兼容性、API 變更等挑戰。升級到 8.0 為 Facebook 帶來了如基於寫入集合的並行複製和事務性資料字典等新功能,進一步提升了資料庫的性能和可擴展性。
MySQL 用來儲存哪些資料?
Facebook 的 MySQL 主要用來儲存結構化數據與關鍵業務數據,而不是全文搜尋或大規模分析數據。具體來講,與帳戶、財務收款、商業業務相關的資料,都是用 MySQL 儲存的,例如:
用戶資料(User Data)
帳戶資訊(如用戶 ID、名稱、電子郵件、密碼哈希等)
個人設定(如語言偏好、隱私設定等)
朋友關係(好友列表、關係鏈接)
為什麼用 MySQL?
這些數據需要強一致性(ACID 事務)
查詢主要基於用戶 ID(Primary Key 查詢快)
關聯性高,例如朋友關係(用戶與用戶之間的關係)
互動狀況(Social Interactions)
好友關係(Friendship Graph)
按讚(Likes)
分享記錄(Shares)
留言(Comments)
通知(Notifications)
為什麼用 MySQL?
這些數據量很大,但大部分是基於 單個用戶 ID 的查詢
需要快速讀取(例如載入用戶的讚過的貼文)
這些記錄有關聯(例如「某用戶讚了哪篇貼文」)
廣告與商業資料(Ads & Business Data)
廣告投放記錄
廣告用戶設定
企業帳戶資訊
廣告競價數據(Bidding)
為什麼用 MySQL?
關聯性強,如「這則廣告是由哪個企業發佈的?」
交易性強,廣告競價需要高可靠性與一致性
適合 OLTP(線上事務處理)
內部工具與管理平台
開發者 API 相關數據
系統日誌(部分)
運營管理數據
內容審查與政策違規記錄
為什麼用 MySQL?
這些數據量比社交數據小,但查詢頻繁
交易性需求高(例如一條審查記錄不能錯誤刪除)
可以看見在相對傳統的商業邏輯部分,由於 ACID 需求高,依然大量使用 MySQL 承載關鍵業務資料,例如用戶數據、互動記錄、廣告數據等。但不會用來存照片、影片、聊天訊息或搜尋索引,因為這些數據的特性更適合 NoSQL 或分散式儲存。
使用非 MySQL 的部份有哪些?
對於 大規模數據、非結構化內容、即時高併發應用,Facebook 則選擇 NoSQL 或分散式儲存技術。
貼文(Posts)
HBase(類似 BigTable) → 貼文資料
TAO(Facebook 自研的圖數據庫) → 管理貼文的關聯(誰發布、誰按讚)
Facebook 每天有 數十億條貼文,寫入量巨大,且存取模式是 讀多寫多。MySQL 雖能支援分區,但在處理超大數據量的讀取時,效率不如 NoSQL。
照片與影片(Photos & Videos)
Haystack(Facebook 內部開發的高效存儲系統) → 儲存照片的 metadata
f4 分散式存儲系統 → 儲存影片與大規模二進制文件
CDN(內容分發網絡) → 加速用戶存取媒體文件,早期使用 Akamai,目前可能轉往其他方案了。
Facebook 每天上傳數億張照片和影片,這些 二進制大文件(BLOBs) 會直接使用檔案系統保存。
即時訊息(Messenger / WhatsApp / Instagram Chat)
Apache Cassandra(高可用、無中心、支援水平擴展) → 儲存聊天訊息
RocksDB(Facebook 優化的嵌入式存儲引擎) → 提供更快的訊息讀寫
即時訊息有極高併發需求(每秒數百萬條訊息),MySQL 寫入鎖機制會成為瓶頸。
搜尋索引(Facebook Search & Graph Search)
Elasticsearch → 儲存搜尋索引
Facebook 自研的 AI 搜尋模型 → 提供更精確的搜尋結果
TAO(Facebook 圖數據庫) → 進行 Graph Search(社交網絡關聯查詢)
全文檢索(Full-text search) 在 MySQL 效能較差,且不支援語意分析、模糊匹配等功能。
反詐欺與風險分析(Fraud Detection & Risk Analysis)
Presto(分散式 SQL 查詢引擎) → 即時分析大數據
Apache Hive(基於 Hadoop 的數據倉庫) → 儲存歷史數據,進行批量分析
AI/機器學習系統 → 訓練反詐欺模型
詐欺分析需要 快速數據掃描(數據量大),MySQL 在 大規模 OLAP 分析 上表現不佳。
廣告投放數據(Ads & Analytics Data)
Scuba(Facebook 內部的 OLAP 查詢系統) → 內部即時分析
Apache Druid(分佈式時序數據庫) → 分析廣告點擊數據
Presto → OLAP 分析廣告數據
廣告投放涉及即時競價(Real-time Bidding, RTB),需要 低延遲讀取。分析數據量極大,超過 數十 PB 級別,不適合傳統關聯式資料庫。
伺服器日誌與監控數據(Server Logs & Monitoring)
Scribe(Facebook 內部開發的日誌系統) → 收集日誌
Apache Kafka → 處理流式數據
Hadoop HDFS → 長期存儲伺服器日誌
Grafana + Prometheus → 監控伺服器效能
日誌數據寫入量極大,通常為 非結構化 JSON / Key-Value,MySQL 索引負擔過大。
AI / 機器學習數據(AI & ML Data)
PyTorch(Facebook 開發的深度學習框架)
FAISS(Facebook AI 相似性搜尋庫) → 用於圖像搜尋
Apache Spark → 大數據預處理
AI 訓練數據通常是非結構化的圖片、影片、音訊、文本,MySQL 不適合處理這類型的數據。
結論:MySQL 的應用領域依然廣泛
不只 Facebook,Pinterest、Uber 其實都是 MySQL 的重度使用者。當然他們也都根據自身的需求,額外客製化了 MySQL 的引擎或原始碼。但我們可以得知,MySQL 作為傳統 RDBMS ,其 ACID 特性依然很適合用在企業的商業業務資料儲存上。而 Facebook 轉用 NoSQL 的部份,較偏向是貼文或訊息等,不需要結構化查詢的項目。
雖然我們知道 MySQL 在超巨量資料時表現沒那麼好,但對多數公司來說,企業業務合作資料通常也都是在「千萬」或「億」級別以內的資料量,MySQL 處理這種資料量其實還是很輕鬆的。對許多創業家來說,時間分秒必爭,選用成熟好掌握的技術依然是優先考量的方向。
參考資料: