Redis的基本數(shù)據(jù)類型
String, list, set, map, zset(sorted-set)
zset的使用
set與zset都是string類型元素的集合,不允許有重復(fù)。zset的每個成員都會關(guān)聯(lián)一個double類型的分?jǐn)?shù),根據(jù)這個分?jǐn)?shù)為集合中的成員進(jìn)行從小到大的排序。
分?jǐn)?shù)可重復(fù), 集合是通過哈希表實現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是O(1)
舉例:在直播系統(tǒng)中,實時排行信息包含直播間在線用戶列表,各種禮物排行榜,彈幕消息(可以理解為按消息維度的消息排行榜)等信息,適合使用Redis中的zset結(jié)構(gòu)進(jìn)行存儲。
實例
redis 127.0.0.1:6379> ZADD runoobkey 1 redis
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 2 mongodb
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 3 mysql
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 3 mysql
(integer) 0
redis 127.0.0.1:6379> ZADD runoobkey 4 mysql
(integer) 0
redis 127.0.0.1:6379> ZRANGE runoobkey 0 10 WITHSCORES
1) "redis"
2) "1"
3) "mongodb"
4) "2"
5) "mysql"
6) "4"
Redis有序集合命令
|
1
|
向有序集合添加一個或多個成員,或者更新已存在成員的分?jǐn)?shù)
|
11
|
移除有序集合中的一個或多個成員
|
|
2
|
獲取有序集合的成員數(shù)
|
12
|
移除有序集合中給定的字典區(qū)間的所有成員
|
|
3
|
計算在有序集合中指定區(qū)間分?jǐn)?shù)的成員數(shù)
|
13
|
移除有序集合中給定的排名區(qū)間的所有成員
|
|
4
|
有序集合中對指定成員的分?jǐn)?shù)加上增量 increment
|
14
|
移除有序集合中給定的分?jǐn)?shù)區(qū)間的所有成員
|
|
5
|
計算給定的一個或多個有序集的交集并將結(jié)果集存儲在新的有序集合 key 中
|
15
|
返回有序集中指定區(qū)間內(nèi)的成員,通過索引,分?jǐn)?shù)從高到低
|
|
6
|
在有序集合中計算指定字典區(qū)間內(nèi)成員數(shù)量
|
16
|
返回有序集中指定分?jǐn)?shù)區(qū)間內(nèi)的成員,分?jǐn)?shù)從高到低排序
|
|
7
|
通過索引區(qū)間返回有序集合指定區(qū)間內(nèi)的成員
|
17
|
返回有序集合中指定成員的排名,有序集成員按分?jǐn)?shù)值遞減(從大到小)排序
|
|
8
|
通過字典區(qū)間返回有序集合的成員
|
18
|
返回有序集中,成員的分?jǐn)?shù)值
|
|
9
|
通過分?jǐn)?shù)返回有序集合指定區(qū)間內(nèi)的成員
|
19
|
計算給定的一個或多個有序集的并集,并存儲在新的 key 中
|
|
10
|
返回有序集合中指定成員的索引
|
20
|
迭代有序集合中的元素(包括元素成員和元素分值
|
Redis的持久化(怎么保證redis掛掉之后再重啟數(shù)據(jù)可以進(jìn)行恢復(fù))
Redis的一種持久化方式叫快照(snapshotting,RDB),另一種是只追加文件(append-only file,AOF)。
RDB
Redis創(chuàng)建快照之后,可以對快照進(jìn)行備份,可以將快照復(fù)制到其他服務(wù)器從而創(chuàng)建具有相同數(shù)據(jù)的服務(wù)器副本(Redis主從結(jié)構(gòu),主要用來提高Redis性能),還可以將快照留在原地以便重啟服務(wù)器的時候使用。
RDB是Redis采用的默認(rèn)持久化方式
AOF
持久化的實時性更好,因此已成為主流的持久化方案。通過appendonly參數(shù)開啟。appendonly yes
開啟后,每執(zhí)行一條會更改Redis中的數(shù)據(jù)的命令,Redis就會將該命令寫入硬盤中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通過dir參數(shù)設(shè)置的,默認(rèn)的文件名是appendonly.aof
在Redis的配置文件中存在三種不同的AOF持久化方式,它們分別是
appendfsync always #每次有數(shù)據(jù)修改發(fā)生時都會寫入AOF文件,嚴(yán)重降低Redis的速度
appendsync everysec #每秒同步一次,顯示地將多個寫命令同步到硬盤
appendfsync no #讓操作系統(tǒng)決定合適進(jìn)行同步
推薦appendsync everysec方法,性能幾乎不影響,最差丟失1秒鐘的數(shù)據(jù)
Redis4.0對于持久化機(jī)制的優(yōu)化
支持AOF RDB混合持久化。默認(rèn)關(guān)閉需手動開啟。
AOF重寫的時候就直接把RDB的內(nèi)容寫到AOF文件開頭。這樣做可以快速加載同時避免丟失過多的數(shù)據(jù)。缺點是AOF里面的RDB部分時壓縮格式不再是AOF格式,可讀性較差。
補(bǔ)充:AOF重寫
重寫可以產(chǎn)生一個新的AOF文件,這個新文件和原文件所保存的數(shù)據(jù)庫狀態(tài)一樣,但體積更小。
該功能是通過讀取數(shù)據(jù)庫中的鍵值對來實現(xiàn)的,無需對原文件進(jìn)行任何讀入、分析或?qū)懭氩僮鳌?/div>
重寫過程:在執(zhí)行BGREWRITEAOF命令時,Redis服務(wù)器會維護(hù)一個AOF重寫緩沖區(qū),該緩沖區(qū)會在子進(jìn)程創(chuàng)建新AOF文件期間,記錄服務(wù)器執(zhí)行的所有寫命令。當(dāng)子進(jìn)程創(chuàng)建完成,緩沖區(qū)所有內(nèi)容被追加到新文件末尾,使新舊兩文件保存的數(shù)據(jù)庫狀態(tài)一致。最后,服務(wù)器用新文件替換舊文件,以此完成重寫。
Redis分布式鎖實現(xiàn)原理
每個客戶端對某個方法加鎖時,在zookeeper上的與該方法對應(yīng)的指定節(jié)點的目錄下,生成一個唯一的瞬時有序節(jié)點。判斷是否獲取鎖的方式很簡單,只需要判斷有序節(jié)點中序號最小的一個。當(dāng)釋放鎖的時候,只需將這個瞬時節(jié)點刪除即可。同時,其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖無法釋放,而產(chǎn)生的死鎖問題。完成業(yè)務(wù)流程后,刪除對應(yīng)的子節(jié)點釋放鎖。
(使用Redission框架)
Rlock lock = redisson.getLock("mylock");
lock.lock();
lock.unlock();
加鎖機(jī)制:給一臺機(jī)器加鎖,需要一段lua腳本。鎖的名字,鎖的默認(rèn)生存時間,和加鎖客戶端的ID。使用exists判斷,如果你要加鎖的那個鎖不存在,就可以添加。返回一串hash,客戶端ID和加鎖次數(shù)。
鎖互斥機(jī)制:客戶端2嘗試加鎖,發(fā)現(xiàn)鎖已存在,得到鎖的剩余生存時間,然后進(jìn)入while循環(huán),不停的嘗試加鎖。
watch dog自動延期機(jī)制:watch dog是一個后臺線程,每隔十秒檢查一次,如果客戶端還持有鎖,則不斷延長鎖的生存時間
可重入鎖加鎖機(jī)制:發(fā)現(xiàn)鎖已存在,但是ID一致,就會增加鎖的個數(shù)。
釋放鎖機(jī)制:釋放鎖一次,鎖的次數(shù)就會減減一次,直到為0則刪除鎖
分布式鎖的缺點:在redis master實例宕機(jī)可能導(dǎo)致多個客戶端同時完成加鎖
浙公網(wǎng)安備 33010602011771號