最近在項目中需要在多機之間共享一些集合,hash等有類型的資料結構,如果基于mysql來存儲的話需要預先定義一系清單結構并維護表結構和資料結構的一緻性,後續還需要根據時間對資料庫做舊資料清理工作,是以開始調研一些能滿足下列需求的存儲引擎。
具有高可用,持久化的特性。
資料可以設定失效時間,友善自動資料清理。
支援常用資料結構,如集合,有序集合,hash map,清單等。
支援事務操作,友善原子化的對多個key進行操作。
有python,golang語言的用戶端。
通過對公司内部的tair,開源的redis,memcache,leveldb, mongodb等産品進行比較,感覺redis最符合需求,現将我對redis-3.2的了解和使用方法總結一下。
非持久化的獨立部署方式:
這種使用方式主要的使用場景是使用redis做為cache叢集,存儲可以丢失的cache資料,首要考慮目标是速度,不考慮持久化。典型的使用方式如下:

所有資料都在記憶體中,不落盤,叢集中執行個體之間互相無感覺,每個執行個體都是對等的,在用戶端做基于一緻性hash的資料配置設定。使用者隻需要告訴用戶端所有可用的叢集執行個體清單,由用戶端對key做一緻性hash來決定key會落到那個redis執行個體上,進而決定會對哪個執行個體進行讀寫。
持久化方案:
redis有兩種持久化方案: rdb和aof, 說白了前者就是dump全量資料做snapshot,後者是記錄增量記錄檔。
兩者的優缺點也很明顯: rdb适合做資料備份和資料快速恢複,但是做snapshot是一個很費時的過程,不可能做到頻率很高,一般是每幾分鐘進行一次,是以不能保證最近幾分鐘之内的資料不會丢。
aof做增量記錄檔的代價不是很高,一般是每秒一次,是以能保證最多隻丢一秒的資料。
不過需要指出的是這兩種方式并不沖突,可以同時開啟,我們在部署的時候也是這麼做的。
社群也在考慮結合rdb和aof,達到類似postgresql的資料安全性(有點小期待呢)。
主從複制(replication):
redis采用1:n主備結構來實作replication。但是需要注意的是為了提高效率,master和slave之間是異步進行資料同步的,這也就意味着主備之間可能存在資料不一緻的情況,但是有配置可以指定主備之間的最大資料延時,需要使用者自己根據業務場景進行配置。
使用sentinel哨兵實作ha:
sentinel是redis提供的一個哨兵元件,主要實作了兩個功能:
1. master和slave監控,一旦master不可用,則sentinel叢集會進行投票,進行failover,選舉新的master。
2. master和slave的配置提供,用戶端隻需要從sentinel即可讀取目前的主從配置即可,不需要主動連接配接master和slave。
redis cluster叢集部署方式:
redis cluster使用多個redis執行個體進行容量擴充。這種方式同獨立部署方式的差別是叢集的執行個體之間不是互相獨立的,是互相感覺的,每個執行個體都知道其他執行個體的存在,并會進行通信同步全局的sharding和叢集配置。
此模式下如何對資料進行切分(sharding):
1. 用戶端不會進行一緻性hash,而是會對key做crc16運算,然後将産生的值%16384, 進而産生一個0~16383的值。
2. 叢集會将所有key切分成16384個hash slot, 并根據叢集中redis執行個體的個數将hash slot均分到所有的執行個體中。
3. 将1中産生的值直接對應到相同值的hash slot,而叢集中包含此hash slot的機器既是包含此key的機器
4. 當3中用戶端計算出的機器因進行過人工resharding而不在包含3中的slot時,此機器會根據自己感覺的叢集sharding配置傳回redirect告知真正包含所需hash slot的機器。
不過有幾個需要注意的地方:
1. 當需要對叢集進行擴容時,将新機器加到叢集中之後其實新機器并沒有包含任何hash slot,需要手動重新進行sharding配置設定hash slot并進行資料遷移。
2. 連接配接redis cluster的用戶端和标準用戶端是不一樣的,不能混用。
3. transaction支援受限:當transaction中涉及的key不屬于同一個redis執行個體時無法完成transaction。
4. 多key操作受限:如取兩個集合的交集操作,若兩個集合的key屬于不同的機器,則無法完成。
最終標明的部署方式:
由于redis cluster部署方式下transaction和多key操作受限,而單台機器的容量能滿足我們的業務需求,是以沒有選擇redis cluster部署方式,最終選擇的部署方式如下:
1. 采用一台master加兩台slave做replication。
2. 采用三台機器搭建sentinel叢集,保證高可用性。
3. 将sentinel部署在使用的redis服務的三台tesla api後端機,使得sentinel能反映api到master/slave的真實可用性。
在這種部署方式下再加上針對redis server和redis sentinel的配置和運維控制腳本即可完成服務的搭建。