Redis知識點總結

Redis知識點總結

簡介

Redis的16個DB

redis默認是有16個db組成,默認操作的一半都是第0個,這些DB主要有以下特點:

  1. 不支持自定義數據庫名詞
  2. 每個數據庫不能單獨設置授權
  3. 每個數據庫之間並不是完全隔離的。 可以通過flushall命令清空redis實例面的所有數據庫中的數據
    通過 select dbid 去選擇不同的DB 。 dbid的取值範圍默認是0 -15

Redis的數據結構

主要有5種

  1. 字符類型(String)
  2. 散列類型(hash)
  3. 列表類型(List)
  4. 集合類型(Set)
  5. 有序集合類型(ZSet)

Redis的應用場景

  1. 數據緩存
  2. 單點登錄
  3. 秒殺類活動
  4. 網站訪問排名
  5. 應用模塊開發

Redis常用命令

String命令 用法 含義
set key value set aaa aaa 緩存一個字符串類型aaa,key是aaa,value是aaa
get key get aaa 從緩存中獲取一個key是aaa的數據
incr key incr bbb 將key是bbb的數據進行遞增,類似i++,value必須是數字
incrby key increment incrby bbb 5 將key是bbb的數據加5
decr key decr bbb 將key是bbb的數字遞減,類似i–
decrby key decrby bbb 3 將key是bbb的數字減3
append key value append aaa 000 將key是aaa的數據尾部添加000,比如說之前aaa的值是aaa,操作之後aaa的值是aaa000
strlen key strlen aaa 獲取key是aaa的數據長度
mget key key … mget aaa bbb 同時獲取多個key的數據
mset key value key value … mset ccc 111 ddd 222 同時設置多個key和value
Hash命令 用法 含義
hset map key value hset user name zhangsan 設置user對象的name字段爲zhangsan,設置多個就是一個對象,hash就可以用來表示這個關係
hmset map key1 value1 key2 value2 … hmset user … 一次設置多個屬性,相當於上邊的批量添加
hsetnx map key value hnxset user age 13 如果user對象的age屬性不存在,那就設置這個屬性值
hget map key hget user name 獲取user對象的name屬性
havls map havls user 獲取整個map的值,也就是user對象
hkeys map hkeys user 獲取user所有的屬性值
hlen map hlen user 獲取user的字段數量
hdel map key1 key2 hdel user name age 刪除一個或多個哈希表字段
hexists map key hexists user name 查看user對象不否存在name字段
List命令 用法 含義
key value lpush eee 111 從左邊往列表插入數據
rpush key value rpush eee 222 從右邊往列表插入數據
lpop key lpop eee 從列表左邊彈出數據,會把數據從列表刪除
rpop key rpop eee 從列表右邊彈出數據,也會刪除
llen key llen eee 獲取列表的長度
lrange key start stop lrange eee 0 3 從列表做邊開始獲取範圍數據,範圍就是0-3,stop爲-1時表示列表最大值,也就是最右邊第一個元素
lrem key count value lrem eee 1 3 從列表中刪除1個值爲3的數據
lset key index value lset eee 0 5 把列表中key是eee的數據下標爲0的值改成5
Set命令 用法 含義
sadd set value sadd mySet 1 添加元素
smembers set smembers mySet 查看全部元素
sismember set value sismember mySet 3 判斷是否包含某個值
srem set value srem mySet 1 刪除某個元素
srem set value1 value2 srem mySet 2 4 刪除某些元素
scard set scard mySet 查看元素個數
spop set spop mySet 隨機刪除一個元素
smove set1 set2 value smove yourSet mySet 2 將一個set的元素移動到另外一個set
sinter set1 set2 sinter yourSet mySet 求兩set的交集
sunion set1 set2 sunion yourSet mySet 求兩set的並集
sdiff set1 set2 sdiff yourSet mySet 求在yourSet中而不在mySet中的元素
ZSet命令 用法 含義
zrange zset start stop zrange zset 0 3 獲取排名最後三位,
start 和 stop 都以 0 爲底,也就是說,以 0 表示有序集第一個成員,
以 1 表示有序集第二個成員,以此類推。
你也可以使用負數下標,以 -1 表示最後一個成員, -2 表示倒數第二個成員,以此類推。
zrevrange zset start stop zrevrange zset 0 3 獲取排名前三(默認是升序,所以需要 rev 改爲降序)
zrank zset value zrank zset zhangsan 獲取zhangsan的排名
Lua腳本 用法 含義
evel evel(…) 運行lua腳本

Redis分佈式鎖的實現

mysql
建個表,根據for update 或者樂觀鎖,或者insert和delete加唯一索引實現

zookeeper

  1. 競爭創建節點,然後監聽創建成功的
  2. 根據znode,創建一個有序臨時節點,

redis

#加鎖,2s過期
set lock 隨機數 nx px 2000
#刪除鎖,用lua腳本,找到 key 對應的 value,跟自己傳過去的 value 做比較,如果是一樣的才刪除。
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

Redis數據過期策略

redis這三種都使用着,因爲這三種策略是非互斥的

  1. (惰性刪除)被動刪除:當讀/寫一個已經過期的 key 時,會觸發惰性刪除策略,直接刪除掉這個過期 key 。
  2. (定期刪除)主動刪除:由於惰性刪除策略無法保證冷數據被及時刪掉,所以 Redis 會定期主動淘汰一批已過期的 key,redis 默認是每隔 100ms 就隨機抽取一些設置了過期時間的 key,檢查其是否過期,如果過期就刪除
  3. (緩存淘汰)主動刪除:當前已用內存超過 maxmemory 限定時,觸發主動緩存淘汰策略

Redis緩存淘汰策略

Redis默認只能用10G的內存

  1. volatile-lru
    當寫入數據是發現內存不足,那就在設置了過期時間的key中挑選最近最少使用的key刪除掉
  2. volatile-ttl
    當寫入數據是發現內存不足,那就在設置了過期時間的key中把快要過期的某個key提前刪除
  3. volatile-random
    當寫入數據是發現內存不足,那就在設置了過期時間的key中隨機刪除
  4. allkeys-lru
    當寫入數據時發現內存不足,那就在所有key中挑選最近最少使用的key刪除掉,也是最常用的策略
  5. allkeys-random
    當寫入數據時發現內存不足,那就在所有的key中隨機刪除某個key
  6. no-enviction
    當內存不足以容納新寫入數據時,新寫入操作會報錯,一般沒人用吧

Lua

全局變量 local a = 1;
局部變量 a =2;

邏輯表達式
+ - * /
相等 ==
不等於 ~=
大於 >
小於 <
取餘 %
負號 -
邏輯運算符
and /or /not
拼接 … eg : print(a…b)
獲取長度 #
條件判斷
if … then elseif … then else … end
循環
while … do … end

for i=0,10 do print(i) end

–[[範圍註釋]] --單行註釋

函數
全局函數
local function(str…) … end

局部函數
function(str…) … end

Redis持久化策略

RDB(dump.rdb)

RDB會按照規則定製從內存把數據持久化到磁盤
快照(Snapshot)
redis在指定的情況下會觸發快照
1.自己配置的快照規則
save save 秒-單位時間 在這個時間內更改次數大於某個值時會執行快照
save 10 3 就是在10秒內更改次數超過3次就會執行快照
2.通過save或者bgsave命令
save執行內存的數據同步到磁盤的操作,這個操作會阻塞客戶端的請求.
bgsave在後臺異步執行快照,這個不會阻塞客戶端請求
3.執行flushall的時候
清除內存的所有數據,只要配置的規則存在,那就會執行快照
4.執行復制的時候

快照實現原理
redis會使用fork函數複製一份當前進程的副本(子進程),fork進程負責把內存的數據同步到磁盤的臨時文件,父進程繼續處理客戶端請求
優點:
可以最大化redis的性能,但是數據量很大的話,fork時間過久也會影響一些性能
缺點:
可能會存在數據丟失的請求,也就是快照和下一次快照的中間,redis掛了

AOF

AOF是每次執行命令後,把命令本身記錄到磁盤
開始AOF的方式就是在配置文件中把appendonly設置成yes,默認的文件名就是appendonly.aof
每次命令都保存,那些舊數據也被保存了,徒增煩惱,我們只需要最新的數據而已,redis配置文件中有壓縮策略解決了這個
如下兩個參數可以去對aof文件做優化
auto-aof-rewrite-percentage 100 表示當前aof文件大小超過上一次aof文件大小的百分之多少的時候會進行重寫。如果之前沒有重寫過,以啓動時aof文件大小爲準
auto-aof-rewrite-min-size 64mb 限制允許重寫最小aof文件大小,也就是文件大小小於64mb的時候,不需要進行優化

aof重寫的原理
Redis 可以在 AOF 文件體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。 整個重寫操作是絕對安全的,因爲 Redis 在創建新 AOF 文件的過程中,會繼續將命令追加到現有的 AOF 文件裏面,即使重寫過程中發生停機,現有的 AOF 文件也不會丟失。 而一旦新 AOF 文件創建完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操作。AOF 文件有序地保存了對數據庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式保存, 因此 AOF 文件的內容非常容易被人讀懂, 對文件進行分析(parse)也很輕鬆
同步磁盤數據時的問題
redis每次更改數據的時候, aof機制都會將命令記錄到aof文件中,但是由於操作系統的緩存機制,數據並沒有實時的寫入到硬盤中,而是先寫入到了硬盤緩存。再通過硬盤緩存機制去保存到文件中,所以在這個時間段之內如果redis掛了,那就會存在數據同步問題,redis提供了appendfsync參數來解決這個問題.

  1. appendfsync always 每次執行寫入都會進行同步,這個是最安全但是是效率比較低的方式
  2. appendfsync everysec 每一秒執行一次同步,就算丟失也是1秒的數據,是可接受的
  3. appendfsync no 不主動進行同步操作,交給操作系統去執行同步操作這個是速度最快的,但也是最不安全的方式

寫入AOF的時候系統宕機怎麼辦
在寫入AOF和同步到磁盤的時候,系統宕機了,結果造成了AOF文件損壞,那在redis重啓的時候是不會加載損壞的AOF文件的,這樣就造成了數據的不一致或者丟失的情況,redis本身提供了AOF文件修復工具,具體操作如下:
1.先備份一下AOF文件
2.使用Redis提供的 redis-check-aof 程序來修復原來的AOF文件,執行redis-check-aof --fix命令即可,修復完成後重啓,RDB也有一個修復工具,道理相同

缺點
響應請求的同時還要寫磁盤,稍微會影響性能,但是還是IO得問題,換固態即可

緩存擊穿

key不存在

緩存穿透

key過期

緩存雪崩

宕機

總結

可單獨使用也可一起使用,如果一起使用,當redis啓動或重啓時,redis會優先使用AOF來還原數據

發佈了72 篇原創文章 · 獲贊 14 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章