Redis-避免緩存穿透的利器之BloomFilter
Redis相關的問題的時候,經常提到BloomFilter(布隆過濾器)這玩意的使用場景是真的多,而且用起來是真的香,原理也好理解,看一下文章就可以在面試官面前侃侃而談了
布隆過濾器可以用於檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識別率和刪除困難
那應用的場景在哪里呢?一般我們都會用來防止緩存擊穿
簡單來說就是你數據庫的id都是1開始然后自增的,那我知道你接口是通過id查詢的,我就拿負數去查詢,這個時候,會發現緩存里面沒這個數據,我又去數據庫查也沒有,一個請求這樣,100個,1000個,10000個呢?你的DB基本上就扛不住了,如果在緩存里面加上這個,是不是就不存在了,你判斷沒這個數據就不去查了,直接return一個數據為空不就好了嘛
作者:敖丙
鏈接:https://juejin.im/post/5db69365518825645656c0de
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
https://www.cnblogs.com/Ccwwlx/p/11947257.html
redis常見問題
緩存和數據庫雙寫一致性問題
緩存雪崩問題
緩存擊穿問題
緩存的並發競爭問題
單線程的 Redis 為什么這么快
原因主要是以下三點:
- 純內存操作
- 單線程操作,避免了頻繁的上下文切換
- 采用了非阻塞 I/O 多路復用機制
Redis 的過期策略和內存淘汰機制
Redis 采用的是定期刪除+惰性刪除策略。
Redis 和數據庫雙寫一致性問題
一致性問題還可以再分為最終一致性和強一致性。數據庫和緩存雙寫,就必然會存在不一致的問題。前提是如果對數據有強一致性要求,不能放緩存。我們所做的一切,只能保證最終一致性。
另外,我們所做的方案從根本上來說,只能降低不一致發生的概率。因此,有強一致性要求的數據,不能放緩存。首先,采取正確更新策略,先更新數據庫,再刪緩存。其次,因為可能存在刪除緩存失敗的問題,提供一個補償措施即可,例如利用消息隊列。
緩存雪崩,即緩存同一時間大面積的失效,這個時候又來了一波請求,結果請求都懟到數據庫上,從而導致數據庫連接異常。
zadd marvel:user:f1:grade0:1010:20190731 2 1008
setnx mykey myvalue
,在redis sentinel集群中,這條命令先是落到了主庫。假設這時主庫down了,而這條數據還沒來得及同步到從庫,sentinel將從庫中的一台選舉為主庫了。這時,我們的新主庫中並沒有mykey這條數據,若此時另外一個client執行
setnx mykey hisvalue
, 也會成功,即也能得到鎖。這就意味着,此時有兩個client獲得了鎖
Redis常用命令
keys鍵操作
exists-----測試key是否存在
del-----刪除key
type-----返回key的類型
keys-----匹配滿足的key
rename------改key名
dbsize-----當前數據庫key的數量
expire-----設置key過期時間
ttl-----key剩余過期時間
move-----將key移動到指定數據庫
flushdb-----刪除當前數據庫的所有key
flushall-----刪除所有數據庫的key
String鍵操作
set-----設置單個key
mset-----批量添加key
mget-----批量獲取
incr-----key值+1
decr-----key值-1
incrby-----對key加指定值
decrby-----對key減定值
appeand-----在key值后追加
substr-----截取字符串(包前包后)
List類型操作
lpush-----在list頭部添加
rpop-----批量添加
llen-----(存在對應key返回長度,反之-1,類型不對應會報錯)
lrange-----在指定區間查找元素
rpush-----刪除尾部元素
lpop-----刪除頭部元素
ltrim-----截取list(保留)
Set類型操作
sadd-----添加set
srem-----刪除set中的指定元素
smove set1 set2-----將元素從set1轉移到set2
scard-----返回set中元素的個數
sismember-----判斷元素是否在set中
sinter set1 set2 set3...-----給所定set的交集
sunion
set1 set2 set3...-----給所定set的並集
sdiff set1 set2 set3...-----給所定set的差集
smembers-----返回set所對應的元素
Scort set
zadd-----添加
zrem--刪除
zincrby (鍵 加值 元素) -----對set指定元素加值
zrank-----返回元素下標(按‘權’從小到大排列)
zrevrank-----返回元素下標(按‘權’從大到小排列)
zrange-----返回集合,(按‘權’從小到大排列)
zrevrange-----返回集合(按‘權’從大到小排列)
zcard-----返回集合元素個數zscorde-----返回給定元素的‘權’
zremrangebyrank-----刪除集合指定區間的元素
使用命令fdisk -l查看當前磁盤的分區狀態
df -lh(df -k或者df -m) 是來自於coreutils 軟件包,系統安裝時,就自帶的;我們通過這個命令可以查看磁盤的使用情況以及文件系統被掛載的位置;
查詢項目日志 : tail -f catalina.out
總結
Redis初始化會創建一批數據庫,每個數據庫的內部數據結構都是字典,key-value的最終存儲也會落到字典上。
AOF持久化比RDB持久化頻率更高、速度更快;當有AOF持久化時,RDB持久化命令不會再執行;但當RDB持久化命令執行時,AOF命令會等待其執行完成后再執行,而其他RDB命令不會執行。
AOF文件重寫過程不會影響舊的AOF文件,即便AOF重寫過程失敗,也不會干擾原來的AOF恢復數據,只有在成功之后才會替換原來的文件。
RDB持久化是最直接的持久化方式,直接將內存中的數據保存到RDB文件中,當恢復時也是直接從RDB文件中恢復
1. redis 支持的 java 客戶端都有哪些?
Redisson、Jedis、lettuce等等,官方推薦使用Redisson。
2. jedis 和 redisson 有哪些區別?
Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支持。
Redisson實現了分布式和可擴展的Java數據結構,和Jedis相比,功能較為簡單,不支持字符串操作,不支持排序、事務、管道、分區等Redis特性。Redisson的宗旨是促進使用者對Redis的關注分離,從而讓使用者能夠將精力更集中地放在處理業務邏輯上。
3. 怎么保證緩存和數據庫數據的一致性?
-
合理設置緩存的過期時間。
-
新增、更改、刪除數據庫操作時同步更新 Redis,可以使用事物機制來保證數據的一致性。
4. redis 持久化有幾種方式?
Redis 的持久化有兩種方式,或者說有兩種策略:
-
RDB(Redis Database):指定的時間間隔能對你的數據進行快照存儲。
-
AOF(Append Only File):每一個收到的寫命令都通過write函數追加到文件中。
5. redis 怎么實現分布式鎖?
Redis 分布式鎖其實就是在系統里面占一個“坑”,其他程序也要占“坑”的時候,占用成功了就可以繼續執行,失敗了就只能放棄或稍后重試。
占坑一般使用 setnx(set if not exists)指令,只允許被一個程序占有,使用完調用 del 釋放鎖。
6. redis 分布式鎖有什么缺陷?
Redis 分布式鎖不能解決超時的問題,分布式鎖有一個超時時間,程序的執行如果超出了鎖的超時時間就會出現問題。
AOF