2014-12-04

Understanding Cassandra Architecture

Reading Document : http://www.datastax.com/docs/1.0/cluster_architecture/index


Gossip

  • Cassandra 使用 gossip 協定來找出其它參與 Cassandra 叢集的節點位置和狀態資訊。
  • Gossip 訊息有版本號,比較老舊的訊息,不能覆寫較新的訊息。
  • 為了預防 gossip 溝通上的隔閡,在一個叢集內的所有節點都應該擁有相同的種子節點(seed nodes)清單。
  • Seed node 的目的只有在新的節點加入時啟動 gossip 程序,它也不是單點失敗 (Single point of failure) 的設定。
  • 每個節點都必須知道它自己的 token 值。當一個叢集被初始化時,應該要建立整個叢集的 tokens,並且為每個節點分配一個 token。之後,每個節點都會把它的 token 拿來跟其他節點溝通。
  • 錯誤偵測 (Failure detection) 是一個採取 gossip state 來決定的方法。錯誤偵測也被來避免客戶端請求被繞送到到不了的節點 (unreachable node)。
  • 透過 dynamic snitch,Cassandra 也能夠避免把客戶的請求,繞送到活著但效能不佳的節點。
  • Cassandra 使用一個累積(accrual)偵測機制,用來計算每一個節點的門檻值,這個門檻值必須考量到網路情況、工作量、或其它跟影響心跳感應率有關的條件。
  • 透過設定 phi_convict_threshold 屬性,來調整錯誤偵測的敏感度。目前的預設值已經是大部分情況下的最佳值。
  • 個節點的中斷不表示,這個節點從叢集中永遠離開,節點不會自動從 ring 中離開,其它的節點會定期的透過 gossip 和它聯繫,去看看它是否回來了。(如果要將一個節點,加入一個 ring 或從一個 ring 移掉,那麼就要使用 nodetool。)


Data Partitioning in Cassandra

  • Data Partitioning 決定資料如何分佈在叢集內的節點。
  • 與資料分散有關的三個要素:
    • Partitioner:決定哪個節點來存資料。
    • 資料副本數量:透過副本放置策略 (replica placement strategy) 來決定。
    • 叢集拓撲:節點數量,節點在機櫃 (rack) 的分佈和資料中心 (data center) 的數量。
  • 要決定一個 row 的第一個副本 (replica) 要存到哪一個節點,便要順時針方向走訪這個 ring 的每個節點,直到遇到一個節點的 token 值大於 row key 值。
  • 一個節點的責任區在於他自己和前面節點的那一段區域。
  • Cassandra 1.0 提供兩個 Partitioner。
    • RandomPartitioner
    • ByteOrderedPartitioner
  • RandomPartitioner 是預設的 partitioning strategy,在大部份的情況下是最佳選擇。
    • 把資料均勻的分佈在數個節點,row key 是用一個雜湊演算法所建立一個 MD5 的雜湊值。(雜湊值的範圍為 0 ~ 2127 - 1)
    • 另一個使用 RandomPartitioner 的好處是,簡單化了叢集負載平衡,因為每一個區塊的雜湊範圍平均接受了等量的資料。
  • ByteOrderedPartitioner 從字面上來看,這個 Partitioner 的 row key 是 bytes。
    • Datastax 強烈建議不要使用這個 Partitioner,原因如下:
      1) Sequential writes can cause hot spots
      如果你的應用程式傾向一次寫入或更新一批連續資料列,這些寫入的資料並不分散在整個叢集裡,也就是都存到單一個節點,這經常會是一個應用程式會有 處理與timestamped 資料有關的問題。

      2) More administrative overhead to load balance the cluster
      Ordered Partitioner 需要管理者去計算出 token 的範圍,以估算出 row key 的分散。

      3) Uneven load balancing for multiple column families
      若你的應用程式有很多列族,有個可能性是這些列族們有不同的 row key 並且有不同的資料分佈。
  • 佈署在多個 data center 的副本放置策略(replication placement strategy) 比較推薦的是 NetworkTopologyStrategy,這個策略對每個 data center 計算副本的放置。
    • 這個策略,為每一個列,藉由 token 值來分配節點以放置第一個副本,之後,要在同一個 data center 裡放置額外的副本,就必須以順時鐘方向走訪 ring 的節點,直到遇到在另一個 rack 的第一個節點。
    • 在 data center 內不均勻的資料分佈,會導致不均勻的資料分佈。
    • 要先確保每一個 data center 裡的每一個節點所獲得的 token 可以讓它們均勻分布在 ring 裡,這樣可以避免 row key 不均勻的分配在每一個 data center 裡。
    • 無論如何,你必須避免節點有相同的 token 值,而造成衝突,即使不在同一個叢集的節點。必須要確認每一個節點都有一個唯一值的 token。


Replication in Cassandra

  • Replication 是一個把資料複本儲存到多個節點的程序,用來確保可靠度和容錯。
  • Cassandra 的儲存複本稱為 replica (複製品;複寫),針對 row key 的每個 row 來存。
  • 這個策略將複本分散儲存到叢集內的一些節點,取決於叢集的拓撲 (topology)。
  • 叢集內複本的總數參考到複本因子(replication factor)。
  • 複本因子為 1 的意思是,針對每一筆資料列只會有1 筆複本在一個節點裡。複本因子為 2 的意思是,每一筆資料列有 2 筆複本,分別存到不同節點裡。
  • 所有複本一樣重要,沒有主要或次要複本的差別。
  • 個通則是,副本因子的數量不能超過叢集內節點的總數,當然你可以增加副本因子的數量,在之後增加節點。如果副本因子超過節點數,就無法寫成功,但讀取只要可以符合一致性等級(consistency level) 仍然可以成功。
  • 複本策略仰賴叢集設定 snitch
  • Replication Strategy 可用設定有:SimpleStrategy、NetworkTopologyStrategy
  • SimpleStrategy
    • 針對單一 data center 的話,就使用這個策略。
    • 若你透過 CLI 建立 keyspace 時,這是預設的複本放置策略。
      CREATE KEYSPACE myspace WITH placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy'
                              AND strategy_options = {replication_factor:3};
    • 這個策略放置第一個複本的依據是來自 partitioner,剩下的複本則是依序走訪 ring 中的節點,而不需要考慮機櫃 (rack) 或資料中心 (data center)。
    • 下圖顯示 3 個資料列的 3 個複本被放置在 4 個節點的叢集中。


















  • NetworkTopologyStrategy
    • 當你已經或想要佈署你的 Cassandra 叢集橫跨多個 data center。這個策略可以指定有你想要放置多少複本在每個 data center。
    • 當你想決定要將多少複本設置到每一個 data center 時,底下兩件事情是需要考慮的:
      1) 能夠滿足本地端的讀取,而不需要跨 data center
      2) 錯誤的情形
    • Two replicas in each data center
      這個設定能夠容忍一個複本群組的單點失效狀態,並允許在 consistency level 設為 1 時的本地端讀取。
    • Three replicas in each data center
      這個設定能夠在 consistency level 為 LOCAL_QUORUM 的情況下,容忍一個複本群組的單點失效狀態。或者,在 consistency level 設為 1 的情況下,容忍 data center 有多個失敗節點。
    • 每個 data center 都是獨立決定資料複本的放置,規則如下:
      1) 
      第一個複本,會根據 partitioner 來放置 (與 SimpleStrategy 一樣)
      2) 剩餘的複本會順時針走訪 ring 的每個節點,直到發現有不同的 rack 的節點。如果沒有這樣的節點,那麼就會放在同一個 rack 裡的其它節點。
    • 這個策略會嘗試將複本放到不同的 rack,因為在同一個 rack 的節點,有可能會同時失效 (斷電, 網路中斷)。
    • NetworkTopologyStrategy 仰賴 snitch 的設定,以正確地放置複本到 rack 和 data center。慎重的為你的叢集選擇 snitch 的類型,這個重要性可以讓你的叢集能夠正確地決定節點在你網路的位置。
    • OldNetworkTopologyStrategy 設定上的限制,只能夠指定多少複本要存到分別存到不同的 data center,不能夠像 NetworkTopologyStrategy 那樣可以個別設定哪一個 data center 可以存多少複本。
  • Snitch
    • Snitch 將 IP 對應到 rack 和 data center。
    • 它定義了,節點如何在整個網路拓撲裡,被群集在一起。
    • Cassandra 使用了這個資訊,盡可能以高效的方式,繞送 (route) 節點間的請求。
    • 在同一個叢集內的節點應該都要使用相同的 snitch 設定。
    • Snitch 的類型:
      1) SimpleSnitch不去識別 data center 或 rack 資訊,用在 single-data center 佈署。

      2) RackInferringSnitch
      RackInferringSnitch 猜測網路拓撲是依據八進位的節點 IP 位址。

       
      當定義你的 keyspace 的 strategy_options 時,使用第二個八進位的 IP 當做你 data center 的名稱。
      左圖表示,data center 的名稱是 100。
















      3) PropertyFileSnitch
      透過 rack 和 data center 決定節點的位置。透過 cassandra-topology.properties  來設定。
      使用這個 snitch 的原因有:節點 IP 會改變、有複雜的複本群組需求。

      4) EC2Snitch
      提供 Amazon EC2 佈署(single region)

      5) ECMRegionSnitch
      提供 Amazon EC2 佈署(multiple region)。
  • Dynamic Snitching
    • 預設上是啟用的,所有的 snitch 都使用一個動態 snitch 層,這個 snitch 監控讀的延遲 (read latency)以及試著不要將請求送到效能低下的節點。
    • 可以在 cassandra.yaml 針對每個節點,設定 dynamic snitch threshold 。

Cient Requests in Cassandra

  • 所有 Cassandra 節點的地位都是相同的,同一個 Client 的讀或寫的請求可以送到任何一個節點處理,當一個 Client 連到一個節點並且發起一個讀或寫的請求,這個節點就成為協調者 (coordinator) 用來處理特定客戶端操作。
  • 協調者的工作是:
    • 扮演代理 (proxy) 的角色,做為 Client 與複本節點 (replicas) 之間的代理人。
    • 決定 ring 裡的哪些節點應該取得請求,這必須依據 partitioner 和 replica placement strategy。
  • Write Requests:
    • Coordinator 將寫的請求發送給所有的 replicas,只要所有的複本節點是正常運作的,它們就會收到寫的請求,不論 Client 是否有指定的一致性等級 (consistency level)。
    • 在一個單一 data center 裡有一個帶有複本因子為 3 並擁有 10 個節點的 Cassandra 叢集,一個在進行的寫的請求將會跑到 3 個節點,以讓它們擁有那筆資料列的請求。
    • 如果 Client 指定這個寫入的 consistency level 是 ONE,第一個節點完成寫入後,回應了 coodinator,那麼隨後就會把成功訊息送回 Client。
    • 如果一個複本節點錯過了一個寫入的請求,那麼這筆資料列將會在後續,以 Cassandra 所提供的修復方式:hinted handoff、read repair、anti-entropy node repair,來修復。
  • Multi-Data Center Write Requests
    • 多 data center 佈署上,Cassandra 最佳化寫的效能上,在每個 data center 各選擇了一個 coordinator,透過它來處理寫入複本的請求,這樣的話,只要把寫入的請求送給每一個 data center 的 coordinator 就行了。.
    • 使用的 consistency level 是 ONE 或是 LOCAL_QUORUM,只有在同一個 data center 作為 coordinator 的節點必須要回應 client 的請求,以表示成功。這個方法,可以壁開地理性延遲的衝擊,影響回應 client 的時間。










  •  Read Requests
    • 有兩種讀的類型:直接讀的請求、背景 read repair 請求。
    • 要聯繫多個 replicas,由 Client 指定 consistency level 直接請求。而背景 read repair 請求則不需要一個直接的請求。
    • Read repair 請求確保所請求的資料列必須一致性的存在於所有的複本。
    • 如果 replicas 的節點都聯繫到了,從每個 replica 來的資料列就會在記憶體內做一致性的比較。若有 replica 是不一致的,接著就會發生一些事情:
      1) 
      不管 read_repair_chance 是否有設定,一個在前景的 read repair 會發生在資料上。
      2) Coordinator 使用擁最新資料的 replica (基於 timestamp) 並把結果傳遞到 client。
      3) 背景裡,coordinator 會比較剩下擁有那筆資料列的 replicas。
      4) 如果有不一致的 replica,會更新那筆資料列以反映最新寫入的資料值 (coordinator 會負責發起 "更新過期的 replica" 的操作)。
    • 這個程序就是 read repair。我們能夠針對每個列族設定 read repair (使用 read_repair_chance 預設上是開啟的)。

Planning a Cassandra Cluster Deployment

  • Hardware recommendations
    • Memory
      1) 最少要 8GB (最普遍)
      2) DataStax 建議大約要 16GB ~ 32GB
      3) Java heap size 最大值應該設定 8GB 或是你記憶體的一半 (要注意GC的衝擊)
      4) 若是再虛擬環境,至少設定 4GB
    • Disk
      1) 要考慮兩部份: 容量 (capacity) ─ 足夠的空間 和 I/O ─ 讀和寫的吞吐量。2) 大部份工作量,使用不昂貴的 SATA 硬碟以擴充容量,並且透過增加節點的方式,來擴充更多 I/O 的能力 (更多的 RAM)3) Solid-state drives (SSDs) 也是一個有效的替代品。4) 理想上,Cassandra 需要兩顆硬碟,一個提供 commit log,另一個提供 data directories。最低限度,commit log 應該在自己的 partition。5) Commit log disk ─ 這個硬碟不需要太大,但至少可以快到足以接收所有的寫入 (appends; sequential I/O)6) Data disks ─ 使用一個以上的硬碟以確保足夠大到能夠儲存 data volume,而且夠快以滿足資料不在記憶體快取的讀取,並且可以跟上 compaction。
      7) RAID ─ 在單一 data directory volume,compaction 會暫時的需要 100% 的硬碟剩餘空間。這意味,當將達到硬碟的 50% 容量時,你應該使用 RAID 或 RAID 10 提供給 data directory volumes 使用。RAID 也能在 I/O 熱點情況下,對使用單一 SSTable 有所幫助
      8) 擴充檔案系統 ─ 到 ext2 或 ext3, 最小的檔案大小是 2TB ( 64-bit kernel 情況下也是)。ext4 可達 16TB
    • Number of Nodes
      使用大量但資料少的節點比起使用少量但資料量大的節點好,這是因為在 compaction 期間,資料量大的節點會有潛在的瓶頸。
    • Network
      1) 
      Cassandra 是一個分散式的儲存體,在網路上的負載就是 read/write 請求的處理和複本資料分散的處理。
      2) 網路必須要能夠容納你需要的流量。
      3) 頻寬至少要 1Gbits。
      4) 將以下兩個介面分開設給不同 NIC
              - Thrift interface (listen_address )
              - RPC server interface (rpc_address)
      5) Cassandra 盡可能的會向同一個 rack 的節點抓 replica,選擇同一個 rack 的節點,勝過於遠端的 data center 的節點。
  • Node Configuration Options
    • Storage Settings
      在 Production 環境必須讓 commitlog_directory 與 data_file_directories 不同硬碟。
    • Gossip Settings
      控制節點如何參與叢集,以及節點如何被其它節點知道,設定有
      cluster_name:要加入這個叢集的節點都要設定一樣。listen_address:Cassandra 的 IP 位址。
      seeds:這個設定用來啟動 gossip 程序,每個節點都要有同樣的 IP 位址列表。
      storage_port:預設是 7000,在叢集內每一個節點都要一樣,這是用來做內部溝通的 port。
      initial_token:用來決定這個節點所負責的資料範圍。
    • Purging Gosssip State On a Node
      Gossip 資訊會被 persisted 在本地端用來立即重啟,而不用等待 gossip。
    • Partitioner Setting
      1) 你必須要確保每一個節點能夠大約有相同量的資料 (負載平衡)。2) 為每個節點,設定 partitioner ,並且設定一個 initial_token 值。3) Datastax 建議對所有叢集的佈署,使用 RandomPartitioner (default)。4) 在單一 data center,你可以分別為叢集內的每個節點計算 token。5) 
      再多個 data center,token 應該被分開計算,如同每個 data center 的負載平衡都是獨立的。
    • Snitch Settings1) Snitch 的責任,是在了解在你的網路拓撲裡的所有節點的位置。
      2) 他的影響是複本要放在哪裡,以及請求要怎麼在 replicas 之間繞送。
      3) endpoint_snitch 用來設定節點的 snitch,每個節點都應該要有確切的 snitch 設定。
      4) 在單一個 data center,使用 SimpleSnitch 通常就夠用。
      5) 
      如果之後你想要延伸到多個 rack 和多個 data center,也是很簡單的,只要在一開始的時候就選一個可以感知 rack 和 data center 的 snitch 就行。
    • Configuring the PropertyFileSnitch
      1) 
      PropertyFileSnitch 允許你去定義自己想要的 data center 和 rack 名稱。
      2) 
      在 cassandra-topology.properties 檔裡,可以定義網路細節,叢集內的每一個節點應該都要被描述在這個檔案裡,而且這個檔案在每個節點應該都要一樣。
  • Choosing Keyspace Replication Options
    • DataStax 建議,不管是單一 data center 或是多個 data center,選擇 NetworkTopologyStrategy 就好。它跟 SimpleStrategy 一樣容易使用,而且在未來也可以擴充到多個 data center。
    • 設定 NetworkTopologyStrategy 有一些選項,如在每個資料中心的複本數。
      即使是單一 data center 仍可使用。
    • UPDATE KEYSPACE gamecloud WITH placement_strategy =
                   'org.apache.cassandra.locator.NetworkTopologyStrategy'
      AND strategy_options={DC1:3};
    • Data center 的名稱應該要參考 snitch 的設定。
    • 一般的規則是,複本數不應該超過在複本群組內的節點數。然而,增加複本數,之後再增加節點數也是有可能的。當複本因子超過節點數,寫就會被拒絕,但是,讀取只要符合 consistency level 仍然沒有問題。當複本因子超過節點數,寫就會被拒絕,但是,讀取只要符合 consistency level 仍然沒有問題的。

沒有留言 :

張貼留言