Cassandra Vnodes在Cassandra 2.0-4.0中的演進

Vnodes簡短歷史

 

Vnodes又叫Virtual Nodes。是Cassandra在1.2版本里引入的功能,已經在生產環境中使用了近8年了。從2.0版本開始,由於默認配置裏num_tokens通常會設成256,因此若是你沒有修改過默認參數,那頗有可能你一直都在使用這個功能。html

 

當初引入vnodes主要是爲了改善增長節點時的靈活性。在pre-1.2時代(也就是沒有vnodes功能的時候),每次集羣擴容都必需要讓節點數翻倍,好比3個節點擴容到6個節點,下次須要擴容的時候再增長到12個節點。這是由於每一個節點都只擁有一個token範圍,增長新節點的時候就是把每一個token範圍一分爲二,讓每一個新節點都負責一半的token範圍。可是,若是要保證整個集羣的token範圍是均勻分佈的,每次新增長的節點數須要跟已有的節點數一致。這樣每次翻倍的擴容方式顯然對運維和資源計劃形成了很大的挑戰。node

有了vnodes之後,默認狀況下每一個物理節點會負責256個token範圍,增長一個新的節點只須要從每一個已有節點的256個token範圍中取出若干個,合起來湊成256個新token範圍分配給新來的節點就行了。整個集羣的token範圍分佈仍是均勻的。算法

 

Vnodes功能在1.2版推出之後,受到了廣大生產環境Cassandra運維人員的歡迎,因此在2.0版裏,vnodes功能被默認啓用,並且這個num_tokens參數默認的被配置成了256。數據庫

 

Vnodes帶來的問題

 

但是,隨着愈來愈多的Cassandra集羣開始在生產環境裏使用vnodes,它的一些不盡如人意的地方逐漸開始體現出來。apache


最大的一個問題,體如今運行nodetool repair的時候:由於repair是按照節點的token範圍來安排一個個的小任務,以進行副本之間的比較和修復工做;一個節點擁有的token範圍的數量越多,這樣的小任務就越多;當一個節點擁有了256個token範圍,而且存儲了幾百GB數據的時候,每一個keyspace的repair小任務加起來所花的時間動輒就會達到幾小時甚至數天;生產環境中通常會有幾個keyspace,再加上nodetool repair -pr須要10天以內在全部的節點上都運行一輪,這會對運維帶來比較大的困難。bootstrap


另外,當一個節點擁有了256個token範圍時,增長新節點的bootstrap過程也會帶來多得多的SSTable數量,須要消耗大量的CPU才能把這些大量的小SSTable消化掉。運維


比較棘手的是,這些問題並非簡單的在配置中下降num_tokens取值就能夠解決的。把num_tokens設置成一個更小的值好比16,固然會大大改善repair和bootstrap,可是這樣面臨着兩個主要的挑戰:測試

  1. Cassandra 1.2原有的vnodes算法設計通常假設每一個節點會有數百個token範圍,使用的是隨機從新分配的算法,token範圍數量多的時候沒問題,可是token範圍數量下降到十幾個的時候,很容易出現數據不均勻分配的狀況(以下圖所示),並且節點增長的越多,這種不均勻的現象會越嚴重;
  2. 一個數據中心的vnodes數量在數據中心初始化的時候就肯定了,未來想要改的話,只能啓用新的數據中心遷移數據。
Datacenter: us-east-1
=====================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address        Load   	  Tokens   	Owns (effective)  Host ID                               Rack
UN  172.1*.3*.1*   1.55 TiB    16       	4.1%          	f683ab0e-a687-400f-80fb-28f7b4471ffc  b
UN  172.1*.3*.1**  1.05 TiB    16       	2.9%          	2097cd01-4161-44a9-a944-d5445e8c5e02  c
UN  172.1*.3*.2*   720.26 GiB  16       	3.0%  	        e6593e3a-bb1c-499c-a99b-73781cfcd076  c
UN  172.1*.3*.2*   1.3 TiB     16       	4.0%          	99670a7c-a55f-4a43-8e4b-a3cccc71f08f  a
UN  172.1*.3*.1**  961.67 GiB  16       	3.2%          	a4bb1648-3582-4f05-a1e6-3125e9c3c46c  b
UN  172.1*.3*.1**  1.29 TiB    16       	4.4%          	890e98d3-d88d-4d8c-89b4-7e9444bb69be  a
UN  172.1*.3*.2*   1.42 TiB    16       	4.0%          	3f2817da-9dc5-4122-8977-5d3d93669b4e  c
UN  172.1*.3*.1**  710.53 GiB  16       	4.9%       	72405162-f121-46d4-a220-a1fd2db868e8  b
UN  172.1*.3*.3*   2.38 TiB    16       	7.1%          	f15c768c-0175-4646-bc68-7b20a74d7f0d  b
UN  172.1*.3*.1**  2.68 TiB    16       	7.3%          	2f444803-7787-474a-9ed9-8555147023d3  c
UN  172.1*.3*.1**  1.59 TiB    16       	5.2%          	bd838966-23e2-44b2-986c-729ede679604  c
UN  172.1*.3*.5*   808.48 GiB  16       	4.3%          	1fe83c82-1fb2-4570-9aae-7805370f24b0  b

 

新版本是怎樣解決問題的

 

針對上面提到的第一個挑戰,Cassandra 3.0裏啓用了新的token分配算法,而且增長了一個新的參數allocate_tokens_for_keyspace,這個貪心算法雖然不能徹底避免token範圍熱點的狀況出現,可是它的最大好處是,在集羣中繼續增長節點的話,token範圍的熱點會愈來愈少,數據分配會愈來愈均勻。spa


Cassandra 4.0在此基礎之上又作了更多的改進,3.0裏的參數allocate_tokens_for_keyspace將被allocate_tokens_for_local_replication_factor取代。這樣配置的工做更加簡單,由於再也不須要在初始化一個數據中心的時候提供一個keyspace的名字。設計


有了這樣算法的加持,社區也逐漸開始建議全部用戶在新建數據庫的時候,把num_tokens參數直接改爲一個比256小得多的取值。最新的討論能夠看這個JIRA和這個郵件列表的討論。社區如今達成的共識是在4.0版本中把默認的num_tokens設置成16,而且默認啓用新的token分配算法。若是4.0 release測試過程再也不發現新的問題,在4.0正式版發佈之後,全部運行新版本的集羣將會是每節點擁有16個token範圍,以兼顧運維操做的高效,和數據分配的均勻。

相關文章
相關標籤/搜索