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
以3個pika節點的集羣爲例,集羣部署結構如上圖所示:github
爲了對數據按照業務進行隔離,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的使用。後端
咱們把proxy內嵌的pika中,不須要單獨部署。與redis cluster相比,客戶端不須要感知proxy的存在,只需像使用單機同樣使用集羣。能夠把pika節點的服務端口掛載到LVS中,實現壓力在整個集羣的負載均衡。數據結構
pika中replication manager模塊負責日誌的主從同步。爲了兼容redis,pika支持非一致日誌複製,leader slot直接在db中寫入數據而無需等待從follower slot的ack應答。同時也支持raft一致性協議方式的日誌複製,須要知足收到大多數副本的ack才寫入db。負載均衡
在非一致場景下處理流程以下:運維
在一致性日誌複製場景下:異步
咱們在codis-dashboard的基礎上二次開發了pika manager(簡稱PM),做爲整個集羣的全局控制節點,用來部署和調度管理集羣。PM裏保存了整個集羣的元數據及路由信息。分佈式
pika原生集羣的推出解決了單機pika受限於磁盤容量的限制,能夠按照業務的需求進行水平擴容。但仍然有一些缺陷,如基於raft的內部自動選主功能的缺失,基於range的數據分佈,及監控信息的展板等功能。後續版本咱們會一一解決這些問題。優化