Redis 是一個 Key-Value 存儲系統。和 Memcached 類似,它支持存儲的 value 類型相對更多,包括 string(字符串)、 list(鏈表)、 set(集合)和 zset(有序集合)。這些數據類型都支持 push/pop、add/remove 及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,Redis 支持各種不同方式的排序。與 memcached 一樣,為了保證效率,數據都是緩存在內存中。區別的是 Redis 會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎上實現了 master-slave(主從)同步。
學習整理:
-
redis中hash slot是什么?
hash slot 是redis分布式部署,節點分配的一種方法
redis分布式部署其結構如下:
Redis 集群采用每個節點擁有 1(主服務自身)到 N 個副本(N-1 個附加的從服務器)的主從模型,cluster內部master和slave之間的數據是異步復制的(提高性能,主要是在性能和一致性間的一個平衡)。
一個redis cluster有固定的16384個hash slot,slot被均勻的分配到cluster中的master節點上,而一個key具體的存儲在哪個slot上,則是通過key的CRC16編碼對16384取模得出的。
再講講hash slot的基本原理:
hash-slot
記錄和物理機之間引入了虛擬桶層,記錄通過hash函數映射到虛擬桶,記錄和虛擬桶是多對一的關系;第二層是虛擬桶和物理機之間的映射,同樣也是多對一的關系,即一個物理機對應多個虛擬桶,這個層關系是通過內存表實現的。
Redis 集群沒有并使用傳統的一致性哈希來分配數據,而是采用另外一種叫做哈希槽 (hash slot)的方式來分配的。redis cluster 默認分配了 16384 個slot,當我們set一個key 時,會用CRC16算法來取模得到所屬的slot,然后將這個key 分到哈希槽區間的節點上,具體算法就是:CRC16(key) % 16384。
- 如果用戶將新節點 D 添加到集群中, 那么集群只需要將節點 A 、B 、 C 中的某些槽移動到節點 D 就可以了。
比如我想新增一個節點D,redis cluster的這種做法是從各個節點的前面各拿取一部分slot到D上。- 與此類似, 如果用戶要從集群中移除節點 A , 那么集群只需要將節點 A 中的所有哈希槽移動到節點 B 和節點 C , 然后再移除空白(不包含任何哈希槽)的節點 A 就可以了。
因為將一個哈希槽從一個節點移動到另一個節點不會造成節點阻塞, 所以無論是添加新節點還是移除已存在節點, 又或者改變某個節點包含的哈希槽數量, 都不會造成集群下線。
最后補充一個跟hash槽類似但應用更廣的一個叫一致性hash的東東:
環形Hash空間
按照常用的hash算法來將對應的key哈希到一個具有232次方個桶的空間中,即0~(232)-1的數字空間中。現在我們可以將這些數字頭尾相連,想象成一個閉合的環形。如下圖環形空間
把數據通過一定的hash算法處理后映射到環上映射數據
將機器通過hash算法映射到環上對象與機器處于同一哈希空間中,這樣按順時針轉動object1存儲到了NODE1中,object3存儲到了NODE2中,object2、object4存儲到了NODE3中。映射機器機器的刪除與添加
- 節點(機器)的刪除
刪除節點- 節點(機器)的添加
添加節點通過按順時針遷移的規則,那么object2被遷移到了NODE4中,其它對象還保持這原有的存儲位置。通過對節點的添加和刪除的分析,一致性哈希算法在保持了單調性的同時,還是數據的遷移達到了最小,這樣的算法對分布式集群來說是非常合適的,避免了大量數據遷移,減小了服務器的的壓力。
一致性哈希算法中,為了盡可能的滿足平衡性,其引入了虛擬節點。
“虛擬節點”( virtual node )是實際節點(機器)在 hash 空間的復制( replica ),一個節點(機器)對應了若干個“虛擬節點”,這個對應個數也稱為“復制個數”,“虛擬節點”在 hash 空間中以hash值排列。
虛擬節點
映射關系:object1->NODE1-1,object2->NODE1-2,object3->NODE3-2,object4->NODE3-1。通過虛擬節點的引入,對象的分布就比較均衡了。那么在實際操作中,對象從hash到虛擬節點到實際節點的轉換如下圖:
時間轉換
“虛擬節點”的hash計算可以采用對應節點的IP地址加數字后綴的方式。例如假設NODE1的IP地址為192.168.1.100。引入“虛擬節點”前,計算 cache A 的 hash 值:
Hash(“192.168.1.100”);
引入“虛擬節點”后,計算“虛擬節”點NODE1-1和NODE1-2的hash值:
Hash(“192.168.1.100#1”); // NODE1-1
Hash(“192.168.1.100#2”); // NODE1-2
參見:
hash slot(虛擬桶):https://www.cnblogs.com/abc-begin/p/8203613.html
每天進步一點點——五分鐘理解一致性哈希算法(consistent hashing):https://blog.csdn.net/cywosp/article/details/23397179
TO BE CONTINUED ......