tair(二)--概述

1. Tair總述

1.1 系統架構

一個Tair集羣主要包括3個必選模塊:configserver、dataserver和client,一個可選模塊:invalidserver。通常情況下,一個集羣中包含2臺configserver及多臺dataServer。兩臺configserver互爲主備並通過維護和dataserver之間的心跳獲知集羣中存活可用的dataserver,構建數據在集羣中的分佈信息(對照表)。dataserver負責數據的存儲,並按照configserver的指示完成數據的複製和遷移工作。client在啓動的時候,從configserver獲取數據分佈信息,根據數據分佈信息和相應的dataserver交互完成用戶的請求。invalidserver主要負責對等集羣的刪除和隱藏操作,保證對等集羣的數據一致。

從架構上看,configserver的角色類似於傳統應用系統的中心節點,整個集羣服務依賴於configserver的正常工作。但實際上相對來說,tair的configserver是非常輕量級的,當正在工作的服務器宕機的時候另外一臺會在秒級別時間內自動接管。而且,如果出現兩臺服務器同時宕機的最惡劣情況,只要應用服務器沒有新的變化, tair依然服務正常。而有了configserver這個中心節點,帶來的好處就是應用在使用的時候只需要配置configserver的地址(現在可以直接配置Diamond key),而不需要知道內部節點的情況。

1.1.1 ConfigServer的功能

1) 通過維護和dataserver心跳來獲知集羣中存活節點的信息
2) 根據存活節點的信息來構建數據在集羣中的分佈表。
3) 提供數據分佈表的查詢服務。
4) 調度dataserver之間的數據遷移、複製。

1.1.2 DataServer的功能

1) 提供存儲引擎
2) 接受client的put/get/remove等操作
3) 執行數據遷移,複製等
4) 插件:在接受請求的時候處理一些自定義功能
5) 訪問統計

1.1.3 InvalidServer的功能

1) 接收來自client的invalid/hide等請求後,對屬於同一組的集羣(雙機房獨立集羣部署方式)做delete/hide操作,保證同一組集羣的一致。
2) 集羣斷網之後的,髒數據清理。
3) 訪問統計。

1.1.4 client的功能

1) 在應用端提供訪問Tair集羣的接口。
2) 更新並緩存數據分佈表和invalidserver地址等。
3) LocalCache,避免過熱數據訪問影響tair集羣服務。
4) 流控

1.2 存儲引擎與應用場景

Tair經過這兩年的發展演進,除了應用於cache緩存外,在存儲(持久化)上支持的應用需求也越來越廣泛。現在主要有mdb,rdb,ldb三種存儲引擎。

1.2.1 mdb

定位於cache緩存,類似於memcache。
支持k/v存取和prefix操作

1.2.1.1 mdb的應用場景
在實際業務中,大部分當緩存用(後端有DB之類的數據源)。
也可用做大訪問少量臨時數據的存儲(例如session登錄,防攻擊統計等)。
集團內絕對多數cache服務都是採用的tair mdb。

1.2.2 rdb

定位於cache緩存,採用了redis的內存存儲結構。
支持k/v,list,hash,set,sortedset等數據結構。

1.2.2.1 rdb的應用場景
適用於需要高速訪問某些數據結構的應用,例如SNS中常見的的粉絲存儲就可以採用set等結構;或者存儲一個商品的多個屬性(hashmap);高效的消息隊列(list)等。現在有30個左右的應用在使用rdb服務。

1.2.3 ldb

定位於高性能存儲,並可選擇內嵌mdb cache加速,這種情況下cache與持久化存儲的數據一致性由tair進行維護。 支持k/v,prefix等數據結構。今後將支持list,hash,set,sortedset等redis支持的數據結構。

1.2.3.1 ldb的應用場景
存儲,裏面可以細分如下場景:
1) 持續大數據量的存入讀取,類似淘寶交易快照。
2) 高頻度的更新讀取,例如計數器,庫存等。
3) 離線大批量數據導入後做查詢。參見fastdump
也可以用作cache:
數據量大,響應時間敏感度不高的cache需求可以採用。例如天貓實時推薦。

1.3 基本概念

1.3.1 configID

唯一標識一個tair集羣,每個集羣都有一個對應的configID,在當前的大部分應用情況下configID是存放在diamond中的,對應了該集羣的configserver地址和groupname。業務在初始化tairclient的時候需要配置此ConfigID。

1.3.2 namespace

又稱area, 是tair中分配給應用的一個內存或者持久化存儲區域, 可以認爲應用的數據存在自己的namespace中。 
同一集羣(同一個configID)中namespace是唯一的。
通過引入namespace,我們可以支持不同的應用在同集羣中使用相同的key來存放數據,也就是key相同,但內容不會衝突。一個namespace下是如果存放相同的key,那麼內容會受到影響,在簡單K/V形式下會被覆蓋,rdb等帶有數據結構的存儲引擎內容會根據不同的接口發生不同的變化。

1.3.3 quota配額

對應了每個namespace儲存區的大小限制,超過配額後數據將面臨最近最少使用(LRU)的淘汰。
持久化引擎(ldb)本身沒有配額,ldb由於自帶了mdb cache,所以也可以設置cache的配額。超過配額後,在內置的mdb內部進行淘汰。

1.3.3.1 配額是怎樣計算的
配額大小直接影響數據的命中率和資源利用效率,業務方需要給出一個合適的值,通常的計算方法是評估在保證一定命中率情況下所需要的記錄條數,這樣配額大小即爲: 記錄條數 * 平均單條記錄大小。

1.3.3.2 管理員如何配置配額
單份數據情況下,業務提供的配額就是需要配置在Tair系統中的配額。但對於多備份,在系統中實際計算的配額爲: 業務配額 * 備份數

1.3.4 expireTime:過期時間

expiredTime 是指數據的過期時間,當超過過期時間之後,數據將對應用不可見,這個設置同樣影響到應用的命中率和資源利用率。不同的存儲引擎有不同的策略清理掉過期的數據。調用接口時,expiredTime單位是秒,可以是相對時間(比如:30s),也可以是絕對時間(比如:當天23時,轉換成距1970-1-1 00:00:00的秒數)。 小於0,不更改之前的過期時間
如果不傳或者傳入0,則表示數據永不過期;
大於0小於當前時間戳是相對時間過期;
大於當前時間戳是絕對時間過期;

1.3.5 version

Tair中存儲的每個數據都有版本號,版本號在每次更新後都會遞增,相應的,在Tair put接口中也有此version參數,這個參數是爲了解決併發更新同一個數據而設置的,類似於樂觀鎖。
很多情況下,更新數據是先get,修改get回來的數據,然後put回系統。如果有多個客戶端get到同一份數據,都對其修改並保存,那麼先保存的修改就會被後到達的修改覆蓋,從而導致數據一致性問題,在大部分情況下應用能夠接受,但在少量特殊情況下,這個是我們不希望發生的。
比如系統中有一個值”1”, 現在A和B客戶端同時都取到了這個值。之後A和B客戶端都想改動這個值,假設A要改成12,B要改成13,如果不加控制的話,無論A和B誰先更新成功,它的更新都會被後到的更新覆蓋。Tair引入的version機制避免了這樣的問題。剛剛的例子中,假設A和B同時取到數據,當時版本號是10,A先更新,更新成功後,值爲12,版本爲11。當B更新的時候,由於其基於的版本號是10,此時服務器會拒絕更新,返回version error,從而避免A的更新被覆蓋。B可以選擇get新版本的value,然後在其基礎上修改,也可以選擇強行更新。

1.3.5.1 如何獲取到當前key的version
get接口返回的是DataEntry對象,該對象中包含get到的數據的版本號,可以通過getVersion()接口獲得該版本號。在put時,將該版本號作爲put的參數即可。 如果不考慮版本問題,則可設置version參數爲0,系統將強行覆蓋數據,即使版本不一致。

1.3.5.2 version是如何改變的
Version改變的邏輯如下:
1) 如果put新數據且沒有設置版本號,會自動將版本設置成1。
2) 如果put是更新老數據且沒有版本號,或者put傳來的參數版本與當前版本一致,版本號自增1。
3) 如果put是更新老數據且傳來的參數版本與當前版本不一致,更新失敗,返回VersionError。
4) put時傳入的version參數爲0,則強制更新成功,版本號自增1。

1.3.5.3 version返回不一致的時候,該如何處理
如果更新所基於的version和系統中當前的版本不一致,則服務器會返回ResultCode.VERERROR。 這時你可以重新get數據,然後在新版本的數據上修改;或者設置version爲0重新請求,以達到強制更新的效果,應用可以根據自身對數據一致性的要求在這兩種策略間進行選擇。

1.3.5.4 version具體使用案例
如果應用有10個client會對key進行併發put,那麼操作過程如下: 
1) get key。如果get key成功,則進入步驟2;如果數據不存在,則進入步驟3. 
2) 在調用put的時候將get key返回的verison重新傳入put接口。服務端根據version是否匹配來返回client是否put成功。 
3) get key數據不存在,則新put數據。此時傳入的version必須不是0和1,其他的值都可以(例如1000,要保證所有client是一套邏輯)。因爲傳入0,tair會認爲強制覆蓋;而傳入1,第一個client寫入會成功,但是新寫入時服務端的version以0開始計數啊,所以此時version也是1,所以下一個到來的client寫入也會成功,這樣造成了衝突

1.3.5.5 version分佈式鎖
Tair中存在該key,則認爲該key所代表的鎖已被lock;不存在該key,在未加鎖。操作過程和上面相似。業務方可以在put的時候增加expire,已避免該鎖被長期鎖住。
當然業務方在選擇這種策略的情況下需要考慮並處理Tair宕機帶來的鎖丟失的情況。

1.3.5.6 什麼情況下需要使用version
業務對數據一致性有較高的要求,並且訪問併發高,那麼通過version可以避免數據的意外結果。
如果不關心併發,那麼建議不傳入version或者直接傳0。

1.4 集羣部署方式

Tair通過多種集羣部署方式,來滿足各類應用的容災需求。
下面所述的雙機房可以擴展到多機房,現階段基本還是採用的雙機房。
現總共有4種方式:
mdb存儲引擎適用於雙機房單集羣單份,雙機房獨立集羣,雙機房單集羣雙份。
rdb存儲引擎適用於雙機房單集羣單份。
ldb存儲引擎適用於雙機房主備集羣,雙機房單集羣單份。

1.4.1 雙機房單集羣單份

雙機房單集羣單備份數是指,該Tair集羣部署在兩個機房中(也就是該Tair集羣的機器分別在兩個機房), 數據存儲份數爲1, 該類型集羣部署示意圖如下所示。數據服務器(Dataserver)分佈在兩個機房中,他們都屬於同一集羣。

使用場景:
1) 後端有無數據源都可。
2) 後端有數據源,且更新比例很高的場景。
優點:
1) 服務器存在於雙機房,任一機房宕機保持可用。
2) 單份數據,無論應用在哪個機房,看到的都是同一個數據。
缺點:
1) 應用服務器會跨機房訪問。如上圖,並假設應用服務器在cm3和cm4,那麼cm3的應用服務器也可能調用到cm4的tair機器,cm4的亦然。
2) 當一邊機房出現故障時,tair中的數據會失效一半(一半這個數值是按兩邊機房tair機器數相同估計的,如果不相同,則按對應比例估算)
該部署方式,應用在刪除數據時,只需要調用delete即可,無需調用invalid。當然,調用invalid也可,這種方式下會直接退化到delete。

1.4.2 雙機房獨立集羣

雙機房獨立集羣是指,在兩個機房中同時部署2個獨立的Tair集羣,這兩個集羣沒有直接關係。下圖是一個典型的雙機房獨立集部署示意圖,可以看到,cm3和cm4各有一個完整的tair集羣(2個configserver+多個dataserver)。圖中還多了一個invalidserver的角色, invalidserver接收客戶端的invalid或者hide請求後,會對各機房內的集羣進行delete或者hide操作,以此保障Tair中的數據和後端數據源保持一致的。

適用場景:
1) 後端必須要有數據源,否則則退化成單機房集羣,Tair集羣本身不做同步。
2) 讀寫比不能過小,不然可能會帶來Tair命中率降低。例如某個key,在數據庫中被頻繁更新,那麼此時應用必須調用invalid來確保Tair和DB的一致性。此時應用讀Tair一直會不命中,導致整體命中率低,可能造成DB壓力比較大。 如果依然有疑問的話,請聯繫 tair答疑。
優點:
1) 每個機房擁有獨立Tair集羣,應用在哪個機房就訪問相同機房的Tair集羣,不會出現跨機房調用和流量。
2) 單邊機房故障,不會影響業務訪問tair命中率。
缺點:
1) 後端必須要有數據源,也就是這種部署方式下,Tair必然是當作傳統意義上的cache存在的。因爲Tair mdb集羣之間本身不會做數據同步,多集羣間一致性保證依賴於後端數據源,如DB。
2) 當後端數據源數據發生更新後,業務不能直接把數據put到Tair,而是先需要調用invalid接口來失效這些對等集羣中的數據(來保持各Tair集羣的數據和後端數據源的一致性)。之後業務可以把數據put到當前Tair集羣(注意:只會put到本機房的Tair集羣,不會put到對端集羣)或者在讀Tair時發生not exist的時候從後端數據源取來放入Tair。

1.4.3 雙機房單集羣雙份

雙機房單集羣雙份,是指一個Tair集羣部署在2個機房中,數據保存2份,並且同一數據的2個備份不會放在同一個數據服務器上。根據數據分佈策略的不同,還可以將同一份數據的不同備份分佈到不同的機房上。該類型的集羣部署方式與雙機房單集羣單份數據的部署方式一樣。其不同之處,數據保存份數不一樣。該類型集羣部署方式示意圖如下圖所示,數據服務器分別部署在兩個不同的機房裏,所有的數據服務器都被相同的配置服務器管理,在邏輯上,他們構成一個獨立的集羣。

現只有tbsession集羣使用了這種部署方式。
適用場景:
後端無數據源,臨時數據的存放,非cache。
cache類應用推薦使用雙機房獨立集羣和雙機房單集羣單份部署方式。
優點:
1) 數據存放兩份,數據安全性有一定保障。但由於存儲引擎是mdb,數據存放在內存中,無法絕對保證數據不丟失。
2) 當一邊機房故障時,另外一邊機房依然可以服務,並且數據不丟失。
缺點:
1) 如果機房間網絡出現異常情況,依然有較小几率丟失數據。

1.4.4 雙機房主備集羣

這種部署方式中,存在一個主集羣和一個備份集羣,分別在兩個機房中。如下圖所示,不妨假設CM3中部署的是主集羣,CM4中部署的是備份集羣。那麼,在正常情況下,用戶只使用主集羣,讀寫數據都與主集羣交互。主備集羣會自動同步數據(不需要業務去更新兩邊),保證兩個機房數據的最終一致性。當一個機房發生故障後,備集羣會自動切換成主集羣,提供服務,保證系統可用性。

適用場景:
該方式只在ldb存儲引擎中存在,也就是業務將Tair當作最終存儲使用。我們會在當前主集羣存兩份數據,並由Tair異步將數據更新到備集羣,確保數據安全和服務可用。
優點:
1) 數據安全和服務可用性高。
2) 用戶調用方便,無需考慮多集羣間數據一致性的問題。


轉自:http://code.taobao.org/p/tair/wiki/intro2/

發佈了66 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章