網(wǎng)絡(luò) IO 模型
redis 采用 io 多路復(fù)用,默認(rèn)采用 epoll 方式仑濒,也提供了 kqueue叹话、select、poll 等實現(xiàn)
單線程設(shè)計
redis 處理網(wǎng)絡(luò)請求是單線程的設(shè)計墩瞳,主要是由于通常情況下 cpu 不是 redis 的瓶頸所在驼壶,內(nèi)存或者網(wǎng)絡(luò)才是主要的瓶頸,同時采用單線程的設(shè)計相對多線程而言可以避免很多問題喉酌,更加簡單
分布式鎖
鎖的獲取
set ${key} ${value} nx ex ${seconds}
# 或
set ${key} ${value} nx px ${milliseconds}
鎖的釋放
需要采用 lua 腳本的方式進行鎖的釋放热凹,采用 lua 的原因是為了釋放的原子性,避免釋放了其他人的鎖
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
存在問題
redis 的主從同步是異步復(fù)制泪电,有可能在客戶端 a 獲取鎖的過程中般妙,redis 的主服務(wù)器掛掉,而獲取鎖的 key 未及時同步到從服務(wù)器相速,此時發(fā)生 failover碟渺,從服務(wù)器晉升為主服務(wù)器,另一個客戶端 b 此時進行鎖獲取的操作突诬,由于數(shù)據(jù)未同步苫拍,導(dǎo)致獲取鎖成功,造成同一時間有兩個客戶端獲取鎖
持久化機制
redis 主要有兩種持久化機制:RDB 與 AOF
-
RDB
可以理解為一種快照模式旺隙,可以通過 SAVE 或者 BGSAVE (fork 一個子進程)進行 RDB 文件的生成- 優(yōu)點
- 生成的文件大小相對較小
- 重啟恢復(fù)時間較快
- 缺點
- 生成的文件與最新數(shù)據(jù)差距較大绒极,相對于 aof 會丟失更多數(shù)據(jù)
- fork 調(diào)用產(chǎn)生子進程在數(shù)據(jù)集較大的情況下相對耗時,在數(shù)據(jù)集較大的情況或者 cpu 性能較差的情況下催束,甚至可能造成幾毫秒到一秒不等的停服時間
- 優(yōu)點
-
AOF (append only file)
記錄了所有的變更操作,提供了 AOF 的重寫機制- 優(yōu)點
- 持久性更佳
- 缺點
- 生成文件相對較大
- 重啟恢復(fù)時間相對 rdb 而言更長
- 優(yōu)點
跳表(skip list)
本身是個很精巧的數(shù)據(jù)結(jié)構(gòu)伏社,跳表在鏈表的基礎(chǔ)上加上多層索引抠刺,擁有 O(log N) 的查詢性能塔淤,同時可以利用鏈表本身的特點很好的支持范圍查詢
在 redis 中的應(yīng)用主要是 zset(sorted set)
內(nèi)存淘汰機制
redis 可以通過 maxmemory 設(shè)置最大內(nèi)存,如果超過該配置將觸發(fā)淘汰機制
maxmemory <bytes>
通過 maxmemory-policy 進行內(nèi)存淘汰策略的設(shè)置速妖,有 6 種不同的策略可以供選擇高蜂,主要是基于 lru 和 random 刪除兩種策略實現(xiàn),默認(rèn)是不刪除罕容,當(dāng)?shù)竭_ maxmemory 時备恤,將回復(fù)錯誤提示,不影響只讀請求
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key according to the LRU algorithm
# volatile-random -> remove a random key with an expire set
# allkeys-random -> remove a random key, any key
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# noeviction -> don't expire at all, just return an error on write operations
# default
maxmemory-policy noeviction
Redis sentinel(哨兵)
哨兵機制是 redis 實現(xiàn)高可用的方案锦秒,監(jiān)控 redis 的 master 和 slave露泊,在 master 宕機的情況下進行主備切換,保證可用性旅择,哨兵本身也會存在單點問題惭笑,可以部署多個哨兵,組成哨兵集群生真,在 master 出現(xiàn)問題時沉噩,哨兵通過 raft 協(xié)議選出 leader,由哨兵 leader 進行主備切換操作
Redis cluster
redis cluster 是基于 redis 的分布式數(shù)據(jù)庫方案柱蟀,redis cluster 的數(shù)據(jù)分片既不是采用 hash 分布川蒙,也非采用 range 方式,而是采用 slot 的方式進行數(shù)據(jù)的分片长已,key 通過 hash 后對 16384 個 slot 進行取模決定 key 隸屬的 slot畜眨,每個 redis 實例可以被分配若干個 slot