Codis 的設計與實現 Part 2

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

多 Proxy 架構

在 Codis 的設計中, Proxy 被設計成無狀態的,用戶端串連任何一個 Proxy 都是一樣的。而且每個 Proxy 啟動的時候,會在 Zookeeper 上註冊一個臨時節點, 所以用戶端甚至可以根據這個特性實現 HA (其實我在豌豆莢內部就寫了一個基於 Jedis 的 Codis HA RoundRobinPool)

當然,這個設計帶來的好處是,請求可以被負載平衡,而且在整個系統中不會出現單點。 但是,問題來了,由於 Codis 是動態擴縮容的功能的, 當 Codis 在進行資料移轉的過程中,如何保證任意一個 Proxy 都不會讀到老的或者錯誤的資料?

解釋這個問題之前,我想先介紹一下 Codis 的資料存放區方式和關於資料移轉的一些前置知識:

  • 資料被根據key,分布在 1024 個 slot 中, slot 是一個虛擬概念,資料存放區在實際的多個 codis-server (codis 修改版的 redis-server) 中,每個 codis-server 負責一部分key-value資料, 雜湊演算法是 crc32(key) % 1024
  • 資料移轉是由 codis-config 發起的,在 codis-config 看來,資料移轉的最小單位是 slot
  • 對於 codis-server 來說,沒有任何分布式邏輯在其中, 只是實現了幾個關於資料轉送的指令: slotsmgrtone, slotsmgrt…. 其主要的作用是:隨機選取特定 slot 中的一個 key-value pair, 傳輸給另外一個 codis-server, 傳輸成功後,把本地的這個 key-value pair 刪除, 注意, 這個整個操作是原子的。

所以,這就決定了 Codis 並不太適合 key 少,但是 value 特別大的應用, 而且你的 key 越少, value 越大,最後就會退化成單個 redis 的模型 (效能還不如 raw redis),所以 Codis 更適合海量 Key, value比較小 (<= 1 MB) 的應用。

為什麼 codis-server 的資料移轉是一個個key的,而不是類似很多其他分布式系統,採用 replication 的方式? 我認為,對於 redis 這種系統來說,實現 replication 不太經濟, 首先,你需要 rdb dump 吧? 在 redis 裡面所有的操作嚴格來說都是串列的(單執行緒模式決定),所以dump資料是需要 fork 一個新進程的, 否則如果直接 SAVE 會阻塞唯一的主線程,同時還得考慮dump過程和傳輸過程中產生的新資料的同步的問題, 實現起來比較複雜。所以我們每次只原子的遷走一個 key,不會把主線程 block 住, redis 操作的是記憶體,批量的一次性寫入和分多次set幾乎沒有區別(對於單機而言), 而且這個模型還避免了遷移過程中的資料更新同步的問題,因為由於遷移一個 key 的操作是原子的, 對於這個 redis-server 來說, 在完成這次遷移指令之前,是不會響應其他請求的。 所以保證了資料的安全。

一次典型的遷移流程:

  1. codis-config 發起遷移指令如 pre_migrate slot_1 to group 2

  2. codis-config 等待所有的 proxy 回複收到遷移指令, 如果某台 proxy 沒有響應, 則標記其下線 (由於proxy啟動時會在zk上註冊一個臨時節點, 如果這個proxy掛了, 正常來說, 這個臨時節點也會刪除, 在codis-config發現無響應後, codis-config會等待30s, 等待其下線, 如果還沒下線或者仍然沒有響應, 則codis-config 將不會釋放鎖, 通知管理員出問題了) 相當於一個2階段提交

  3. codis-config 標記slot_1的狀態為 migrate, 服務該slot的server group改為group2, 同時codis-config向group1的redis機器不斷髮送 SLOTSMGRT 命令, target參數是group2的機器, 直到group1中沒有剩餘的屬於slot_1的key

  4. 遷移過程中, 如果用戶端請求 slot_1 的 key 資料, proxy 會將請求轉寄到group2上, proxy會先在group1上強行執行一次 MIGRATE key 將這個索引值提前遷移過來. 然後再到group2上正常讀取

  5. 遷移完成, 標記slot_1狀態為online

關鍵點:

  1. 所有的操作命令,都通過 Zookeeper 中轉,所有的路由表,都放置在 ZooKeeper 中,確保任意一個 proxy 的視圖都是一樣的。

  2. codis-config 在實際修改slot狀態之前,會確保所有的 proxy 收到這個遷移請求。

  3. 在用戶端讀取正在遷移的slot內的資料之前, 會強制在源redis是執行一下遷移這個key的操作。

這兩點保證了,proxy 在讀取資料的時候,總是能在遷移的目標機上命中這個 key。

這就是 Codis 如何進行安全的資料移轉的過程。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.