面試連環炮系列(二):你們的項目Redis做了集群部署嗎


  1. 你們的項目Redis做了集群部署嗎?
    我們有大量數據需要緩存,而單實例的容量畢竟是有限的,於是做了Redis集群部署。

  2. 采取的方案是什么,Codis還是Redis Cluster,為什么要選擇這個方案?
    我們采用的官方Redis Cluster方案。Codis是一整套緩存解決方案,采取的代理模式實現了高可用、數據分片、監控、動態擴態等功能,但是部署太復雜了。Cluster要簡單很多,而且也基本滿足目前的需要。

  3. Redis Cluster有什么缺點嗎,或者說不適合什么場景?
    這種模式將存儲和元數據管理放一起的,出現問題不好排查,如果是大規模集群或者多地域情況下不適合, 可能會有較高的網絡通訊成本以及腦裂等問題。

  4. Redis Cluster的集群分片原理是什么?
    Redis集群沒有使用一致性hash, 而是引入了哈希槽的概念。Redis集群有16384個哈希槽,每個key通過CRC16校驗后對16384取模來決定放置哪個槽,集群的每個節點負責一部分hash槽,舉個例子,比如當前集群有3個節點,那么:節點 A 包含 0 到 5500號哈希槽;節點 B 包含5501 到 11000 號哈希槽;節點 C 包含11001 到 16384號哈希槽。

  5. 為什么哈希槽偏偏是16384個?
    在redis節點發送心跳包時需要把所有的槽放到這個心跳包里,以便讓節點知道當前集群信息,16384=2^14=16k,在發送心跳包時使用char進行bitmap壓縮后是2k(2 * 8 (8 bit) * 1024(1k) = 2K),也就是說使用2k的空間創建了16k的槽數。
    雖然使用CRC16算法最多可以分配65535(2^16-1)個槽位,65535=65k,壓縮后就是8k(8 * 8 (8 bit) * 1024(1k) = 8K),也就是說需要需要8k的心跳包,作者認為這樣做不太值得;並且一般情況下一個redis集群不會有超過1000個master節點,所以16k的槽位是個比較合適的選擇。

  6. 如果要擴容或者縮容,該怎么處理呢?
    如果我想新添加個節點D, 我需要從節點 A, B, C中得部分槽到D上,如果我想移除節點A,需要將A中的槽移到B和C節點上,然后將沒有任何槽的A節點從集群中移除即可,由於從一個節點將哈希槽移動到另一個節點並不會停止服務,所以無論添加刪除或者改變某個節點的哈希槽的數量都不會造成集群不可用的狀態。

  7. Redis Cluster模式有哪些命令不支持嗎?
    mget,mset等命令不支持,我猜想多個鍵值可能不在一個節點中,處理很復雜,官方就干脆不支持。

參考文章:

http://www.redis.cn/topics/cluster-tutorial.html
https://www.cnblogs.com/amei0/p/8177076.html
https://www.jianshu.com/p/de268f62f99b

雞湯:莫問收獲,但問耕耘。-曾國藩


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM