您好,登錄后才能下訂單哦!
顏然,螞蟻金服 OceanBase 團隊資深技術專家,OceanBase 初創成員之一,目前負責事務引擎以及性能優化相關的研發工作。
以下為演講實錄:
首先,我們先來聊一個大家都很感興趣的話題:跟已有的經典數據庫比如:Oracle、SQL Server等,OceanBase跟他們最大的區別在哪里?OceanBase是一個云原生的數據庫。而我們所做的軟件全部是基于硬件的基礎之上。那么,我們首先就需要了解現在的硬件到底處在什么水平?
如上圖所示,IBM的解決方案是最為大家所熟識的,從五十多年前的System 360到去年新出的IBM z14,時至今日依然還有很多機構在沿用這套解決方案。
我們每天都在說云計算,那么到底什么是云計算?云計算不是從石頭縫里蹦出來的解決方案,它最早起源于DEC的小型機。DEC是和IBM大型機同時代的產物,以較低的價格解決存儲和計算的需求。它與IBM大型機的區別在于:DEC價格低,獲得方式更靈活。
DEC之后被基于芯片的解決方案打破了,諸如SUN工作站的解決方案提供了更好的性能和更低價格,平臺也更通用。再之后PC Server接過接力棒,此時的CPU、內存、存儲可以來自于不同的廠商,但大家組合起來以后仍然可以提供一套標準化的計算和存儲的平臺。
相比較IBM大型機,基于PC Server的數據中心以一種更產業鏈化的方式提供了計算和存儲的解決方案,具有更好的性價比,也更易于擴展。但是IBM大型機是軟硬一體化設計,這也是大型機滿足需求可以采用很多硬件層面的解決思路。例如,金融業務對于高可靠性的需求,大型機是在硬件層面做了多種可靠性保障,從存儲到內存甚至CPU都是有冗余策略來支持。但是PC Server的單臺機器的故障率相對來說是高的,所以需要使用完全不同的思路來解決業務高可靠和高可用的需求。
此處引用OceanBase團隊創始人陽振坤的一句話——“計算機天然不適合數據庫,但數據庫天然選擇了計算機”。為什么計算機天然不適合數據庫?因為在處理數據的時候,一個非常關鍵的問題就是數據的可靠安全和一致。而計算機的硬件天然具有各種概率的損壞,不管是掉電,軟件出Bug,操作系統有問題,還是整個機房都掛掉,計算機是天然會出錯的。但我們要解決的問題又是不能出錯,所以在計算機上去解決數據庫的可靠安全一致性的問題,其實是一個非常大的挑戰。
要在一個更低可靠性的機器上實現更可靠的數據庫的事務服務能力,這就是我們當前所面臨的嚴峻挑戰。
當然,有挑戰的地方就有機遇。OceanBase在面對這樣的挑戰之下我們做了什么?在這樣的一個基于PC Server的云化環境下,OceanBase實現了彈性擴展的能力,同時實現了不依賴高端硬件解決數據庫事務的高可靠和高可用的能力。
OceanBase所依賴的硬件條件是一套通用的云化環境。但在這個硬件基礎上,我們依然可以做到數據庫的事務,同樣能夠實現高性能,甚至能夠支撐金融級的可靠性。
何謂金融級可靠性?每個人都會有切身的感受。比如說你發了一條帖子,但是這條帖子丟了,你可能會不爽,但是不至于非常難受。再換一個場景,今天你給朋友轉賬100元,你朋友卻只收到98元,此時你的內心一定是恐懼的。所以在這種金融級場景下,必須做到的就是為用戶提供充足的保障,這就叫做金融級可靠性。但金融級可靠性的難度在于對細節的處理能力。細節是魔鬼,我們在做數據庫軟件的時候,需要對細節的把控能力極強。
這里要重點提到的幾點,其實就延續著數據庫事務的幾個重要的特性。
OceanBase的架構基于LSM Tree。為什么會基于LSM Tree?它有哪些特點?
在經典的數據庫里,所有的數據是分片保存在持久化存儲里的,比如磁盤或者SSD。在讀取數據的時候,一定要先把它放在內存里。當需要做修改的時候,也要把一塊數據放在內存里。如果內存滿了之后,就會把這個頁面刷回去。
OceanBase所基于的LSMTree,可以把更多的修改更集中地放在一個內存結構里。我們的做法是在后臺定期地做這件事情,前臺把數據盡可能存更久的時間,然后再讓后臺去做合并。OceanBase有一個機制叫每日合并,也就是說如果前臺能存一天的時間,我們到了每天夜里才做后臺合并這件事情。
OceanBase會在系統內部做調度,第一臺機器在后臺刷臟頁的時候,讓業務的流量都跑在其他機器上,就可以不影響前臺的業務。當第一臺完成后,再把業務的流量切回來,然后讓第二臺機器做后臺刷臟頁的操作。我們通過這種“輪轉合并”的方法解決在集群環境下利用不同機器不同服務的時間差去做刷臟頁這件事情。
OceanBase事務引擎設計也利用了LSM Tree的結構,讓事務的所有執行狀態都保存在內存中,只有事務提交之后才會把事務修改的數據持久化。所以在實現事務原子性時,不需要做undo。這樣OceanBase可以以一個更簡潔的方式來做數據庫的事務。這個就是OceanBase存儲引擎的整體邏輯。
OceanBase的事務執行操作都在內存里發生。內存跟硬盤一個最大的差別,就是內存是可以以字節為單位進行隨機尋址的,而這帶來的一個非常大的好處就是使得數據結構更豐富了。
舉個例子,如上圖表格中的數據,現在要對第一行數據進行更新:條件是給Han加50萬薪水。現在需要給這張表格中這一列對應的Han寫一個新的值。在內存里的表示方法就是這樣一個鏈表。如果Han漲了薪水以后突然希望換部門接受全新的挑戰,我們就需要再做一次更新操作。只需要在這個列表里串上一次新的更新把他的部門進行更改。他從研發部門轉到投資部門了,那我們就把這一列對應的修改記錄在這里。
這個是數據庫內部基于多版本的一種并發控制,記錄了每一次更新發生的時間,保證了修改操作跟讀取操作不會互相影響。因為即使一行數據被改了,我們還是可以直接拿到歷史數據。基于鏈表的數據結構對程序員來說是非常友好的。
相比較經典的基于硬盤的數據庫,無論數據讀取還是寫入都是定長數據塊為單位的操作,表達信息的方式也是基于塊的。OceanBase的方式帶來的一個最大的好處就是大大提升了表達的簡潔性,也就是它本身的操作效率要高特別多。這也解釋了了為什么OceanBase能在目前的硬件環境下提供更強的事務處理能力,這是其中一個很重要的原因。
我們再回顧一下OceanBase的架構,OceanBase把數據分片了之后,可以在多個集群里的多臺機器上把數據擴展出去做存儲,它提供了線性擴展能力。
像上圖所示同樣一份數據會有多個副本,比如P0在三臺機器上,這三臺機器可能在同一個機房,也可能來自不同機房。但是它們會服務于同一份數據,其中只有一個是當前的主,它負責做數據庫的操作,并且把數據庫事務的修改同步到其他的機器上。我們這里提到OceanBase的數據組織與分布的目的就是要解決后面數據庫的可靠性問題。
高可靠和高可用是被所有數據庫產品廣泛提及的概念。那么,可靠性和可用性到底意味著什么?
傳統的數據庫,ACID的理論里并沒有availability這個概念,只保證了durable。但是數據不丟,卻不一定能保證服務的連續性。但是failover的能力在實際的系統中卻是非常重要的。所以所有的商業數據庫都有對應的解決可用性的方案。其中經典的就是基于主備同步的方案,當主壞掉的時候,備可以繼續提供服務,這就是在解決可用性的問題。
OceanBase采用Paxos協議來解決可靠性和可用性的問題。任何一個數據庫的事務要做持久化,事務的日志都需要持久到多個副本上。在三個副本之中,我們認為只要持久化到兩個副本的硬盤上,就定義為這個事務是成功的。也就是說有任何一臺機器壞了的時候,至少還有一個副本在。
那么,反過來思考是不是同步到越多的機器上越好?如果三個副本都同步到,是不是就更加可靠了?這就是可用性所帶來的問題,如果其中有一臺機器網絡出現故障,或者系統負載太高無法響應,你是否認為這個事務成功?
如果要求三個都成功的話,就不能認為它成功,因為有一臺機器沒響應。Paxos協議只要求兩個機器同步到,就是即便有一個沒有應答,我們依然認為這個事務是成功的,因為多數派成功了。
保證三個里面有一個壞掉是不受影響的,同時也不影響系統的持續服務。這是在可靠性和可用性中間的一個很好的平衡。如果你需要更高的保障,就可以選擇五個副本的方案,這樣可以保證有兩臺機器出故障的時候,同樣既不影響可靠性,也不影響可用性,這是一個很重要的平衡點。
所以我們在ACID里再加入一個A,也就是我們既要讓事務有可靠性,也要讓事務的處理能力有可用性。
數據庫在單機上寫日志一定是只寫自己機器上的日志文件,如果寫成功了就成功,不成功就失敗。但是在多臺機器上的時候就涉及到:A機器成功了,B機器失敗了。這件事情該怎么辦?
兩階段提交協議的存在就是為了解決這個問題,也就是說提交再也不能是一次性就成功的,它要涉及到多個機器之間達成一致,每臺機器都成功了最終才能定義為成功。
事實上,兩階段提交協議在實際應用中非常少。為什么呢?主要因為它很復雜,雖然理論很漂亮,但是存在的細節問題特別多。但是在OceanBase的業務場景下又一定要用兩階段提交協議來解決。
OceanBase的基礎是每一個參與者都是高可用的,因為OceanBase使用了Paxos協議保證了Partition高可用,所以任何一臺機器的故障不會導致服務停止,這是一個很重要的前提。另外,因為Paxos同步引入了跨網絡、跨機房的同步延遲,原始的兩階段提交協議多次寫日志會帶來較多的開銷,OceanBase做了一件事情就是讓協調者不寫日志,只保留內存狀態。它帶來的一個非常重要的好處就是commit延遲低。同時因為所有參與者都是高可用的,我們不會出現兩階段狀態一般會出現的問題,比如協調者宕機卡住的問題。
事務隔離涉及到事務的并發控制怎么做,OceanBase使用的是多版本并發控制。讀取請求會拿到當前系統的publish version作為讀取的快照版本。事務提交的時候會生成一個版本號,版本號是連續遞增的,作為本事務所有修改數據的版本。
單機場景下,一條日志就能決定這個事務最終是否能夠提交。那么這條日志的位置就決定了這個事務的版本號,它的版本號一定是遞增連續的。但是在分布式事務參與進來之后,舉個例子,就會出現230可能是一條prepare日志,prepare日志不代表這個事務能夠提交,但是232可能是另外一個事務的commit日志,這也就意味著這個事務要commit的話,232版本就需要可讀,但是230又處在行鎖未解事務進行中的狀態。這個時候就需要另外一種控制方法,對于兩階段提交的prepare和commit之間的事務,這些事務所有操作的行要鎖住,不允許讀取。
這個影響很小是因為在prepare和commit之間不涉及到用戶的任何干預,是一個毫秒級的操作,也就是說,這個行在提交的過程中會在一個很短的瞬間被鎖住。這個瞬間里讀取操作會等待事務提交掉,再去判斷該不該讀這一行的數據。
基于以上的技術創新,OceanBase真正實現了在云環境下事務的高可靠、高可用,同時還具有很好的性能。希望OceanBase可以幫助更多的業務解決數據存儲和查詢的需求,不再受困于傳統商業數據庫的價格高、擴展性差的問題。
點擊閱讀更多,查看更多詳情
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。