做優化的資料庫工程師請參考!CynosDB的計算層設計優化揭秘

来源:https://www.cnblogs.com/qcloud1001/archive/2018/12/20/10148358.html
-Advertisement-
Play Games

本文由雲+社區發表 本文作者:孫旭,騰訊資料庫開發工程師,9年資料庫內核開發經驗;熟悉資料庫查詢處理,併發控制,日誌以及存儲系統;熟悉PostgreSQL(Greenplum,PGXC等)、Teradata等資料庫內核實現機制。 CynosDB 是騰訊資料庫研發團隊推出的自研資料庫,有Postgre ...


本文由雲+社區發表

本文作者:孫旭,騰訊資料庫開發工程師,9年資料庫內核開發經驗;熟悉資料庫查詢處理,併發控制,日誌以及存儲系統;熟悉PostgreSQL(Greenplum,PGXC等)、Teradata等資料庫內核實現機制。

CynosDB 是騰訊資料庫研發團隊推出的自研資料庫,有PostgreSQL和MySQL兩個版本。本文以相容PostgreSQL版CynosDB為例,介紹我們的架構設計和優化思路。

1、概述

PostgreSQL是世界上最先進的開源資料庫,始於1986年,有30多年的社區演進歷史。其先進的架構、可靠性以及豐富的功能已經獲得業界高度認可。同時,PostgreSQL能夠在多種操作系統上運行,支持多種索引類型和擴展,特別是對PostGIS擴展的支持,可以讓PostgreSQL輕鬆的處理地理信息數據。

相容PostgreSQL版CynosDB作為PostgreSQL在NewSQL領域的一個產品,也具有良好的擴展性。由其架構特點帶來的資源池化,可以讓用戶付出更少的成本而獲得同等的性能,並且不損失PostgreSQL資料庫原有的功能特性。

2、基礎架構

現有共有雲上的資料庫存在一些不足:

1.網路IO重。傳統雲上的主備架構下,會有大量數據需要寫到磁碟,主要包括:WAL LOG、臟頁數據、防止頁部分寫的Double Write或者Full Page Write。

2.主從實例不共用數據。一方面浪費了大量存儲,另一方面進一步加重了網路IO。這樣會導致磁碟利用率低、CPU閑置等問題。

而CynosDB可以通過日誌下沉、共用存儲來解決上述問題,以實現共有雲資料庫的高性價比、高可用性以及彈性擴展。其基礎架構如下:

img

架構中的組件:

\1. master是資料庫的主實例,負責接收應用的讀寫事務請求。

\2. slave是資料庫的只讀實例,負責處理應用的讀請求,可以支持多個slave實例。

\3. CynosStore Client提供訪問分散式存儲(CynosStore)的介面。DB引擎通過這些介面訪問存儲,完成數據文件的讀寫等操作。

\4. CynosStore是一個分散式存儲系統,存放資料庫的數據和日誌,並負責日誌到數據頁面的轉換。

\4. 集群管理服務負責整個系統的管理,例如:存儲擴容,實例創建等。

\5. 冷備存儲用來存儲系統的日誌。

master實例將數據的變更以日誌方式發送到存儲系統(CynosStore)中,同時CynosStore會定期將日誌合併到數據頁面上。因此,CynosDB無需將臟頁寫入到存儲中,這點與傳統資料庫是不同的。slave資料庫實例沒有寫事務,不會向存儲發送日誌,但是會從存儲中讀取頁面,也會接收master實例的日誌來刷新記憶體中的數據頁面;如果收到的日誌所對應的頁面沒有在slave的記憶體中,則會丟棄這些日誌。

從架構上看,CynosDB實現了存儲和計算分離,並把資源進行池化,因此適合雲上部署。而且計算和存儲傳輸數據的僅有日誌流,無需寫臟頁面,因此也減少了系統中的網路量。總的來說,CynosDB具有如下優勢:

1.計算能力彈性擴展。可以快速增加slave節點來擴展讀能力,而不必進行全量的數據拷貝。

\2. 存儲能力彈性擴展。不像傳統資料庫那樣受單機存儲能力的限制。

\3. 充分利用硬體資源。緩解傳統主備架構中的CPU閑置、磁碟利用率不高等問題。

\4. 備份容易。備份完全由後臺持續進行,用戶無需干預。

3、相容PostgreSQL版CynosDB的計算層架構

CynosDB實現了計算與存儲分離,系統也因此被分成兩大塊:計算層和存儲層。計算層負責SQL解析、日誌生成等;存儲層負責數據存儲、日誌歸檔以及日誌合併等。本節以CynosDB的PostgreSQL相容版本為例來介紹計算層架構。其計算層架構如下圖所示。為了實現這種NewSQL架構,我們對PostgreSQL內核做了新設計:

img

灰色部分是PostgreSQL內核原生模塊:

\1. SQL:PostgreSQL的SQL引擎,包括詞法/語法分析、語義分析、查詢重寫/優化和查詢執行。CynosDB的設計不涉及SQL層改動,因此它相容PostgreSQL原來的SQL語法和語義。

\2. Access:資料庫的訪問層,定義了對象的組織方式和訪問方法。其中包括:

lHeap:表實現以及訪問方法,包括掃描、更新、插入、刪除等。

lbtree/gin/gist/spgist/hash/brin:索引實現,包括各種索引的實現和操作方式,如索引掃描、插入等。

lCLOG/MultiXACT:與事務提交狀態以及併發等。

Access是設計和優化的重點模塊。當表和索引等資料庫對象被修改時,原生的PostgreSQL會生成XLog,並寫入到日誌文件中。在CynosDB中,這些對象修改時也會生成日誌,但是這些日誌不會寫本地的日誌文件,而是發送到CynosStore中。

\3. storage/buffer:buffer pool和存儲管理,調用文件介面對數據文件進行讀寫。在CynosDB中使用CynosStore Client對CynosStore中的文件進行操作。

\5. CynosStore Client提供訪問CynosStore的介面,以完成資料庫對數據文件的操作。包括數據頁面讀取介面、日誌發送介面等。

\6. 分散式存儲CynosStore是一個基於日誌的分散式的塊存儲,在本文中不做重點介紹。

CynosDB的計算層把數據文件修改所生成的日誌,通過CynosStore Client發送到分散式存儲CynosStore中,而CynosStore會將日誌定時合併到數據頁面上。這裡比較重要的一點是,計算層寫出日誌並不是PostgreSQL原生的XLog,而是我們自己重新設計的日誌系統和日誌格式。因此CynosDB不依賴於PostgreSQL的原生日誌系統,這種設計也可以讓我們有機會在CynosDB上做更多的性能優化。具體可以參見下節。

4、架構優化

CynosDB計算層的架構設計遵循瞭如下思路:

1.“極簡IO”。即,降低網路/磁碟IO

\2. 高效的系統設計。非同步的日誌設計、降低計算層CPU負載

通過這些設計,使CynosDB的性能比雲上的同等配置性能要高。本節主要介紹計算層所做的優化手段。

4.1 日誌系統

相容PostgreSQL版CynosDB的底層存儲CynosStore是一個支持日誌寫的、可以提供多版本讀的、分散式的塊設備,DB引擎對存儲中文件的修改,都是以日誌的方式發送到存儲中。其日誌格式是:<頁面號,頁面偏移,修改內容,修改長度>,含義是:在頁面的哪個偏移做了什麼內容的修改。這樣設計的日誌是冪等的。

以表插入元組為例,PostgreSQL原來的XLog日誌格式可能是:

<relfilenode, pageno, offsetnum,informask2,infomask,hoff,tuple_data>:代表在頁面(由relfilenode和pageno來確定一個頁面)的offsetnum位置插入一條元組,插入的元組是在恢復時由informask2, infomask, hoff, tuple_data等信息進行重構。

同樣的操作,在CynosDB中生成的日誌可能如下。假設在頁面號為n的頁面上插入元組tuple:

<n,10,(char *) &pd_flag,2> -- 保存頁面頭pd_flag到日誌

<n,12,(char *) &pd_lower,2> -- 保存頁面頭pd_lower到日誌

<n,14,(char *) &pd_upper,2> -- 保存頁面頭pd_upper到日誌

<n,36,(char *) &ItemIdData,4> -- 保存ItemIdData數組的第3個元素到日誌

<n,7488,(char *) tuple,172> -- 保存tuple到日誌

這些條目記錄了頁面在插入元組時的所有修改,它們最終會在CynosStore Client中形成一個MTR(mini-transaction record:多條日誌的集合,代表對資料庫存儲結構的一次原子修改,例如:btree結構、頁面結構的修改;在日誌重放的時候需要將一個MTR的所有日誌都應用完畢,否則會導致資料庫存儲結構的破壞),並放到日誌流中發送到存儲。當存儲需要將這個MTR合併到頁面時,要保證MTR中的所有日誌應用完畢,任何不完全的應用都會導致頁面結構不正確。

利用日誌特點,我們對PostgreSQL 的內核進行了優化,而優化之後的日誌大小開銷與PostgreSQL的原生XLOG差不多。這些優化和設計包括:

\1. 移除原本PostgreSQL中full page write(FPW)特性。為了保證系統crash再重啟之後,那些部分寫的頁面(torn page)可以被正確恢復,PostgreSQL在Checkpoint之後,對頁面執行第一次被修改時,會將整個頁面記錄到日誌中,這種特性就是FPW,類似MySQL的double write。當crash recovery時,系統會以這個全頁作為基頁面進行日誌回放,並將恢復好的頁面寫到存儲,而不必關心存儲頁面中的頁面是否是半頁。由於CynosDB日誌的冪等性,當出現半頁寫時,系統直接重新在此頁面上直接進行日誌回放,即可將頁面修複到一致狀態。因此CynosDB中無需原生的FPW,從而減少了日誌量。

\2. 移除系統中臟頁面刷盤操作。CynosDB通過日誌保存頁面的修改,並且可以通過在基頁上合併日誌而得到最新頁面,因此無需原本系統的刷臟操作,僅僅刷日誌就足夠。

通過如上優化,可以很大程度上減少網路IO和日誌量。

\3. 除了以上對PostgreSQL內核的優化,CynosDB對日誌的記錄方式也進行了精簡和壓縮。CynosDB的日誌都有日誌頭(LogHeader),如果修改同一個頁面的多條日誌共用一個日誌頭,則可以省去多個日誌頭的開銷,如下圖所示:

img

LH代表LogHeader,Log Element代表對頁面的頁一次修改。如上圖,有兩條對Block1的修改日誌,並且每個修改都有一個日誌頭(LH),經過日誌頭合併優化後,形成新的MTR中,修改Block1的那些日誌共用了同一個日誌頭。

如果修改同一個頁面的兩條日誌是相鄰的,那麼可以將兩條日誌進一步合併成一條日誌。這種方式減少了日誌條目,從而可以提高日誌合併和頁面生成速度。

4.2 頁面CRC

在PostgreSQL中,頁面在刷盤前會計算並填充頁面的CRC屬性,而在CynosDB中,如果為CRC也生成了一條日誌寫入到存儲中的話,會增加計算節點的CPU負擔和日誌條數。為瞭解決這個問題,我們將CRC的計算任務下放到存儲中,從而減輕了計算層的CPU負擔,以及日誌條數。

4.3 非同步表擴展

原生的PostgreSQL資料庫使用的是本地文件系統存儲數據,其文件擴展操作同步並實時的反映到磁碟文件上。但是CynosDB的擴展操作是通過日誌實現,如果每次擴展都對日誌做一次flush操作,讓擴展實時的反應到存儲上,勢必會影響系統的性能。因此,我們實現了文件的非同步擴展,即文件擴展的日誌先保留在系統的日誌buffer中,而不是每次擴展都實時的刷新到存儲中,當事務提交的時候再把這些日誌刷到存儲上,對數據批量導入的性能提升很明顯。另外,擴展操作可以一次性在文件中擴展出多個頁面,減少調用擴展操作的次數。

後續

後續我們會在新硬體、多Master架構等領域作更多探索,為雲上的資料庫產品形態帶來更多驚喜和亮點。

此文已由作者授權騰訊雲+社區發佈



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Ubuntu 12.04上安裝MySQL並運行 作者:凱魯嘎吉 - 博客園 http://www.cnblogs.com/kailugaji/ 安裝MySQL資料庫 確認是否安裝成功 當mysql節點處於LISTEN狀態表示啟動成功 登錄資料庫 MySQL資料庫常用操作 1.顯示所有資料庫(註意後面 ...
  • 一. Sentinel 高可用環境準備 1.1 Sentinel 集群環境 1.2 Redis主庫庫環境,主從庫搭建在(redis 系列22 複製Replication 下) 二. Sentinel 配置說明 2.1 啟動Sentinel服務方法 對於啟動Sentinel服務有二種方法: (1)是使 ...
  • Call to localhost/127.0.0.1:9000 failed on connection exception:java.net.ConnectException的解決方案 作者:凱魯嘎吉 - 博客園 http://www.cnblogs.com/kailugaji/ 在啟動hado ...
  • ...
  • 數據表介紹 --1.學生表 Student(SId,Sname,Sage,Ssex) --SId 學生編號,Sname 學生姓名,Sage 出生年月,Ssex 學生性別 --2.課程表 Course(CId,Cname,TId) --CId 課程編號,Cname 課程名稱,TId 教師編號 --3. ...
  • [20181220]使用提示OR_EXPAND優化.txt--//鏈接http://www.itpub.net/thread-2107240-2-1.html,http://www.itpub.net/thread-2107231-2-1.html的討論.--//ZALBB建議在18c下嘗試看看,我 ...
  • 1,某條數據放首位,其他倒序並分頁 select * from Student order by( case when id='2' then 1 ELSE 4 END),id desc limit 0,5; 2,給查詢的每條記錄添加編號 select (@i:=@i+1) no , s.* fro ...
  • Ubuntu 12.04上安裝Hadoop並運行 作者:凱魯嘎吉 - 博客園 http://www.cnblogs.com/kailugaji/ 在官網上下載好四個文件 在Ubuntu的/home/wrr/下創建一個文件夾java,將這四個文件拷到Ubuntu的/home/wrr/java/下,將e ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...