上篇文章中,我們介紹了與 tikv 處理讀寫請求相關的基礎知識,下面將開始詳細的介紹 tikv 的讀寫流程。enjoy~tikv 提供兩套 api,一套叫做 rawkv,另一套叫做 txnkv。txnkv 對應的就是上面提到的 percolator,而 rawkv 則不會對事務做任何保證,而且比 txnkv 簡單很多,這裡我們先討論 rawkv。
當進行寫入,譬如 write a = 1,會進行如下步驟:
client 找 pd 問 a 所在的 region
pd 告訴 region 相關資訊,主要是 leader 所在的 tikv
client 將命令傳送給 leader 所在的 tikv
leader 接受請求之後執行 raft 流程
對於 read 來說,也是一樣的操作,唯一不同在於 leader 可以直接提供 read,不需要走 raft。
對於 txnkv 來說,情況就要複雜的多,不過大部分流程已經在 percolator 章節進行說明了。這裡需要注意的是,因為我們要快速的 seek 到最新的 commit,所以在 rocksdb 裡面,我們會先將 ts 使用 bigendian 生成 8 位元組的 bytes,然後將這個 bytes 逐位取反,在跟原始的 key 組合儲存到 rocksdb 裡面,這樣就能保證最新的提交存放到前面,seek 的時候就能直接定位了,當然 seek 的時候,也同樣會將對應的 ts 按照相同的方式編碼處理。
譬如,假設乙個 key 現在有兩次提交,committs 分別為 10 和 12,startts 則是 9 和 11,那麼在 rocksdb 裡面,key 的存放順序則是:
write cf:
a_12 -> 11
a_10 -> 9
data cf:
a_11 -> data_11
a_9 -> data_9
複製**
另外,還需要注意的是,對於 value 比較小的情況,tikv 會直接將 value 存放到 write cf 裡面,這樣 read 的時候只要走 write cf 就行了。在寫入的時候,流程如下:
prewrite:
lock cf: w a -> lock + data
commit:
lock cf: r a -> lock + 10 + data
lock cf: d a
write cf: w a_11 -> 10 + data
複製**
對於 tikv 來說,在 commit 階段無論怎樣都會讀取 lock 來判斷事務衝突,所以我們可以從 lock 拿到資料,然後再寫入到 write cf 裡面。
read 的流程之前的 percolator 已經有說明了,這裡就不詳細解釋了。
我們在 tikv 上面構建了乙個分布式資料庫 tidb,它是乙個關係型資料庫,所以大家需要關注的是乙個關係型的 table 是如何對映到 key-value 上面的。假設我們有如下的表結構:
create table t1
複製**
上面我們建立了一張表 t1,裡面有四個字段,id 是主鍵,name 是唯一索引,age 是乙個索引。那麼這個表裡面的資料是如何對應到 tikv 的呢?
在 tidb 裡面,任何一張表都有乙個唯一的 id,譬如這裡是 11,任何的索引也有唯一的 id,上面 name 就是 12,age 就是 13。我們使用字首 t 和 i 來區分表裡面的 data 和 index。對於上面表 t1 來說,假設現在它有兩行資料,分別是 (1, 「a」, 10, 「hello」) 和 (2, 「b」, 12, 「world」),在 tikv 裡面,每一行資料會有不同的 key-value 對應。如下:
pk
t_11_1 -> (1, 「a」, 10, 「hello」)
t_11_2 -> (2, 「b」, 12, 「world」)
unique name
i_12_a -> 1
i_12_b -> 2
index age
i_13_10_1 -> nil
i_13_12_2 -> nil
複製**
因為 pk 具有唯一性,所以我們可以用 t + table id + pk 來唯一表示一行資料,value 就是這行資料。對於 unique 來說,也是具有唯一性的,所以我們用 i + index id + name 來表示,而 value 則是對應的 pk。如果兩個 name 相同,就會破壞唯一性約束。當我們使用 unique 來查詢的時候,會先找到對應的 pk,然後再通過 pk 找到對應的資料。
對於普通的 index 來說,不需要唯一性約束,所以我們使用 i + index id + age + pk,而 value 為空。因為 pk 一定是唯一的,所以兩行資料即使 age 一樣,也不會衝突。當我們使用 index 來查詢的時候,會先 seek 到第乙個大於等於 i + index id + age 這個 key 的資料,然後看字首是否匹配,如果匹配,則解碼出對應的 pk,再從 pk 拿到實際的資料。
tidb 在操作 tikv 的時候需要保證操作 keys 的一致性,所以需要使用 txnkv 模式。
上面簡單的介紹了下 tikv 讀寫資料的流程,還有很多東西並沒有覆蓋到,譬如錯誤處理,percolator 的效能優化這些,如果你對這些感興趣,可以參與到 tikv 的開發,歡迎聯絡我 [email protected]。
HBase 是如何訪問資料的
hbase是乙個查詢極其快速的非關係型資料庫,它在實時讀寫和實時訪問上有著巨大的優勢,並且非常靈活。先來看下面這幅圖 這是乙個hbase表的儲存結構模型,其中有4個字段。分別為rowkey 主鍵 time stamp 時間戳 cf 列族 cf xx 列 這看上去是乙個資料表,但是對於hbase而言,...
SpringMVC 如何訪問web inf下的頁面
對應web inf目錄下面的jsp頁面,我們知道是不能直接使用url訪問到。需要通過 的方式,而我們一般都是在控制器中做 對映,對應一些我們不需要其他操作的jsp頁面,我們可以使用來配置,這樣就可以不用再控制器中再去做 對映 看看success.jsp頁面的目錄結果 一般我們需要配置乙個spring...
Ubuntu 下如何掛載訪問Windows磁碟
error mounting dev sda5 at media原因 微軟為win8加入了快速啟動功能,當你在win8中關閉計算機時,預設情況下會執行混合關機。混合關機使得win8的啟動速度會比win7及windows以前版本快很多。不同於冷啟動,win8會將需要載入的系統核心和驅動程式儲存到磁碟休...