pika集羣水平擴展——讓性能容量再也不受限

背景

Pika是一個可持久化的大容量redis存儲服務,兼容string、hash、list、zset、set的絕大部分接口(兼容詳情),解決redis因爲存儲數據量巨大而致使內存不夠用的容量瓶頸。用戶能夠不修改任何代碼從redis遷移到pika服務。具備良好的兼容性和穩定性,被360公司內部使用超過3000實例,github社區超過3.8K star。因爲單機pika容量受限於單塊硬盤容量的大小,360公司業務和社區對分佈式pika集羣的需求愈來愈強烈,所以咱們推出了原生分佈式pika集羣,發佈pika版本v3.4。與pika+codis集羣方案相比,codis對pika建立和管理slot操做的支持並不友好,須要運維人員大量介入。而pika原生集羣則不須要額外部署codis-proxy模塊。git

集羣部署結構

image.png

以3個pika節點的集羣爲例,集羣部署結構如上圖所示:github

  1. 部署Etcd集羣做爲pika manager的元信息存儲。
  2. 3臺物理機上分別部署pika manager,並配置好Etcd的服務端口。Pika manager會向etcd註冊,並爭搶成爲leader。集羣中有且只有一個pika manager可以成爲leader並向etcd中寫入集羣數據。
  3. 3臺物理機上分別部署pika節點,而後把pika節點的信息添加到pika manager中。
  4. 爲了負載均衡,把pika的服務端口註冊到LVS中。

數據分佈

image.png

爲了對數據按照業務進行隔離,Pika集羣引入table的概念,不一樣的業務數據存儲在不一樣的table中。業務數據按照key的hash值存儲到對應的slot上面。每個slot會有多個副本,從而造成一個replication group。replication group中的全部slot副本具備相同的slot ID,其中一個slot副本是leader,其餘副本爲follower。爲了保證數據的一致性,只有leader提供讀寫服務。可使用pika manager對slot進行調度遷移,使數據和讀寫壓力均勻的分散到整個pika集羣中,從而保證了整個集羣資源的充分利用而且能夠根據業務壓力和存儲容量的須要進行水平擴容和縮容。redis

pika使用rocksdb做爲存儲引擎,每一個slot會建立對應的rocksdb。pika中的每一個slot都支持讀寫redis 5種數據結構。所以數據遷移的時候會特別方便,只需遷移pika中的slot便可。但同時也存在資源佔用過多的問題。目前的pika在建立slot的時候會默認建立5個rocksdb,分別來存儲5種數據結構。在table中含有大量slot或者建立大量table的時候會使單個pika節點含有多個slot,進而建立過多的rocksdb實例,佔用了過多系統資源。在後續版本中一方面會支持建立slot的時候根據業務須要建立一種或多種數據結構,另外一方面會持續對pika中的blackwidow接口層進行優化,減小對rocksdb的使用。後端

數據處理

image.png

  1. 當pika節點接收到用戶請求時,解析層處理解析redis協議,並把解析好的結果交給router層進行判斷。
  2. router根據key的hash結果找到key對應的slot,並判斷slot是否在本地節點上。
  3. 若是key所在的slot在其餘節點,則根據請求建立一個task放入隊列中,並把請求轉發給peer節點來處理。當task接收到請求的處理結果後把請求返回給客戶端。
  4. 若是key所在的slot屬於本地節點,就直接本地處理請求並返回給客戶端。
  5. 對於須要本地處理的寫請求,先經過replication manager模塊寫binlog,異步複製到其餘slot副本。process layer根據一致性的要求,寫入leader slot。其中blackwidow是對rocksdb的接口封裝。

咱們把proxy內嵌的pika中,不須要單獨部署。與redis cluster相比,客戶端不須要感知proxy的存在,只需像使用單機同樣使用集羣。能夠把pika節點的服務端口掛載到LVS中,實現壓力在整個集羣的負載均衡。數據結構

日誌複製

pika中replication manager模塊負責日誌的主從同步。爲了兼容redis,pika支持非一致日誌複製,leader slot直接在db中寫入數據而無需等待從follower slot的ack應答。同時也支持raft一致性協議方式的日誌複製,須要知足收到大多數副本的ack才寫入db。負載均衡

非一致日誌複製

image.png

在非一致場景下處理流程以下:運維

  1. 處理線程接收到客戶端的請求,直接加鎖後寫入binlog和並操做db。
  2. 處理線程返回客戶端response。
  3. 輔助線程發送BinlogSync同步請求給follower slot,同步日誌。
  4. follower slot返回BinlogSyncAck報告同步狀況。
一致性日誌複製

image.png

在一致性日誌複製場景下:異步

  1. 處理線程把客戶端請求寫入binlog文件
  2. 經過發送BinlogSync請求向從庫同步
  3. 從庫返回BinlogSyncAck報告同步情況
  4. 檢查從庫應答知足大多數後將相應的請求寫入db
  5. 將response返回客戶端

集羣元數據處理

咱們在codis-dashboard的基礎上二次開發了pika manager(簡稱PM),做爲整個集羣的全局控制節點,用來部署和調度管理集羣。PM裏保存了整個集羣的元數據及路由信息。分佈式

  • 增長了集羣建立多表的功能,方便業務根據表的不一樣來實現業務數據隔離。
  • 支持建立表時指定slot數目和副本數目,方便運維根據業務的規模和故障容忍度建立table。
  • 從邏輯上把group的概念改成replication group,使得原來的進程級別的數據和日誌複製轉變爲slot級別的複製。
  • 支持建立table時建立密碼來隔離業務的使用。客戶端只須要執行auth和select語句就能夠認證並對指定的table進行操做。
  • 支持slot遷移,方便根據業務需求進行擴容和縮容。
  • 集成哨兵模塊,PM會不斷的向集羣中的pika節點發送心跳,監測存活狀態。當PM發現leader slot down時,會自動提高binlog偏移最大的slave slot爲leader。
  • 存儲後端支持元數據寫入etcd,保證元數據的高可用。
  • pika manager經過不斷向etcd爭搶鎖來成爲leader,來實現pika manager的高可用。

後記

pika原生集羣的推出解決了單機pika受限於磁盤容量的限制,能夠按照業務的需求進行水平擴容。但仍然有一些缺陷,如基於raft的內部自動選主功能的缺失,基於range的數據分佈,及監控信息的展板等功能。後續版本咱們會一一解決這些問題。優化

相關文章
相關標籤/搜索