天天看點

Tair簡介

簡介

tair 是淘寶自己開發的一個分布式 key/value 存儲引擎. tair 分為持久化和非持久化兩種使用方式. 非持久化的 tair 可以看成是一個分布式緩存. 持久化的 tair 将資料存放于磁盤中. 為了解決磁盤損壞導緻資料丢失, tair 可以配置資料的備份數目, tair 自動将一份資料的不同備份放到不同的主機上, 當有主機發生異常, 無法正常提供服務的時候, 其于的備份會繼續提供服務.

tair 的總體結構

tair 作為一個分布式系統, 是由一個中心控制節點和一系列的服務節點組成. 我們稱中心控制節點為config server. 服務節點是data server. config server 負責管理所有的data server, 維護data server的狀态資訊. data server 對外提供各種資料服務, 并以心跳的形式将自身狀況彙報給config server. config server是控制點, 而且是單點, 目前采用一主一備的形式來保證其可靠性. 所有的 data server 地位都是等價的.

Tair簡介

tair 的負載均衡算法是什麼

tair 的分布采用的是一緻性雜湊演算法, 對于所有的key, 分到Q個桶中, 桶是負載均衡和資料遷移的基本機關. config server 根據一定的政策把每個桶指派到不同的data server上. 因為資料按照key做hash算法, 是以可以認為每個桶中的資料基本是平衡的. 保證了桶分布的均衡性, 就保證了資料分布的均衡性.

Tair簡介

DataServer内部結構

DataServer負責資料的實體存儲,并根據configserver建構的對照表完成資料的複制和遷移工作。DataServer具備抽象的存儲引擎層,可以很友善地添加新存儲引擎。DataServer還有一個插件容器,可以動态地加載/解除安裝插件。

Tair簡介

抽象的存儲引擎層

Tair的存儲引擎有一個抽象層,隻要滿足存儲引擎需要的接口,便可以很友善地替換Tair底層的存儲引擎。比如你可以很友善地将bdb、tc甚至MySQL作為Tair的存儲引擎,而同時使用Tair的分布方式、同步等特性。

Tair預設包含兩個存儲引擎:mdb和fdb。

mdb是一個高效的緩存存儲引擎,它有着和memcached類似的記憶體管理方式。mdb支援使用share memory,這使得我們在重新開機Tair資料節點的程序時不會導緻資料的丢失,進而使更新對應用來說更平滑,不會導緻命中率的較大波動。

fdb是一個簡單高效的持久化存儲引擎,使用樹的方式根據資料key的hash值索引資料,加快查找速度。索引檔案和資料檔案分離,盡量保持索引檔案在記憶體中,以便減小IO開銷。使用空閑空間池管理被删除的空間。

自動的複制和遷移

為了增強資料的安全性,Tair支援配置資料的備份數。比如你可以配置備份數為3,則每個資料都會寫在不同的3台機器上。得益于抽象的存儲引擎層,無論是作為cache的mdb,還是持久化的fdb,都支援可配的備份數。

當資料寫入一個節點(通常我們稱其為主節點)後,主節點會根據對照表自動将資料寫入到其他備份節點,整個過程對使用者是透明的。

當有新節點加入或者有節點不可用時,configserver會根據目前可用的節點,重新build一張對照表。資料節點同步到新的對照表時,會自動将在新表中不由自己負責的資料遷移到新的目标節點。遷移完成後,用戶端可以從configserver同步到新的對照表,完成擴容或者容災過程。整個過程對使用者是透明的,服務不中斷。

插件容器

Tair還内置了一個插件容器,可以支援熱插拔插件。

插件由configserver配置,configserver會将插件配置同步給各個資料節點,資料節點會負責加載/解除安裝相應的插件。

插件分為request和response兩類,可以分别在request和response時執行相應的操作,比如在put前檢查使用者的quota資訊等。

插件容器也讓Tair在功能友善具有更好的靈活性。

增加或者減少data server的時候會發生什麼

       當有某台data server故障不可用的時候, config server會發現這個情況, config server負責重新計算一張新的桶在data server上的分布表, 将原來由故障機器服務的桶的通路重新指派到其它的data server中. 這個時候, 可能會發生資料的遷移. 比如原來由data server A負責的桶, 在新表中需要由 B負責. 而B上并沒有該桶的資料, 那麼就将資料遷移到B上來. 同時config server會發現哪些桶的備份數目減少了, 然後根據負載情況在負載較低的data server上增加這些桶的備份. 當系統增加data server的時候, config server根據負載, 協調data server将他們控制的部分桶遷移到新的data server上. 遷移完成後調整路由. 當然, 系統中可能出現減少了某些data server 同時增加另外的一些data server. 處理原理同上. 每次路由的變更, config server都會将新的配置資訊推給data server. 在用戶端通路data server的時候, 會發送用戶端緩存的路由表的版本号. 如果data server發現用戶端的版本号過舊, 則會通知用戶端去config server取一次新的路由表. 如果用戶端通路某台data server 發生了不可達的情況(該 data server可能當機了), 用戶端會主動去config server取新的路由表.

發生遷移的時候data server如何對外提供服務

      當遷移發生的時候, 我們舉個例子, 假設data server A 要把 桶 3,4,5 遷移給data server B. 因為遷移完成前, 用戶端的路由表沒有變化, 用戶端對 3, 4, 5 的通路請求都會路由到A. 現在假設 3還沒遷移, 4 正在遷移中, 5已經遷移完成. 那麼如果是對3的通路, 則沒什麼特别, 跟以前一樣. 如果是對5的通路, 則A會把該請求轉發給B,并且将B的傳回結果傳回給客戶, 如果是對4的通路, 在A處理, 同時如果是對4的修改操作, 會記錄修改log.當桶4遷移完成的時候, 還要把log發送到B, 在B上應用這些log. 最終A B上對于桶4來說, 資料完全一緻才是真正的遷移完成. 當然, 如果是因為某data server當機而引發的遷移, 用戶端會收到一張中間臨時狀态的配置設定表. 這張表中, 把當機的data server所負責的桶臨時指派給有其備份data server來處理. 這個時候, 服務是可用的, 但是負載可能不均衡. 當遷移完成之後, 才能重新達到一個新的負載均衡的狀态.

桶在data server上分布時候的政策

       程式提供了兩種生成配置設定表的政策, 一種叫做負載均衡優先, 一種叫做位置安全優先: 我們先看負載優先政策. 當采用負載優先政策的時候, config server會盡量的把桶均勻的分布到各個data server上. 所謂盡量是指在不違背下面的原則的條件下盡量負載均衡. 1 每個桶必須有COPY_COUNT份資料 2 一個桶的各份資料不能在同一台主機上; 位置安全優先原則是說, 在不違背上面兩個原則的條件下, 還要滿足位置安全條件, 然後再考慮負載均衡. 位置資訊的擷取是通過 _pos_mask(參見安裝部署文檔中關于配置項的解釋) 計算得到. 一般我們通過控制 _pos_mask 來使得不同的機房具有不同的位置資訊. 那麼在位置安全優先的時候, 必須被滿足的條件要增加一條, 一個桶的各份資料不能都位于相同的一個位置(不在同一個機房). 這裡有一個問題, 假如隻有兩個機房, 機房1中有100台data server, 機房2中隻有1台data server. 這個時候, 機房2中data server的壓力必然會非常大. 于是這裡産生了一個控制參數 _build_diff_ratio(參見安裝部署文檔). 當機房差異比率大于這個配置值時, config server也不再build新表. 機房差異比率是如何計出來的呢? 首先找到機器最多的機房, 不妨設使RA, data server數量是SA. 那麼其餘的data server的數量記做SB. 則機房差異比率=|SA – SB|/SA. 因為一般我們線上系統配置的COPY_COUNT是3. 在這個情況下, 不妨設隻有兩個機房RA和RB, 那麼兩個機房什麼樣的data server數量是均衡的範圍呢? 當差異比率小于 0.5的時候是可以做到各台data server負載都完全均衡的.這裡有一點要注意, 假設RA機房有機器6台,RB有機器3台. 那麼差異比率 = 6 – 3 / 6 = 0.5. 這個時候如果進行擴容, 在機房A增加一台data server, 擴容後的差異比率 = 7 – 3 / 7 = 0.57. 也就是說, 隻在機器數多的機房增加data server會擴大差異比率. 如果我們的_build_diff_ratio配置值是0.5. 那麼進行這種擴容後, config server會拒絕再繼續build新表.

tair 的一緻性和可靠性問題

       分布式系統中的可靠性和一緻性是無法同時保證的, 因為我們必須允許網絡錯誤的發生. tair 采用複制技術來提高可靠性, 并且為了提高效率做了一些優化, 事實上在沒有錯誤發生的時候, tair 提供的是一種強一緻性. 但是在有data server發生故障的時候, 客戶有可能在一定時間視窗内讀不到最新的資料. 甚至發生最新資料丢失的情況.

tair提供的用戶端

    tair 的server端是C++寫的, 因為server和用戶端之間使用socket通信, 理論上隻要可以實作socket操作的語言都可以直接實作成tair用戶端. 目前實際提供的用戶端有java 和 C++. 用戶端隻需要知道config server的位置資訊就可以享受tair叢集提供的服務了.

Tair的未來

    我們将Tair開源,希望有更多的使用者能從我們開發的産品中受益,更希望依托社群的力量,使Tair有更廣闊的發展空間。

     Tair開源後,有很多使用者關心我們是否會持續維護這個項目。我們将Tair開源後,淘寶内部已經不再有私有的Tair分支,所有的開發和應用都基于開源分支。Tair在淘寶有非常廣的應用,我們内部有一個團隊,專門負責Tair的開發和維護,相信我們會和社群一起,将Tair越做越好。

    有很多使用者在淘寶開源平台上申請加入Tair項目,加入項目在我們的開源平台上意味着成為項目的送出者,可以向代碼庫直接送出代碼。是以我們暫時還沒有準許外部使用者加入,我們将在大家對Tair有更深入的了解後和社群一起決定是否準許加入項目的申請,在此之前,如果你有對代碼的改進,歡迎使用patch的方式送出給我們,我們将在review後決定是否合并到代碼庫。

   希望我們能和社群一起,将Tair做成一個真正對大家都有幫助的項目。

原文連結:http://www.infoq.com/cn/articles/taobao-tair/

                    Tair官網