您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關高性能數據庫中的讀寫分離是怎樣的,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
雖然近十年來各種存儲技術飛速發展,但關系數據庫由于其 ACID 的特性和功能強大的 SQL 查詢,目前還是各種業務系統中關鍵和核心的存儲系統,很多場景下高性能的設計最核心的部分就是關系數據庫的設計。
不管是為了滿足業務發展的需要,還是為了提升自己的競爭力,關系數據庫廠商(Oracle、DB2、MySQL 等)在優化和提升單個數據庫服務器的性能方面也做了非常多的技術優化和改進。但業務發展速度和數據增長速度,遠遠超出數據庫廠商的優化速度,尤其是互聯網業務興起之后,海量用戶加上海量數據的特點,單個數據庫服務器已經難以滿足業務需要,必須考慮數據庫集群的方式來提升性能。
高性能數據庫集群的第一種方式是“讀寫分離”,其本質是將訪問壓力分散到集群中的多個節點,但是沒有分散存儲壓力;第二種方式是“分庫分表”,既可以分散訪問壓力,又可以分散存儲壓力。先來看看“讀寫分離”。
讀寫分離的基本原理是將數據庫讀寫操作分散到不同的節點上,下面是其基本架構圖。
讀寫分離的基本實現是:
數據庫服務器搭建主從集群,一主一從、一主多從都可以。
數據庫主機負責讀寫操作,從機只負責讀操作。
數據庫主機通過復制將數據同步到從機,每臺數據庫服務器都存儲了所有的業務數據。
業務服務器將寫操作發給數據庫主機,將讀操作發給數據庫從機。
需要注意的是,這里用的是“主從集群”,而不是“主備集群”。“從機”的“從”可以理解為“仆從”,仆從是要幫主人干活的,“從機”是需要提供讀數據的功能的;而“備機”一般被認為僅僅提供備份功能,不提供訪問功能。所以使用“主從”還是“主備”,是要看場景的,這兩個詞并不是完全等同的。
讀寫分離的實現邏輯并不復雜,但有兩個細節點將引入設計復雜度:主從復制延遲和分配機制。
以 MySQL 為例,主從復制延遲可能達到 1 秒,如果有大量數據同步,延遲 1 分鐘也是有可能的。主從復制延遲會帶來一個問題:如果業務服務器將數據寫入到數據庫主服務器后立刻(1 秒內)進行讀取,此時讀操作訪問的是從機,主機還沒有將數據復制過來,到從機讀取數據是讀不到最新數據的,業務上就可能出現問題。例如,用戶剛注冊完后立刻登錄,業務服務器會提示他“你還沒有注冊”,而用戶明明剛才已經注冊成功了。
解決主從復制延遲有幾種常見的方法:
1. 寫操作后的讀操作指定發給數據庫主服務器
例如,注冊賬號完成后,登錄時讀取賬號的讀操作也發給數據庫主服務器。這種方式和業務強綁定,對業務的侵入和影響較大,如果哪個新來的程序員不知道這樣寫代碼,就會導致一個 bug。
2. 讀從機失敗后再讀一次主機
這就是通常所說的“二次讀取”,二次讀取和業務無綁定,只需要對底層數據庫訪問的 API 進行封裝即可,實現代價較小,不足之處在于如果有很多二次讀取,將大大增加主機的讀操作壓力。例如,黑客暴力破解賬號,會導致大量的二次讀取操作,主機可能頂不住讀操作的壓力從而崩潰。
3. 關鍵業務讀寫操作全部指向主機,非關鍵業務采用讀寫分離
例如,對于一個用戶管理系統來說,注冊 + 登錄的業務讀寫操作全部訪問主機,用戶的介紹、愛好、等級等業務,可以采用讀寫分離,因為即使用戶改了自己的自我介紹,在查詢時卻看到了自我介紹還是舊的,業務影響與不能登錄相比就小很多,還可以忍受。
將讀寫操作區分開來,然后訪問不同的數據庫服務器,一般有兩種方式:程序代碼封裝和中間件封裝。
1. 程序代碼封裝
程序代碼封裝指在代碼中抽象一個數據訪問層(所以有的文章也稱這種方式為“中間層封裝”),實現讀寫操作分離和數據庫服務器連接的管理。例如,基于 Hibernate 進行簡單封裝,就可以實現讀寫分離,基本架構是:
程序代碼封裝的方式具備幾個特點:
實現簡單,而且可以根據業務做較多定制化的功能。
每個編程語言都需要自己實現一次,無法通用,如果一個業務包含多個編程語言寫的多個子系統,則重復開發的工作量比較大。
故障情況下,如果主從發生切換,則可能需要所有系統都修改配置并重啟。
目前開源的實現方案中,淘寶的 TDDL(Taobao Distributed Data Layer,外號: 頭都大了)是比較有名的。它是一個通用數據訪問層,所有功能封裝在 jar 包中提供給業務代碼調用。其基本原理是一個基于集中式配置的 jdbc datasource 實現,具有主備、讀寫分離、動態數據庫配置等功能,基本架構是:
(http://1.im.guokr.com/0Y5YjfjQ8eGOzeskpen2mlNIYA_b7DBLbGT0YHyUiLFZAgAAgwEAAFBO.png)
2. 中間件封裝
中間件封裝指的是獨立一套系統出來,實現讀寫操作分離和數據庫服務器連接的管理。中間件對業務服務器提供 SQL 兼容的協議,業務服務器無須自己進行讀寫分離。對于業務服務器來說,訪問中間件和訪問數據庫沒有區別,事實上在業務服務器看來,中間件就是一個數據庫服務器。其基本架構是:
數據庫中間件的方式具備的特點是:
能夠支持多種編程語言,因為數據庫中間件對業務服務器提供的是標準 SQL 接口。
數據庫中間件要支持完整的 SQL 語法和數據庫服務器的協議(例如,MySQL 客戶端和服務器的連接協議),實現比較復雜,細節特別多,很容易出現 bug,需要較長的時間才能穩定。
數據庫中間件自己不執行真正的讀寫操作,但所有的數據庫操作請求都要經過中間件,中間件的性能要求也很高。
數據庫主從切換對業務服務器無感知,數據庫中間件可以探測數據庫服務器的主從狀態。例如,向某個測試表寫入一條數據,成功的就是主機,失敗的就是從機。
由于數據庫中間件的復雜度要比程序代碼封裝高出一個數量級,一般情況下建議采用程序語言封裝的方式,或者使用成熟的開源數據庫中間件。如果是大公司,可以投入人力去實現數據庫中間件,因為這個系統一旦做好,接入的業務系統越多,節省的程序開發投入就越多,價值也越大。
目前的開源數據庫中間件方案中,MySQL 官方先是提供了 MySQL Proxy,但 MySQL Proxy 一直沒有正式 GA,現在 MySQL 官方推薦 MySQL Router。MySQL Router 的主要功能有讀寫分離、故障自動切換、負載均衡、連接池等,其基本架構如下:
(https://dev.mysql.com/doc/mysql-router/2.1/en/images/mysql-router-positioning.png)
奇虎 360 公司也開源了自己的數據庫中間件 Atlas,Atlas 是基于 MySQL Proxy 實現的,基本架構如下:
以下是官方介紹,更多內容你可以參考這里。
Atlas 是一個位于應用程序與 MySQL 之間中間件。在后端 DB 看來,Atlas 相當于連接它的客戶端,在前端應用看來,Atlas 相當于一個 DB。Atlas 作為服務端與應用程序通信,它實現了 MySQL 的客戶端和服務端協議,同時作為客戶端與 MySQL 通信。它對應用程序屏蔽了 DB 的細節,同時為了降低 MySQL 負擔,它還維護了連接池。
以上就是高性能數據庫中的讀寫分離是怎樣的,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。