一、什麼是 redis?簡述它的優缺點?
redis 的全稱是:remote dictionary.server,本質上是一個 key-value 類型的內存數據庫,按期經過異步操做把數據庫數據 flush 到硬盤上進行保存。每秒能夠處理超過 10 萬次讀寫操做,是已知性能最快的key-value db。
redis多種數據結構,單個 value 的最大限 制是 512m,不像 memcached 只能保存 1mb 的數據,所以 redis 能夠消息雙向鏈表,消息隊列等服務。redis 能夠持久化其數據
另外 redis 也能夠對存入的 key-value 設置 expire 時間,主要缺點是數據庫容量受到物理內存的限制,不能用做海量數據的高性能 讀寫,所以 redis 適合的場景主要侷限在較小數據量的高性能操做和運算上。
redis 內部使用文件事件處理器file event handle,這個文件事件處理器是單線程的,因此 redis 才叫作單線程的模型。它採用 IO 多路複用機制同時監聽多個 socket,將產生事件的 socket 壓入內存隊列中,事件分派器根據 socket 上的事件類型來選擇對應的事件處理器進行處理。
1.noeviction:返回錯誤當內存限制達到
2.allkeys-lru: 嘗試回收最少使用的鍵(lru)
3.volatile-lru: 嘗試回收最少使用的鍵(lru),但僅限於在過時集合的鍵。
4.allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
5.volatile-random: 回收隨機的鍵,但僅限於在過時集合的鍵。
6.volatile-ttl: 回收在過時集合的鍵,而且優先回收存活時間較短的鍵。
redis內存數據集大小上升到必定大小的時候,就會施行數據淘汰策略allkeys-lru,計算預估出20w數據所佔空間,而後將redis限制爲此數,同時設置redis回收策略爲allkeys-lru回收最少使用.
redisson、jedis、lettuce等等,官方推薦使用redisson。
五、說說redis哈希槽的概念?
在redis節點發送心跳包時須要把全部的槽放到這個心跳包裏,以便讓節點知道當前集羣信息,16384=16k,在發送心跳包時使用bitmap壓縮後是2k(2 * 8 (8 bit) * 1024(1k) = 2k),也就是說使用2k的空間建立了16k的槽數。
雖然使用crc16算法最多能夠分配65535(2^16-1)個槽位,65535=65k,壓縮後就是8k(8 * 8 (8 bit) * 1024(1k) = 8k),也就是說須要須要8k的心跳包,做者認爲通常狀況下一個redis集羣不會有超過1000個master節點,因此16k的槽位是個比較合適的選擇。
redis集羣沒有使用一致性hash,而是引入了哈希槽的概念,redis集羣有16384個哈希槽,每一個key經過crc16校驗後對16384取模來決定放置哪一個槽,集羣的每一個節點負責一部分hash槽。
六、怎麼理解redis事務?
事務指令:multi :開啓事務
exec :提交事務
discard :放棄事務
watch :當被監控的鍵被修改後取消以後的事務
unwatch
redis事務不能保證每條指令徹底正確執行,只能保證此事務數據的原子性,單獨的一組操做。不支持失敗回滾。
7、redis回收策略:
惰性刪除:
讀刪除:用於當客戶端讀取帶有超時屬性的鍵時,若是已經超過鍵設置的過時時間,會執行刪除操做並返回空,這種策略是出於節省cpu成本考慮,不須要單獨維護ttl鏈表來處理過時鍵的刪除。
寫刪除:客服端運行新命令致使內存不足時,redis將根據回收策略回收。
定時任務刪除:redis內部維護一個定時任務,默認每秒運行10次(經過配置hz控制)。定時任務中刪除過時鍵邏輯採用了自適應算法,根據鍵的過時比例,使用快慢兩種速率模式回收鍵。
8、使用過redis分佈式鎖麼,它是怎麼實現的及缺點?
先拿setnx來爭搶鎖,搶到以後,再用expire給鎖加一個過時時間防止鎖忘記了釋放。可使用redis事務機制 將兩條指令合併執行。
redis並不能保證數據的強一致性,這意味這在實際中集羣在特定的條件下可能會丟失寫操做。在redis主實例宕機的時候,可能多個客戶端同時完成加鎖。
緩存穿透:指查詢一個必定不存在的數據,因爲緩存是不命中時查詢數據庫。若流量大時,數據庫可能會宕機。
解決方案:
1.布隆過濾器:將全部可能存在的key放到一個足夠大bitmap中。必定不存在的數據直接被bitmap攔截掉。
2.短時緩存:若數據庫查詢的數據爲空,扔把key緩存起來,設置一個短期的過時時間。數據插入後清理。
緩存擊穿:某個熱點key失效後,大併發訪問,致使數據庫宕機。
解決方案:
1.加鎖排隊:互斥鎖對某個key只容許一個線程查數據寫緩存,其餘線程等待。
緩存雪崩:緩存時集中在某一時段同時失效,請求所有轉發到數據庫,數據庫瞬時壓力太重致使雪崩效應。
解決方案:
1.緩存時間增長隨機值:每一個緩存時間不同,避免集體失效。
緩存預熱:系統上線前把熱點數據加入redis緩存中。
使用 LinkedHashMap(int initialcapacity,float loadfactor,boolean accessorder) 第三個參數設置爲true,表明按訪問順序排序,可做爲LRU緩存。設置爲false 表明按插入順序排序,可做爲fifo緩存。
LRU算法實現:1.經過雙向鏈表來實現,新數據插入到鏈表頭部;2.每當緩存命中(即緩存數據被訪問),則將數據移到鏈表頭部;3.當鏈表滿的時候,將鏈表尾部的數據丟棄。
使用sortedset,使用時間戳作score, 消息內容做爲key,調用zadd來生產消息,消費者使用zrangbyscore獲取n秒以前的數據作輪詢處理。
13.redis緩存數據域數據庫不一致性問題解決方案
採用 先更新數據庫,再刪除緩存
1.主從引發數據庫不一致的解決方案
主庫更新後,redis設置一個短有效期(主從同步延時時間)緩存,當業務查緩存時,先判斷是否有這個緩存,有這個緩存直接讀主庫,不然讀從庫數據。
2. 緩存與數據庫不一致
a線程刪除緩存,操做數據庫,b線程查詢,將數據庫數據插入緩存,因爲併發問題,致使髒數據被拉長。
解決方案:訂閱數據庫binlog,獲取並判斷操做的數據。另起程序進行刪除緩存數據,從新寫入數據。
14. redis集羣方案
redis-cluster採用無中心結構,每一個節點保存數據和整個集羣狀態,每一個節點都和其餘全部節點鏈接。其redis-cluster架構圖以下:
客戶端與redis節點直連,不須要中間proxy層.客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可。
redis-cluster選舉:選舉過程當中全部master參與,超過半數以上master間節點通訊,認爲當前master節點掛掉。若是集羣任意master掛掉且沒有slave節點,集羣不可用。超過半數以上master掛掉,也不可用。
相對於單機redis,功能上有一些限制:
(1)key批量操做支持有限;
(2)只支持多key在同一節點上的事務操做,當多個key分佈在不一樣節點時,不支持事務操做;
(3)key做爲數據分區的最小粒度,不能將一個大的鍵值對象如hash, list等映射到不一樣的節點;
15.redis的持久化方案
save 同步保存操做,將redis數據快照以rdb文件形式保存到硬盤,阻塞客戶端,影響性能
bgsave 異步保存數據
bgrewriteaof 異步優化aof文件
master主:主開啓AOF模式
slave從:從開啓RDB模式
RDB(redis database:在不一樣的時間點將 redis 的數據生成的快照同步到磁盤等介質上):內存到硬盤的快照,按期更新。缺點:耗時,耗性能(fork+io 操做),易丟失數據。
AOF(append only file:將 redis 所執行過的全部指令都記錄下來,在下次 redis 重啓時,只 須要執行指令就能夠了):寫日誌。缺點:體積大,恢復速度慢。
字符串:
setnx(key,value) 只在鍵 key 不存在的狀況下, 將鍵 key 的值設置爲 value 。key存在,不作任何操做。
setex(key,seconds,value) 將key設置及生存時間seconds秒,原值存在覆蓋。
psetex(key,milliseconds,value) 與setex一樣,只是單位是毫秒。
getset(key,value) 設置新值並返回舊值,不存在返回nil
setrange(key,offset,value) 從偏移量開始offset開始
mset 同時給多個key複製
哈希表(map):
hset(hash field value) 將哈希表 hash 中域 field 的值設置爲 value
hmset key field value [field value …] 同時將多個 field-value (域-值)對設置到哈希表 key 中。
hget hash field 返回哈希表中給定域的值。
hgetall key 返回哈希表 key 中,全部的域和值。
隊列(queue):
lpush key value [value …] 將一個或多個值 value 插入到列表 key 的表頭
lpop key 移除並返回列表 key 的頭元素,不存在返回nil
lset key index value 將列表 key 下標爲 index 的元素的值設置爲 value 。
brpop key [key …] timeout 在超時時間內移除列表尾元素,阻塞的。
集合:
sadd key member [member …] 將一個或多個 member 元素加入到集合 key 當中,已經存在於集合的 member 元素將被忽略
sismember key member 若是 member 元素是集合的成員,返回 1 。 若是 member 元素不是集合的成員,或 key 不存在,返回 0 。
spop key 移除集合key的隨機元素
smembers key 返回集合 key 中的全部成員。
sdiff key [key …] 返回給定多個集合之間的差集。
有序集合:
zadd key score member [[score member] [score member] …] 將一個或多個 member 元素及其 score 值加入到有序集 key 當中。
zscore key member 返回有序集 key 中,成員 member 的 score 值。
zcount key min max score 值在 min 和 max 之間的成員的數量。
zrange key start stop [withscores] 返回有序集 key 中,指定區間內的成員(從小到大)。
zrank key member 返回有序集 key 中成員 member 的排名。其中有序集成員按 score 值遞增(從小到大)順序排列。
zrem key member [member …] 移除有序集 key 中的一個或多個成員,不存在的成員將被忽略。
時效性:
expire(key,seconds) 爲給定 key 設置生存時間,當 key 過時時(生存時間爲 0 ),它會被自動刪除。
expireat( key,timestamp) 設置過時時間戳,expireatcache1355292000# 這個 key 將在 2012.12.12 過時
ttl(key) 返回剩餘時間
persist key 移除key有效期,轉換成永久的
數據指令:
keys pattern 符合給定模式的 key 列表。阻塞的
scan 異步的 有重複
也能夠自定義數據結構hyperloglog、geo、pub/sub。