1.3 萬億條數據查詢,如何做到毫秒級響應?

超全面!Java核心知識總結

超全面!Java核心知識總結

超全面!Java核心知識總結


知乎,在古典中文中意爲“你知道嗎?”,它是中國的 Quora,一個問答網站,其中各種問題由用戶社區創建,回答,編輯和組織。

作爲中國最大的知識共享平臺,我們目前擁有 2.2 億註冊用戶,3000 萬個問題,網站答案超過 1.3 億。

隨着用戶羣的增長,我們的應用程序的數據大小無法實現。我們的 Moneta 應用程序中存儲了大約 1.3 萬億行數據(存儲用戶已經閱讀過的帖子)。

由於每月累計產生大約 1000 億行數據且不斷增長,這一數字將在兩年內達到 3 萬億。在保持良好用戶體驗的同時,我們在擴展後端方面面臨嚴峻挑戰。

在這篇文章中,我將深入探討如何在如此大量的數據上保持毫秒級的查詢響應時間,以及 TiDB 是一個開源的 MySQL 兼容的 NewSQL 混合事務/分析處理( HTAP)數據庫,如何爲我們提供支持獲得對我們數據的實時洞察。

我將介紹爲什麼我們選擇 TiDB,我們如何使用它,我們學到了什麼,優秀實踐以及對未來的一些想法。 

我們的痛點


本節介紹了我們的 Moneta 應用程序的體系結構,我們嘗試構建的理想體系結構,以及數據庫可伸縮性作爲我們的主要難點。


系統架構要求

知乎的 Post Feed 服務是一個關鍵系統,用戶可以通過該系統接收網站上發佈的內容。

後端的 Moneta 應用程序存儲用戶已閱讀的帖子,並在知乎的推薦頁面的帖子流中過濾掉這些帖子。

Moneta 應用程序具有以下特徵:


  • 需要高可用性數據: Post Feed 是第一個出現的屏幕,它在推動用戶流量到知乎方面發揮着重要作用。
  • 處理巨大的寫入數據: 例如,在高峯時間每秒寫入超過 4 萬條記錄,記錄數量每天增加近 30 億條記錄。
  • 長期存儲歷史數據:目前,系統中存儲了大約 1.3 萬億條記錄。隨着每月累積約 1000 億條記錄並且不斷增長,歷史數據將在大約兩年內達到 3 萬億條記錄。
  • 處理高吞吐量查詢: 在高峯時間,系統處理平均每秒在 1200 萬個帖子上執行的查詢。
  • 將查詢的響應時間限制爲 90 毫秒或更短: 即使對於執行時間最長的長尾查詢,也會發生這種情況。
  • 容忍誤報: 這意味着系統可以爲用戶調出許多有趣的帖子,即使有些帖子被錯誤地過濾掉了。

考慮到上述事實,我們需要一個具有以下功能的應用程序架構:


  • 高可用性: 當用戶打開知乎的推薦頁面時,找到大量已經閱讀過的帖子是一種糟糕的用戶體驗。
  • 出色的系統性能: 我們的應用具有高吞吐量和嚴格的響應時間要求。
  • 易於擴展: 隨着業務的發展和應用程序的發展,我們希望我們的系統可以輕鬆擴展。

勘探

爲了構建具有上述功能的理想架構,我們在之前的架構中集成了三個關鍵組件:


  • 代理: 這會將用戶的請求轉發給可用節點,並確保系統的高可用性。
  • 緩存: 這暫時處理內存中的請求,因此我們並不總是需要處理數據庫中的請求。這可以提高系統性能。
  • 存儲: 在使用 TiDB 之前,我們在獨立的 MySQL 上管理我們的業務數據。隨着數據量的激增,獨立的 MySQL 系統還不夠。
    然後我們採用了 MySQL 分片和 Master High Availability Manager( MHA)的解決方案,但是當每月有 1000 億條新記錄湧入我們的數據庫時,這個解決方案是不可取的。

MySQL Sharding 和 MHA 的缺點

MySQL 分片和 MHA 不是一個好的解決方案,因爲 MySQL 分片和 MHA 都有它們的缺點。


MySQL 分片的缺點:

  • 應用程序代碼變得複雜且難以維護。
  • 更改現有的分片鍵很麻煩。
  • 升級應用程序邏輯會影響應用程序的可用性。

MHA 的缺點:

  • 我們需要通過編寫腳本或使用第三方工具來實現虛擬 IP(VIP)配置。
  • MHA 僅監視主數據庫。
  • 要配置 MHA,我們需要配置無密碼安全 Shell( SSH)。這可能會導致潛在的安全風險。
  • MHA 不爲從屬服務器提供讀取負載平衡功能。
  • MHA 只能監視主服務器(而不是從主服務器)是否可用。

在我們發現 TiDB 並將數據從 MySQL 遷移到 TiDB 之前,數據庫可伸縮性仍然是整個系統的弱點。

什麼是 TiDB?


TiDB 平臺是一組組件,當它們一起使用時,它們將成爲具有 HTAP 功能的 NewSQL 數據庫。
TiDB 平臺架構

在 TiDB 平臺內部,主要組件如下:


  • TiDB 服務器是一個無狀態的 SQL 層,它處理用戶的 SQL 查詢,訪問存儲層中的數據,並將相應的結果返回給應用程序。它與 MySQL 兼容並且位於 TiKV 之上。
  • TiKV 服務器是數據持久存在的分佈式事務鍵值存儲層。它使用 Raft 共識協議進行復制,以確保強大的數據一致性和高可用性。
  • TiSpark 集羣也位於 TiKV 之上。它是一個 Apache Spark 插件,可與 TiDB 平臺配合使用,支持商業智能(BI)分析師和數據科學家的複雜在線分析處理(OLAP)查詢。
  • 放置驅動程序(PD)服務器是由 etcd 支持的元數據集羣,用於管理和調度 TiKV。



除了這些主要組件之外,TiDB 還擁有一個工具生態系統,例如用於快速部署的  Ansible 腳本,用於從 MySQL 遷移的 Syncer 和 TiDB 數據遷移。

以及用於收集對 TiDB 羣集進行的邏輯更改並提供增量備份的 TiDB Binlog。複製到下游(TiDB,Kafka 或 MySQL)。

TiDB 的主要功能包括:


  • 水平可擴展性。
  • MySQL 兼容的語法。
  • 具有強一致性的分佈式事務。
  • 雲原生架構。
  • 使用 HTAP 進行最小提取,轉換,加載( ETL)。
  • 容錯和 Raft 恢復。
  • 在線架構更改。

我們如何使用 TiDB


在本節中,我將向您展示如何在 Moneta 的架構中運行 TiDB 以及 Moneta 應用程序的性能指標。

我們架構中的 TiDB


知乎的 Moneta 應用程序中的 TiDB 架構

我們在系統中部署了 TiDB,Moneta 應用程序的整體架構變爲:



在該系統中,所有組件都是可自我恢復的,整個系統具有全局故障監視機制。然後,我們使用 Kubernetes 來協調整個系統,以確保整個服務的高可用性。


TiDB 的性能指標

由於我們在生產環境中應用了 TiDB,因此我們的系統具有高可用性和易於擴展性,並且系統性能得到顯著改善。例如,在 2019 年 6 月爲 Moneta 應用程序採用一組性能指標。

在高峯時間每秒寫入 40,000 行數據:
每秒寫入的數據行(數千)

在高峯時段每秒檢查 30,000 個查詢和 1200 萬個帖子:
每秒寫入的數據行(數千)

第 99 百分位響應時間約爲 25 毫秒,第 999 百分位響應時間約爲 50 毫秒。實際上,平均響應時間遠遠小於這些數字,即使對於需要穩定響應時間的長尾查詢也是如此。
第 99 百分位響應時間
第 999 百分位響應時間

我們學到了什麼


我們遷移到 TiDB 並非順利,在這裏,我們想分享一些經驗教訓。

更快地導入數據
我們使用 TiDB 數據遷移(DM)來收集 MySQL 增量 Binlog 文件,然後使用 TiDB Lightning 將數據快速導入 TiDB 集羣。

令我們驚訝的是,將這 1.1 萬億條記錄導入 TiDB 只用了四天時間。如果我們邏輯地將數據寫入系統,可能需要一個月或更長時間。如果我們有更多的硬件資源,我們可以更快地導入數據。

減少查詢延遲

完成遷移後,我們測試了少量的讀取流量。當 Moneta 應用程序首次上線時,我們發現查詢延遲不符合我們的要求。爲解決延遲問題,我們與 PingCap 工程師合作調整系統性能。

在此過程中,我們積累了寶貴的數據和數據處理知識:


  • 有些查詢對查詢延遲很敏感,有些則不然。我們部署了一個單獨的 TiDB 數據庫來處理對延遲敏感的查詢。(其他非延遲敏感的查詢在不同的 TiDB 數據庫中處理。)
    這樣,大型查詢和對延遲敏感的查詢在不同的數據庫中處理,前者的執行不會影響後者。
  • 對於沒有理想執行計劃的查詢,我們編寫了 SQL 提示來幫助執行引擎選擇最佳執行計劃。
  • 我們使用低精度時間戳 Oracle( TSO)和預處理語句來減少網絡往返。

評估資源
在我們嘗試 TiDB 之前,我們沒有分析我們需要多少硬件資源來支持 MySQL 端的相同數據量。

爲了降低維護成本,我們在單主機 - 單從機拓撲中部署了 MySQL。相反,在 TiDB 中實現的 Raft 協議至少需要三個副本。

因此,我們需要更多的硬件資源來支持 TiDB 中的業務數據,我們需要提前準備機器資源。

一旦我們的數據中心設置正確,我們就可以快速完成對 TiDB 的評估。

對 TiDB 3.0 的期望


在知乎,反垃圾郵件和 Moneta 應用程序的架構相同。我們在用於生產數據的反垃圾郵件應用程序中嘗試了 TiDB 3.0(TiDB 3.0.0-rc.1 和 TiDB 3.0.0-rc.2)的候選版本中的 Titan 和 Table Partition。 

①Titan 縮短了延遲

反垃圾郵件應用程序一直受到嚴重的查詢和寫入延遲折磨。

我們聽說 TiDB 3.0 將引入 Titan,一種鍵值存儲引擎,用於在使用大值時減少  RocksDB(TiKV 中的底層存儲引擎)的寫入放大。 爲了嘗試這個功能,我們在 TiDB 3.0.0-rc.2 發佈後啓用了 Titan。

下圖分別顯示了與 RocksDB 和 Titan 相比的寫入和查詢延遲:
在 RocksDB 和 Titan 中編寫和查詢延遲

統計數據顯示,在我們啓用 Titan 後,寫入和查詢延遲都急劇下降。這真是太驚人了!當我們看到統計數據時,我們無法相信自己的眼睛。

②表分區改進了查詢性能

我們還在反垃圾郵件應用程序中使用了 TiDB 3.0 的表分區功能。使用此功能,我們可以按時將表分成多個分區。

當查詢到來時,它將在覆蓋目標時間範圍的分區上執行。這大大提高了我們的查詢性能。

讓我們考慮一下如果我們將來在 Moneta 和反垃圾郵件應用程序中實施 TiDB 3.0 會發生什麼。

③Moneta 應用程序中的 TiDB 3.0

TiDB 3.0 具有諸如 gRPC 中的批處理消息,多線程 Raftstore,SQL 計劃管理和 TiFlash 等功能。我們相信這些將爲 Moneta 應用增添光彩。


④gRPC 和多線程 Raftstore 中的批處理消息


Moneta 的寫入吞吐量超過每秒 4 萬次交易(TPS),TiDB 3.0 可以批量發送和接收 Raft 消息,並且可以在多個線程中處理 Region Raft 邏輯。我們相信這些功能將顯著提高我們系統的併發能力


⑤SQL 計劃管理


如上所述,我們編寫了大量 SQL 提示,以使查詢優化器選擇最佳執行計劃。

TiDB 3.0 添加了一個 SQL 計劃管理功能,可以直接在 TiDB 服務器中將查詢綁定到特定的執行計劃。使用此功能,我們不需要修改查詢文本以注入提示。


⑥TiFlash


在 TiDB DevCon 2019 上,我第一次聽說 TiFlash 是 TiDB 的擴展分析引擎。

它使用面向列的存儲技術來實現高數據壓縮率,並在數據複製中應用擴展的 Raft 一致性算法以確保數據安全性。

由於我們擁有高寫入吞吐量的海量數據,因此我們無法每天使用 ETL 將數據複製到 Hadoop 進行分析。但是對於 TiFlash,我們樂觀地認爲我們可以輕鬆分析我們龐大的數據量。


⑦反垃圾郵件應用程序中的 TiDB 3.0


與 Moneta 應用程序的巨大歷史數據大小相比,反垃圾郵件應用程序具有更高的寫入吞吐量。

但是,它僅查詢過去 48 小時內存儲的數據。在此應用程序中,數據每天增加 80 億條記錄和 1.5 TB。

由於 TiDB 3.0 可以批量發送和接收 Raft 消息,並且它可以在多個線程中處理 Region Raft 邏輯,因此我們可以用更少的節點管理應用程序。

以前,我們使用了七個物理節點,但現在我們只需要五個。即使我們使用商用硬件,這些功能也可提升性能。

下一步是什麼


TiDB 是一個與 MySQL 兼容的數據庫,因此我們可以像使用 MySQL 一樣使用它。

由於 TiDB 的橫向可擴展性,現在我們可以自由擴展我們的數據庫,即使我們有超過一萬億的記錄來應對。 

到目前爲止,我們已經在我們的應用程序中使用了相當多的開源軟件。我們還學到了很多關於使用 TiDB 處理系統問題的知識。

我們決定參與開發開源工具,並參與社區的長期發展。基於我們與 PingCAP 的共同努力,TiDB 將變得更加強大。
本文來源:http://itindex.net

   
   
   
           
              
              
              
題外話: 推薦一個GitHub項目 ,這個 GitHub 整理了上百本常用技術PDF,絕大部分核心的技術書籍都可以在這裏找到,GitHub地址:https://github.com/gsjqwyl/awesome-ebook(電腦打開體驗更好),地址閱讀原文直達。麻煩打個給個Star,持續更新中...


---END---

文末福利


本文分享自微信公衆號 - Java專欄(finishbug)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章