redis數據結構:
string,hash,list,set,zset,
bitmap(布隆過濾器), Geohash, hyperLogLog,
tream(redis5.0才有的)
底層數據結構:
Set 跟hash區別是:set就是一個特殊的value為空的hash
Zset(sorted set)底層數據結構是一種跳錶:skipList
String數據結構包含了raw,embstr,int三種內部編碼
ZipList內部編碼有hash,list,zset
set內部編碼是hashtable,intset
Redis緩存穿透
緩存穿透是數據為空,導致每次都查不到。可以設置空緩存key-null,但是會導致數據量很大,這時候可以用布隆過濾器;數據校驗等輔助手段也可以緩解
布隆過濾器是一種數據結構,比較巧妙的概率型數據結構(probabilistic data structure),特點是高效地插入和查詢,可以用來告訴你 “某樣東西一定不存在或者可能存在”。相比於傳統的 List、Set、Map 等數據結構,它更高效、佔用空間更少,但是缺點是其返回的結果是概率性的,而不是確切的。
HashMap是快,但是佔用空間大
布隆過濾器是一個 bit 向量或者說 bit 數組
Redis緩存擊穿,單點突破
緩存擊穿是高併發下請求同一個數據,改數據緩存過期失效導致查庫。
解決方案:
在查庫追加分佈式鎖;
熱點數據永不失效;
數據可實時追加時間長度;
Redis緩存雪崩
大量緩存同時失效,導致查庫。
解決方案:
設置緩存過期時間均勻化;
熱點數據直接永久性
Redis高可用
① 主從複製+哨兵集群;主從複製讀寫分離提高redis性能,3主3從。哨兵能監控主節點狀態,隨時切換做到高可用
② RDB+AOF數據持久化
redis緩存淘汰策略
① 定期刪除+惰性刪除:
定期刪除:100ms一次掃描dict中的20個key,進行過期時間檢查,過期則刪除;
惰性刪除:當再次使用到該key時候再檢查是否過期,過期則刪除;
② 內存空間不足淘汰策略:
默認不刪除,一般需要配置為最近最少使用刪除原則
Redis提高命中率
① 緩存預熱;
② 細粒度緩存;
③ 緩存時間設置永久有效;
④ 一致性哈希算法,一致性哈希是對2^32次方取模,將整個哈希值空間組成一個虛擬的圓環。Dubbo負載均衡也是一致性哈希策略。其實redis不是直接用一致性哈希,而是用的哈希槽slot,裡面是crc16算法。Redis集群包含16384個槽位,手動指定槽位具體在哪個機器節點,避免一致性哈希的傾斜問題,另外在容錯性與擴展性上與一致性哈希一樣。當需要追加機器或者機器掛掉,影響都很小。
Redis使用場景:
a. KV緩存:配置數據、熱點數據緩存;
b. 分佈式鎖:但是其實不適合作為分佈式鎖,分佈式鎖建議zk鎖。
c. Set key val nx ex 1000 一定要設置時間 注意setnx expire可能會出現問題,不是原子操作,可能導致死鎖。
d. 隊列,限流
e. 定時任務
f. 頻率控制
g. RoaringBitmap
h. 模糊計數
i. 布隆過濾器防止緩存穿透 key-null場景
如果要統計一篇文章的閱讀量,可以直接使用 Redis 的 incr 指令來完成。如果要求閱讀量必須按用戶去重,那就可以使用 set 來記錄閱讀了這篇文章的所有用戶 id,獲取 set 集合的長度就是去重閱讀量。但是如果爆款文章閱讀量太大,set 會浪費太多存儲空間。這時候我們就要使用 Redis 提供的 HyperLogLog 數據結構來代替 set,它只會佔用最多 12k 的存儲空間就可以完成海量的去重統計。但是它犧牲了準確度,它是模糊計數,誤差率約為 0.81%
如何正確訪問redis中的海量數據?
答:keys算法是遍歷算法,時間複雜度O(n),當數據量達到幾百萬,keys命令會導致redis卡頓,因為redis是單線程程序,順序執行所有命令,其他指令必須等待keys執行完畢才能繼續。解決方案:採用scan命令,通過遊標分步進行,不會阻塞線程。返回的結果可能重複,客戶端需要去重,另外返回空不一定就沒數據,而是要看遊標返回零,才表示遍歷結束。
scan cursor [MATCH pattern] [COUNT count]
比如:scan 0 match user_token* count 5
輸出
1)“6”--遊標index
2)1)“user_token:10”
2)“user_token:105”
3)“user_token:101”
4)“user_token:15”
5)“user_token:13”
閱讀更多 wendellFang 的文章