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

作者:孫曉光 ,北京知乎軟件架構師。

來源:http://itindex.net/

知乎,在古文中意為“你知道嗎?”,它是中國的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毫秒或更短:即使對於執行時間最長的長尾查詢,也會發生這種情況。
  • 容忍誤報:這意味著系統可以為用戶調出許多有趣的帖子,即使有些帖子被錯誤地過濾掉了。

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

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

勘探

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

  • 代理:這會將用戶的請求轉發給可用節點,並確保系統的高可用性。
  • 緩存:這暫時處理內存中的請求,因此我們並不總是需要處理數據庫中的請求。這可以提高系統性能。
  • 存儲:在使用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數據庫。

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

圖1 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的主要功能

TiDB的主要功能包括:

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

我們是如何使用TiDB的

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

我們架構中的TiDB

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

  • 頂層:無狀態和可伸縮的客戶端API和代理。這些組件易於擴展。
  • 中間層:軟狀態組件和分層Redis緩存作為主要部分。當服務中斷時,這些組件可以通過恢復保存在TiDB群集中的數據來自我恢復服務。
  • 底層:TiDB集群存儲所有有狀態數據。它的組件高度可用,如果節點崩潰,它可以自我恢復其服務。
1.3萬億條數據查詢如何做到毫秒級響應?

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

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

TiDB的性能指標

由於我們在生產環境中應用了TiDB,因此我們的系統具有高可用性和易於擴展性,並且系統性能得到顯著改善。

例如,在2019年6月為Moneta應用程序採用一組性能指標:

在高峰時間每秒寫入40,000行數據。

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

每秒寫入的數據行(數千)

在高峰時段每秒檢查30,000個查詢和1200萬個帖子

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

每秒寫入的數據行(數千)

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

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

第99百分位響應時間

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

第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的期望

在Zhihu,反垃圾郵件和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相比的寫入和查詢延遲:

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

在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將變得更加強大和強大。


分享到:


相關文章: