亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

CockroachDB指的是什么

發布時間:2021-12-27 10:51:40 來源:億速云 閱讀:348 作者:小新 欄目:大數據

小編給大家分享一下CockroachDB指的是什么,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

介紹

CockroachDB是一個支持SQL,支持分布式事務的ACID的分布式數據,支持ANSI SQL的最高隔離級別Serializability。

在一個分布式系統中,要支持Linearizability比較難,因為不同的機器之間時鐘有誤差,需要一個全局時鐘。TiDB選擇了和Percolator一樣的方案,單點timestamp oracle提供時鐘源。Google Spanner直接搞了一個基于硬件的TrueTime API提供相對來說比較精準的時鐘。CockroachDB沒有原子鐘,也沒有使用單點timestamp oracle,而是基于NTP來盡量同步機器之間的時鐘偏移,NTP誤差能達到250ms甚至更多,并且不能嚴格保證,這導致CockroachDB要保證Linearizability一致性很難,并且性能差。最終雖然CockroachDB支持Linearizability,但是官方不推薦。默認,CockroachDB支持Serializable隔離級別,但是不保證Linearizability。

Serializable

一個真實的數據庫系統同一時刻會有很多并發的事務在執行,如何讓這些事務覺得只有自己運行在數據庫中不受其他事務的任何干擾是一個隔離級別的問題。Serializable就是不受任何干擾,弱一點的隔離級別有Repeatable Read, Read Committed, Read Uncommitted,Snapshot Isolation這些隔離級別多多少少會覺得受到了其他事務的干擾,如Repeatable Read有幻讀問題,Snapshot Isolation有write skew問題,具體不贅述。可以參考a-critique-of-ansi-sql-isolation-levels

要實現一個支持Serializable隔離級別的數據庫挺難的,很多數據庫都不支持Serializable隔離級別,原因有幾個,我覺得最重要的原因是性能不行。Oracle 11g默認隔離級別RC,最高隔離級別Snapshot Isolation,業界一些知名數據庫對隔離級別的支持看When is "ACID" ACID? Rarely. 然而CockroachDB為了實現Serializable,花了大量的功夫。

一個事務通常包含多個讀寫操作,操作不同的行/列。數據庫系統會對系統中的事務進行調度,事務會交叉執行,而不是一個接著一個。

 CockroachDB指的是什么

一共三個事務,上圖是數據庫系統對這三個事務的一種調度。那么這個調度是不是Serializable的?這個有理論支持: serializability graph。這個理論引入了三種沖突,三種沖突都是對于不同的事務操作同一個數據而言:

  • RW: W覆蓋了R讀到的值

  • WR: R讀到了W更新的值

  • WW: W覆蓋了第一個W更新的值

對于任何一個事務調度結果,如果兩個事務存在某種沖突,就在事務之間連上有向邊(后面的事務指向前面的事務)。下圖是上面事務調度的serializability graph。

CockroachDB指的是什么

已經證明如果一個事務調度的serializability graph中不存在環,那么這個事務調度就是Serializable的。那么CockroachDB是怎么做的?

CockroachDB事務處理系統

  • 多版本


CockroachDB的事務是Lock-Free的,不需要加任何讀寫鎖,自然就需要維護數據的多個版本,版本通過timestamp來標識。

ACID中的A和I密切相關,都是通過并發控制協議保證的,下面先說明A是如何保證的,然后說明在并發的情況下,I是如何保證的。并發控制協議保證了A和I。

  • 原子性

一個分布式事務可能會對多個節點上的數據進行讀寫,如何保證原子性? 大家都知道分布式事務都是2PC,第一階段做Prepare,把需要的讀的數據讀進來(怎么保證讀到最新的數據,后面會說,這里先假設能讀到),計算,最后把計算后的數據寫入各個節點,但是不對外生效,即系統中其他事務暫且讀不到這個數據。這種已經寫入各個節點,但是沒有生效的數據CockroachDB把它叫做write intent,這種write intent和實際的數據存儲在一起,只是外部讀不到而已。

CockroachDB指的是什么

那么這個事務的狀態存在哪?事實上,在一個事務開始的時候,會往底層存儲系統中寫入一條記錄,這個記錄叫做Transaction Record,record會記錄事務ID,事務狀態,Pending(正在運行)還是Committed,還是Aborted,而write intent里存在key指向這個Transaction Record。提交事務,只需要把Transaction Record中的事務狀態改成Committed即可,回滾事務改成Aborted即可。一旦事務狀態修改成功,就可以返回給客戶端,遺留的write intent會異步處理:commit時,將write intent的值覆蓋原始值,刪掉write intent,rollback時直接刪掉write intent即可。

隨后客戶端過來讀的時候,如果碰到了write intent(之前說了,write intent是異步刪除),就會沿著write intent找到Transaction Record,看看事務的狀態,如果狀態是committed,返回write intent中的值,如果Abort就會返回原始的值。如果是Pending,說明這個事務還在正常跑,遇到了寫寫沖突,如何解決寫寫沖突? 這個牽扯到隔離級別和并發控制協議,看下面。

  • 隔離性

之前提到,數據是多版本的,版本通過timestamp來標識。timestamp是讀寫事務/寫事務在事務開始的時候從本機拿到的wall time(實際上是HLC,一種基于物理時鐘的可以捕獲因果關系的邏輯時鐘),這個timestamp只是這個事務最后commit的候選timestamp而已,不一定是最終的commit的timestamp(根本原因是機器之間存在時鐘offset,后面會講到),這里先假定,拿到了一個最終的timestamp。timestamp越大,說明版本越新。這個事務的所有寫入的數據都會打上這個timestamp作為版本標識。在這樣一個系統中,serializability graph大概是下面的樣子:

上面這個圖是無環的。下面這個圖是有環的:

回到Serializability,為了實現Serializability,需要保證事務的調度是無環的。CockroachDB通過在timestamp的反方向避免之前提到的三種沖突,從而在圖中就不會有和timestamp走向一致的邊,進而保證無環。最后,CockroachDB的serializability graph長如下樣子:

CockroachDB保證如下約束:

  • RW: W的時間戳只能比R的大,這只會產生回頭邊(通過在每個節點維護一個Read Timestamp Cache)。

  • WR: R只會讀比自己timestamp小的最大的版本,這也只會產生回頭邊。

  • WW:第二W的timestamp比第一個W的timestamp大,這也只會產生回頭邊。

也就是說,只要保證一個事務只與timestamp更小的事務沖突,就能保證無環。

  • Recoverable

殘酷的是,僅僅保證無環能實現Serializability,同時還需要保持數據庫的一致性,即ACID中的C。考慮如下場景:

T1,T2兩個事務,timestamp(T1) < timestamp(T2),T1更新A,還沒有提交,T2讀A。這是一個WR沖突,但是由于這個沖突是回頭邊,所以是允許的。為了維護上面提到的RW約束,T2必須讀T1的更新(W的timestamp必須比R大,然而T1比T2小)。然而,T2讀T1對A的更新有什么問題?

  • T2讀T1的更新。如果最后T2 commit,隨后T1回滾,這個會違反T1的原子性:T1沒有寫成功的值被T2讀到了。

CockroachDB使用一種比較苛刻的調度來處理這種場景:所有的操作只能在已經committed的數據上進行!下面講講CockroachDB的這種苛刻的調度是如何保證的,這里就需要用到前面原子性的知識。

  • Strict Scheduling

從上一節以及原子性章節可以得知,一個事務碰到了一個write intent,那么說明有可能寫write intent的事務還沒有結束(因為write intent是異步清除的),這就說明有可能碰到了uncommitted的數據。這時,當前事務會去檢查write intent所在的事務的狀態,如果已經提交了,將write intent覆蓋舊值然后清除write intent即可。如果已經回滾了,那么直接清除write intent就行。如果是Pending,正在運行呢?這個時候,就要看事務的優先級了,優先級低的事務需要abort,事務開始時賦予的優先級是random的。CockroachDB會保證被abort的事務在restart之后優先級會提高。

到這里,CockroachDB如何提供Serializability隔離級別就講完了,注意,這里的前提是每個事務都被賦予了一個合適的timestamp,什么叫做合適的 timestamp? 一個分布式讀/讀寫事務需要能讀到最新的已經committed的數據。

  • CockroachDB如何為事務賦予時間戳

CockroachDB使用NTP進行時鐘同步,NTP基本能保證機器之間的時鐘offset小于250ms,但是這也不絕對,這受到網絡延時,系統load等因素的影響。從前面可以看出,CockroachDB的Serializability依賴于集群內機器之間的時鐘clock在一個范圍ε內。這個范圍可以配置,默認250ms。任何一個時刻,在一臺機器上拿到wall time為t,那么集群中可能存在的最大wall time是t+ε。

一個事務T開始時,先拿一個本地Wall time(實際上是HLC),記作t,根據NTP定義,集群內機器此刻最大的Wall time為t+ε,如果事務執行過程中讀到的數據對象處于[t,t+ε]之間,我們是不知道這個值到底是在T開始之后才commit的,還是T開始之前就commit的。所以T需要restart,重新設置t為碰到的這個timestamp。

以上是“CockroachDB指的是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

资阳市| 雷波县| 甘南县| 神农架林区| 平陆县| 松江区| 同江市| 涿鹿县| 普洱| 罗甸县| 民权县| 南陵县| 河西区| 成都市| 仙游县| 托克逊县| 桃园县| 腾冲县| 平山县| 苍山县| 高雄市| 厦门市| 石首市| 万盛区| 杂多县| 广西| 中阳县| 平湖市| 汝南县| 普宁市| 鄄城县| 乐至县| 安化县| 闸北区| 宁河县| 双江| 大竹县| 定陶县| 依兰县| 淮安市| 麦盖提县|