Redis

為什么使用Redis
  • 高性能:

    假如用戶第一次訪問數(shù)據(jù)庫中的某些數(shù)據(jù)壤圃。這個過程會比較慢,因為是從硬盤上讀取的琅轧。將該用戶訪問的數(shù)據(jù)存在數(shù)緩存中伍绳,這樣下一次再訪問這些數(shù)據(jù)的時候就可以直接從緩存中獲取了。操作緩存就是直接操作內(nèi)存乍桂,所以速度相當(dāng)快冲杀。如果數(shù)據(jù)庫中的對應(yīng)數(shù)據(jù)改變的之后,同步改變緩存中相應(yīng)的數(shù)據(jù)即可睹酌!

  • 高并發(fā):

    直接操作緩存能夠承受的請求是遠(yuǎn)遠(yuǎn)大于直接訪問數(shù)據(jù)庫的权谁,所以我們可以考慮把數(shù)據(jù)庫中的部分?jǐn)?shù)據(jù)轉(zhuǎn)移到緩存中去,這樣用戶的一部分請求會直接到緩存這里而不用經(jīng)過數(shù)據(jù)庫憋沿。

使用redis的好處旺芽?
  1. 速度快,因為數(shù)據(jù)存在內(nèi)存中卤妒,類似于HashMap甥绿,HashMap的優(yōu)勢就是查找和操作的時間復(fù)雜度都是O(1)

  2. 支持豐富數(shù)據(jù)類型,支持string则披,list共缕,set,sorted set士复,hash

  3. 支持事務(wù) :redis對事務(wù)是部分支持的图谷,如果是在入隊時報錯,那么都不會執(zhí)行阱洪;在非入隊時報錯便贵,那么成功的就會成功執(zhí)行。 redis監(jiān)控:鎖的介紹

  4. 豐富的特性:可用于緩存冗荸,消息承璃,按key設(shè)置過期時間,過期后將會自動刪除蚌本。

分布式緩存和本地緩存有啥區(qū)別盔粹?讓你自己設(shè)計本地緩存怎么設(shè)計隘梨?如何解決緩存過期問題?如何解決內(nèi)存溢出問題舷嗡?
分布式緩存和本地緩存的區(qū)別
  1. 分布式緩存一致性更好一點轴猎,本地緩存 每個實例都有自己的緩存,可能會存在不一致的情況进萄。

  2. 本地緩存會占用堆內(nèi)存捻脖,影響垃圾回收、影響系統(tǒng)性能中鼠。分布式緩存兩大開銷會導(dǎo)致其慢于本地緩存可婶,網(wǎng)絡(luò)延遲和對象序列化

  3. 進(jìn)程內(nèi)緩存適用于較小且頻率可見的訪問場景,尤其適用于不變對象援雇,對于較大且不可預(yù)見的訪問扰肌,最好采用分布式緩存。

如何解決緩存過期問題

緩存失效

引起這個原因的主要因素是高并發(fā)下熊杨,我們一般設(shè)定一個緩存的過期時間時,可能有一些會設(shè)置5分鐘啊盗舰,10分鐘這些晶府;并發(fā)很高時可能會出在某一個時間同時生成了很多的緩存,并且過期時間在同一時刻钻趋,這個時候就可能引發(fā)——當(dāng)過期時間到后川陆,這些緩存同時失效,請求全部轉(zhuǎn)發(fā)到DB蛮位,DB可能會壓力過重较沪。

處理方法:

一個簡單方案就是將緩存失效時間分散開,不要所以緩存時間長度都設(shè)置成5分鐘或者10分鐘失仁;比如我們可以在原有的失效時間基礎(chǔ)上增加一個隨機(jī)值尸曼,比如1-5分鐘隨機(jī),這樣每一個緩存的過期時間的重復(fù)率就會降低萄焦,就很難引發(fā)集體失效的事件控轿。

緩存失效時產(chǎn)生的雪崩效應(yīng),將所有請求全部放在數(shù)據(jù)庫上拂封,這樣很容易就達(dá)到數(shù)據(jù)庫的瓶頸茬射,導(dǎo)致服務(wù)無法正常提供。盡量避免這種場景的發(fā)生冒签。

redis和memcached的區(qū)別
  1. Redis和Memcache都是將數(shù)據(jù)存放在內(nèi)存中在抛,都是內(nèi)存數(shù)據(jù)庫。不過memcache還可用于緩存其他東西萧恕,例如圖片刚梭、視頻等等肠阱;

  2. Memcached僅支持簡單的key-value結(jié)構(gòu)的數(shù)據(jù)記錄。Redis不僅僅支持簡單的k/v類型的數(shù)據(jù)望浩,同時還提供list辖所,set,hash等數(shù)據(jù)結(jié)構(gòu)的存儲磨德;

  3. 虛擬內(nèi)存--Redis當(dāng)物理內(nèi)存用完時缘回,可以將一些很久沒用到的value 交換到磁盤;

  4. 過期策略--memcache在set時就指定典挑,例如set key1 0 0 8,即永不過期酥宴。Redis可以通過例如expire 設(shè)定,例如expire name 10您觉;

  5. 分布式--設(shè)定memcache集群拙寡,利用magent做一主多從;redis可以做一主多從。都可以一主一從琳水;

  6. 存儲數(shù)據(jù)安全--memcache掛掉后肆糕,數(shù)據(jù)沒了;redis可以定期保存到磁盤(持久化)在孝;

  7. 災(zāi)難恢復(fù)--memcache掛掉后诚啃,數(shù)據(jù)不可恢復(fù); redis數(shù)據(jù)丟失后可以通過aof恢復(fù);

  8. Redis支持?jǐn)?shù)據(jù)的備份私沮,即master-slave模式的數(shù)據(jù)備份始赎;

redis常用數(shù)據(jù)結(jié)構(gòu)和使用場景
  • String(字符串

    • set 鍵 值 (設(shè)置鍵值對

    • get 鍵 (根據(jù)鍵取值

    String結(jié)構(gòu)又存在3種類型,分別是字符串仔燕、數(shù)值造垛、bitmap。

    使用場景

    字符串:分布式鎖

    數(shù)值:在一些系統(tǒng)中看似不是很重要的統(tǒng)計晰搀,搶購五辽,秒殺,詳情頁中數(shù)據(jù)統(tǒng)計厕隧,點贊奔脐,評論等∮跆郑可以規(guī)避并發(fā)情況下對數(shù)據(jù)庫的事務(wù)操作髓迎,完全由redis內(nèi)存操作代替。

    bitmap:用戶簽到建丧、在線用戶統(tǒng)計排龄、統(tǒng)計活躍用戶。

  • Hash(哈希

    • hset 鍵 字段 值

    • hmset 鍵 字段1 值1 字段2 值2 字段3 值3 字段n 值n

    • hger 鍵 字段

    • hmget 鍵 字段1 字段2 字段3 字段n

    • hgetall 鍵

      容量:每個hash可以存儲4294967295個鍵值對(2的32次方-1)

    使用場景:點贊、收藏橄维、詳情頁等

  • Set(集合

    • sadd 鍵 值1 值2 值3 值n

    • smembers 鍵

    使用場景:

    1. 關(guān)注集合:共同關(guān)注尺铣、二度好友

    2. 點贊集合

    3. 抽獎集合

    4. 用戶標(biāo)簽

  • List(列表

    • lpush 鍵 值1 值2 值3 值n

    • lrange 鍵 開始下標(biāo) 結(jié)束下標(biāo)

      容量:每個hash可以存儲4294967295個鍵值對(2的32次方-1)

    使用場景:

    1. 隊列,比如:關(guān)注隊列、粉絲隊列

    2. 消息隊列

  • Zset(Sorted Set: 有序集合

    • zadd 鍵 分?jǐn)?shù)1 值1 分?jǐn)?shù)2 值2 分?jǐn)?shù)n 值n

    • zrange 鍵 開始下標(biāo) 結(jié)束下標(biāo)

    • zrangebyscore 鍵 開始分值 結(jié)束分值

    使用場景:

    1. 排行榜

    2. 時間軸

    3. 優(yōu)先級隊列

Zset底層實現(xiàn)争舞?跳表搜索插入刪除過程凛忿?

zset的編碼有ziplistskiplist兩種。 底層分別使用ziplist(壓縮鏈表)skiplist(跳表)實現(xiàn)竞川。

當(dāng)zset滿足以下兩個條件的時候店溢,使用ziplist:

  1. 保存的元素少于128個
  1. 保存的所有元素大小都小于64字節(jié)

不滿足這兩個條件則使用skiplist (注意:這兩個數(shù)值是可以通過redis.confzset-max-ziplist-entrieszset-max-ziplist-value選項 進(jìn)行修改。)

  • ziplist編碼

    ziplist 編碼的有序集合對象使用壓縮列表作為底層實現(xiàn)委乌,每個集合元素使用兩個緊挨在一起的壓縮列表節(jié)點來保存床牧,第一個節(jié)點保存元素的成員,第二個節(jié)點保存元素的分值遭贸。并且壓縮列表內(nèi)的集合元素按分值從小到大的順序進(jìn)行排列戈咳,小的放置在靠近表頭的位置,大的放置在靠近表尾的位置壕吹。

  • skiplist編碼

    skiplist 編碼的有序集合對象使用 zet 結(jié)構(gòu)作為底層實現(xiàn)著蛙,一個 zset 結(jié)構(gòu)同時包含一個字典和一個跳表:

    字典的鍵保存元素的值,字典的值則保存元素的分值耳贬;跳躍表節(jié)點的 object 屬性保存元素的成員册踩,跳躍表節(jié)點的 score 屬性保存元素的分值。

    這兩種數(shù)據(jù)結(jié)構(gòu)會通過指針來共享相同元素的成員和分值效拭,所以不會產(chǎn)生重復(fù)成員和分值,造成內(nèi)存的浪費胖秒。

    注意:單獨使用字典缎患,時間復(fù)雜度很低(O(1)),但字典是以無序的方式保存集合元素的阎肝,需要重新進(jìn)行排序挤渔;單獨使用跳表,雖然能執(zhí)行范圍操作风题,但是查找操作從O(1)的復(fù)雜度變?yōu)榱薕(logN)判导。所以使用兩種數(shù)據(jù)結(jié)構(gòu)共同實現(xiàn)

redis過期淘汰策略
淘汰策略

定期刪除+惰性刪除

所謂定期刪除,指的是redis默認(rèn)是每隔100ms就隨機(jī)抽取一些設(shè)置了過期時間的key沛硅,檢查其是否過期眼刃,如果過期就刪除。(注意:是隨機(jī))

但是摇肌,定期刪除可能會導(dǎo)致很多過期key到了時間并沒有被刪除掉擂红,所以就得靠惰性刪除了。

惰性刪除就是在你獲取某個key的時候围小,redis會檢查一下 昵骤,這個key如果設(shè)置了過期時間那么是否過期了树碱?如果過期了此時就會刪除,不會給你返回任何東西变秦。并不是key到時間就被刪除掉成榜,而是你查詢這個key的時候,redis再懶惰的檢查一下

通過上述兩種手段結(jié)合起來蹦玫,保證過期的key一定會被淘汰

內(nèi)存淘汰機(jī)制

如果redis的內(nèi)存占用過多的時候赎婚,此時會進(jìn)行內(nèi)存淘汰,有如下一些策略:

  • noeviction:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時钳垮,新寫入操作會報錯(一般沒人用)

  • allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時惑淳,在鍵空間中,移除最近最少使用的key(這個是最常用的)

  • allkeys-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時饺窿,在鍵空間中歧焦,隨機(jī)移除某個key(一般沒人用)

  • volatile-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時,在設(shè)置了過期時間的鍵空間中肚医,移除最近最少使用的key(這個一般不太合適)

  • volatile-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時绢馍,在設(shè)置了過期時間的鍵空間中,隨機(jī)移除某個key

  • volatile-ttl:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時肠套,在設(shè)置了過期時間的鍵空間中舰涌,有更早過期時間的key優(yōu)先移除

redis持久化機(jī)制?都有什么優(yōu)缺點你稚?持久化的時候還能接受請求嗎瓷耙?

RDB機(jī)制和AOF機(jī)制

RDB:

RDB其實就是把數(shù)據(jù)以快照的形式保存在磁盤上。什么是快照呢刁赖,你可以理解成把當(dāng)前時刻的數(shù)據(jù)拍成一張照片保存下來搁痛。

RDB持久化是指在指定的時間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤。也是默認(rèn)的持久化方式宇弛,這種方式是就是將內(nèi)存中數(shù)據(jù)以快照的方式寫入到二進(jìn)制文件中,默認(rèn)的文件名為dump.rdb鸡典。

觸發(fā)機(jī)制

  1. save觸發(fā)方式(同步)

    該命令會阻塞當(dāng)前Redis服務(wù)器,執(zhí)行save命令期間枪芒,Redis不能處理其他命令彻况,直到RDB過程完成為止。執(zhí)行完成時候如果存在老的RDB文件舅踪,就把新的替代掉舊的纽甘。我們的客戶端可能都是幾萬或者是幾十萬,這種方式顯然不可取抽碌。

  2. bgsave觸發(fā)方式(異步)

    執(zhí)行該命令時贷腕,Redis會在后臺異步進(jìn)行快照操作,快照同時還可以響應(yīng)客戶端請求。

    具體操作是Redis進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程泽裳,RDB持久化過程由子進(jìn)程負(fù)責(zé)瞒斩,完成后自動結(jié)束。阻塞只發(fā)生在fork階段涮总,一般時間很短胸囱。基本上 Redis 內(nèi)部所有的RDB操作都是采用 bgsave 命令瀑梗。

  3. 自動觸發(fā)

    自動觸發(fā)是由我們的配置文件來完成的烹笔。

RDB 的優(yōu)勢和劣勢

①優(yōu)勢

(1)RDB文件緊湊,全量備份抛丽,非常適合用于進(jìn)行備份和災(zāi)難恢復(fù)谤职。

(2)生成RDB文件的時候,redis主進(jìn)程會fork()一個子進(jìn)程來處理所有保存工作亿鲜,主進(jìn)程不需要進(jìn)行任何磁盤IO操作允蜈。

(3)RDB 在恢復(fù)大數(shù)據(jù)集時的速度比 AOF 的恢復(fù)速度要快。

②劣勢

RDB快照是一次全量備份蒿柳,存儲的是內(nèi)存數(shù)據(jù)的二進(jìn)制序列化形式饶套,存儲上非常緊湊。當(dāng)進(jìn)行快照持久化時垒探,會開啟一個子進(jìn)程專門負(fù)責(zé)快照持久化妓蛮,子進(jìn)程會擁有父進(jìn)程的內(nèi)存數(shù)據(jù),父進(jìn)程修改內(nèi)存子進(jìn)程不會反應(yīng)出來圾叼,所以在快照持久化期間修改的數(shù)據(jù)不會被保存蛤克,可能丟失數(shù)據(jù)。

AOF:

全量備份總是耗時的夷蚊,有時候我們提供一種更加高效的方式AOF咖耘,工作機(jī)制很簡單,redis會將每一個收到的寫命令都通過write函數(shù)追加到文件中撬码。通俗的理解就是日志記錄。

AOF也有三種觸發(fā)機(jī)制

(1)每修改同步always:同步持久化 每次發(fā)生數(shù)據(jù)變更會被立即記錄到磁盤 性能較差但數(shù)據(jù)完整性比較好

(2)每秒同步everysec:異步操作版保,每秒記錄 如果一秒內(nèi)宕機(jī)呜笑,有數(shù)據(jù)丟失

(3)不同no:從不同步

AOF的優(yōu)缺點

優(yōu)點

(1)AOF可以更好的保護(hù)數(shù)據(jù)不丟失,一般AOF會每隔1秒彻犁,通過一個后臺線程執(zhí)行一次fsync操作叫胁,最多丟失1秒鐘的數(shù)據(jù)。(2)AOF日志文件沒有任何磁盤尋址的開銷汞幢,寫入性能非常高驼鹅,文件不容易破損。

(3)AOF日志文件即使過大的時候,出現(xiàn)后臺重寫操作输钩,也不會影響客戶端的讀寫豺型。

(4)AOF日志文件的命令通過非常可讀的方式進(jìn)行記錄买乃,這個特性非常適合做災(zāi)難性的誤刪除的緊急恢復(fù)姻氨。比如某人不小心用flushall命令清空了所有數(shù)據(jù),只要這個時候后臺rewrite還沒有發(fā)生剪验,那么就可以立即拷貝AOF文件肴焊,將最后一條flushall命令給刪了,然后再將該AOF文件放回去功戚,就可以通過恢復(fù)機(jī)制娶眷,自動恢復(fù)所有數(shù)據(jù)

缺點

(1)對于同一份數(shù)據(jù)來說,AOF日志文件通常比RDB數(shù)據(jù)快照文件更大

(2)AOF開啟后啸臀,支持的寫QPS會比RDB支持的寫QPS低届宠,因為AOF一般會配置成每秒fsync一次日志文件,當(dāng)然壳咕,每秒一次fsync席揽,性能也還是很高的

(3)以前AOF發(fā)生過bug,就是通過AOF記錄的日志谓厘,進(jìn)行數(shù)據(jù)恢復(fù)的時候幌羞,沒有恢復(fù)一模一樣的數(shù)據(jù)出來。

持久化的時候還能接受請求嗎竟稳?

RDB就是生成某個時間點快照属桦,有異步bgsave和同步save,同步的話肯定不能對外服務(wù)了他爸,異步是通過fork子進(jìn)程完成的聂宾,需要注意的是,在異步的時候诊笤,數(shù)據(jù)可能發(fā)生變化系谐,redis并不是直接復(fù)制一份進(jìn)行復(fù)制,redis運(yùn)用寫時復(fù)制cow思想讨跟,即一開始redis和子進(jìn)程都指向同一個數(shù)據(jù)纪他,當(dāng)某個key改變時redis主進(jìn)程指向新的,子進(jìn)程不變晾匠。

AOF也是同步不行茶袒,異步可以

redis事務(wù)

概念:

Redis 事務(wù)的本質(zhì)是一組命令的集合。事務(wù)支持一次執(zhí)行多個命令凉馆,一個事務(wù)中所有命令都會被序列化薪寓。在事務(wù)執(zhí)行過程亡资,會按照順序串行化執(zhí)行隊列中的命令,其他客戶端提交的命令請求不會插入到事務(wù)執(zhí)行命令序列中向叉。

總結(jié)說:redis事務(wù)就是一次性锥腻、順序性、排他性的執(zhí)行一個隊列中的一系列命令植康。

Redis事務(wù)沒有隔離級別的概念:

批量操作在發(fā)送 EXEC 命令前被放入隊列緩存旷太,并不會被實際執(zhí)行,也就不存在事務(wù)內(nèi)的查詢要看到事務(wù)里的更新销睁,事務(wù)外查詢不能看到供璧。

Redis事務(wù)不保證原子性:

Redis中,單條命令是原子性執(zhí)行的冻记,但事務(wù)不保證原子性睡毒,且沒有回滾。事務(wù)中任意命令執(zhí)行失敗冗栗,其余的命令仍會被執(zhí)行演顾。

Redis事務(wù)的三個階段:

  • 開始事務(wù)

  • 命令入隊

  • 執(zhí)行事務(wù)

Redis事務(wù)相關(guān)命令:

watch key1 key2 ... : 監(jiān)視一或多個key,如果在事務(wù)執(zhí)行之前,被監(jiān)視的key被其他命令改動隅居,則事務(wù)被打斷 ( 類似樂觀鎖 )

multi : 標(biāo)記一個事務(wù)塊的開始( queued )

exec : 執(zhí)行所有事務(wù)塊的命令 ( 一旦執(zhí)行exec后钠至,之前加的監(jiān)控鎖都會被取消掉 )

discard : 取消事務(wù),放棄事務(wù)塊中的所有命令

unwatch : 取消watch對所有key的監(jiān)控

緩存雪崩和緩存穿透胎源,以及解決方法
  • 緩存穿透

    • 緩存穿透是指緩存和數(shù)據(jù)庫中沒有的數(shù)據(jù)棉钧,而用戶不斷發(fā)起請求,若發(fā)起 id為“-1”的數(shù)據(jù)或id為特別大而不存在的數(shù)據(jù)涕蚤,此時的用戶很可能是攻擊者宪卿,攻擊會導(dǎo)致數(shù)據(jù)庫壓力過大,而影響數(shù)據(jù)庫的性能

    • 解決方案

      1. 接口層增加校驗万栅,如用戶鑒權(quán)校驗佑钾,id做基礎(chǔ)校驗,id<=0的直接攔截

      2. 從緩存取不到的數(shù)據(jù)烦粒,在數(shù)據(jù)庫中也沒有取到休溶,這時可以設(shè)置該id對應(yīng)的value為null,設(shè)置一定的有效時間扰她,可以防止攻擊用戶在一定時間內(nèi)反復(fù)使用同一id進(jìn)行暴力攻擊

  • 緩存擊穿

    • 緩存擊穿是指緩存中沒有但是數(shù)據(jù)庫中有的數(shù)據(jù)(一般是由于緩存時間到期銷毀)兽掰,這時由于并發(fā)用戶特別多,同時讀緩存沒有讀到數(shù)據(jù)义黎,又同時去數(shù)據(jù)庫中取數(shù)據(jù),使數(shù)據(jù)庫壓力瞬間增大豁跑,造成數(shù)據(jù)庫性能大幅度降低

    • 解決方案

      1. 設(shè)置熱點數(shù)據(jù)永不過期

      2. 加互斥鎖

      3. 定時任務(wù)更新緩存數(shù)據(jù)

  • 緩存雪崩

    • 緩存雪崩是指緩存中數(shù)據(jù)大批量到過期時間廉涕,而查詢數(shù)量巨大泻云,引起數(shù)據(jù)庫壓力巨大甚至down機(jī)。和緩存擊穿不同的是狐蜕,緩存擊穿是指大量用戶并發(fā)查同一條數(shù)據(jù)宠纯,緩存雪崩是指大量不同數(shù)據(jù)都在同一時間過期了,大量用戶不能從緩存中得到這些數(shù)據(jù)层释,而進(jìn)入數(shù)據(jù)庫查詢

    • 解決方案

      1. 緩存數(shù)據(jù)的過期時間設(shè)置為隨機(jī)婆瓜,防止大量數(shù)據(jù)在同一時間過期的現(xiàn)象出現(xiàn)

      2. 如果緩存數(shù)據(jù)庫是分布式部署,將熱點數(shù)據(jù)均勻分布在不同緩存數(shù)據(jù)庫中

      3. 設(shè)置熱點數(shù)據(jù)永不過期

如何保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性贡羔?

選擇淘汰緩存

原因:數(shù)據(jù)可能為簡單數(shù)據(jù)廉白,也可能為較復(fù)雜的數(shù)據(jù),復(fù)雜數(shù)據(jù)進(jìn)行緩存的更新操作乖寒,成本較高猴蹂,因此一般推薦淘汰緩存

方案:

先刪除緩存,后更新數(shù)據(jù)庫楣嘁。

  • 更新的時候磅轻,先刪除緩存,然后再更新數(shù)據(jù)庫逐虚。

  • 讀的時候聋溜,先讀緩存;如果沒有的話叭爱,就讀數(shù)據(jù)庫撮躁,同時將數(shù)據(jù)放入緩存,并返回響應(yīng)涤伐。

原因:因為即使后面更新數(shù)據(jù)庫失敗了馒胆,緩存是空的,讀的時候會從數(shù)據(jù)庫中重新拉凝果,雖然都是舊數(shù)據(jù)祝迂,但數(shù)據(jù)是一致的。

  1. 有如下場景:同時有一個請求A進(jìn)行更新操作器净,另一個請求B進(jìn)行查詢操作型雳。 (1)請求A進(jìn)行寫操作,刪除緩存 (2)請求B查詢發(fā)現(xiàn)緩存不存在 (3)請求B去數(shù)據(jù)庫查詢得到舊值 (4)請求B將舊值寫入緩存 (5)請求A將新值寫入數(shù)據(jù)庫

次數(shù)便出現(xiàn)了數(shù)據(jù)不一致問題山害。采用延時雙刪策略得以解決

  1. 數(shù)據(jù)庫讀寫分離的場景:

兩個請求纠俭,一個請求A進(jìn)行更新操作,另一個請求B進(jìn)行查詢操作浪慌。

(1)請求A進(jìn)行寫操作冤荆,刪除緩存 (2)請求A將數(shù)據(jù)寫入數(shù)據(jù)庫了, (3)請求B查詢緩存發(fā)現(xiàn)权纤,緩存沒有值 (4)請求B去從庫查詢钓简,這時乌妒,還沒有完成主從同步,因此查詢到的是舊值 (5)請求B將舊值寫入緩存 (6)數(shù)據(jù)庫完成主從同步外邓,從庫變?yōu)樾轮?/p>

依舊采用延時雙刪策略解決此問題

延時雙刪是將1秒內(nèi)所造成的緩存臟數(shù)據(jù)撤蚊,再次刪除。

redis是單線程還是多線程损话?為什么那么快侦啸?

Redis是單線程的

為什么快?

  1. Redis完全基于內(nèi)存丧枪,絕大部分請求是純粹的內(nèi)存操作光涂,非常快速豪诲。數(shù)據(jù)存在內(nèi)存中顶捷,類似于HashMap,HashMap的優(yōu)勢就是查找和操作的時間復(fù)雜度都是O(1)

  2. 數(shù)據(jù)結(jié)構(gòu)簡單屎篱,對數(shù)據(jù)操作也簡單服赎,Redis中的數(shù)據(jù)結(jié)構(gòu)是專門進(jìn)行設(shè)計的;

  3. 使用多路I/O復(fù)用模型交播,非阻塞IO重虑;

  4. 采用單線程,避免了不必要的上下文切換和競爭條件秦士,也不存在多進(jìn)程或者多線程導(dǎo)致的切換而消耗 CPU缺厉,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作隧土,沒有因為可能出現(xiàn)死鎖而導(dǎo)致的性能消耗提针;

五種IO模型的區(qū)別
  1. 阻塞式IO
  • 使用系統(tǒng)調(diào)用,并一直阻塞直到內(nèi)核將數(shù)據(jù)準(zhǔn)備好曹傀,之后再由內(nèi)核緩沖區(qū)復(fù)制到用戶態(tài)辐脖,在等待內(nèi)核準(zhǔn)備的這段時間什么也干不了

  • 下圖函數(shù)調(diào)用期間,一直被阻塞皆愉,直到數(shù)據(jù)準(zhǔn)備好且從內(nèi)核復(fù)制到用戶程序才返回嗜价,這種IO模型為阻塞式IO

  • 阻塞式IO式最流行的IO模型

  1. 非阻塞式IO
  • 內(nèi)核在沒有準(zhǔn)備好數(shù)據(jù)的時候會返回錯誤碼,而調(diào)用程序不會休眠幕庐,而是不斷輪詢詢問內(nèi)核數(shù)據(jù)是否準(zhǔn)備好

  • 下圖函數(shù)調(diào)用時久锥,如果數(shù)據(jù)沒有準(zhǔn)備好,不像阻塞式IO那樣一直被阻塞异剥,而是返回一個錯誤碼瑟由。數(shù)據(jù)準(zhǔn)備好時,函數(shù)成功返回冤寿。

  • 應(yīng)用程序?qū)@樣一個非阻塞描述符循環(huán)調(diào)用成為輪詢歹苦。

  • 非阻塞式IO的輪詢會耗費大量cpu绿鸣,通常在專門提供某一功能的系統(tǒng)中才會使用。通過為套接字的描述符屬性設(shè)置非阻塞式暂氯,可使用該功能

  1. IO多路復(fù)用
  • 類似與非阻塞,只不過輪詢不是由用戶線程去執(zhí)行亮蛔,而是由內(nèi)核去輪詢痴施,內(nèi)核監(jiān)聽程序監(jiān)聽到數(shù)據(jù)準(zhǔn)備好后,調(diào)用內(nèi)核函數(shù)復(fù)制數(shù)據(jù)到用戶態(tài)

  • 下圖中select這個系統(tǒng)調(diào)用究流,充當(dāng)代理類的角色辣吃,不斷輪詢注冊到它這里的所有需要IO的文件描述符芬探,有結(jié)果時,把結(jié)果告訴被代理的recvfrom函數(shù)偷仿,它本尊再親自出馬去拿數(shù)據(jù)

  • IO多路復(fù)用至少有兩次系統(tǒng)調(diào)用,如果只有一個代理對象酝静,性能上是不如前面的IO模型的,但是由于它可以同時監(jiān)聽很多套接字别智,所以性能比前兩者高

  • 多路復(fù)用包括:

    • select:線性掃描所有監(jiān)聽的文件描述符,不管他們是不是活躍的薄榛。有最大數(shù)量限制(32位系統(tǒng)1024,64位系統(tǒng)2048)

    • poll:同select敞恋,不過數(shù)據(jù)結(jié)構(gòu)不同,需要分配一個pollfd結(jié)構(gòu)數(shù)組耳舅,維護(hù)在內(nèi)核中碌上。它沒有大小限制,不過需要很多復(fù)制操作

    • epoll:用于代替poll和select浦徊,沒有大小限制馏予。使用一個文件描述符管理多個文件描述符,使用紅黑樹存儲盔性。同時用事件驅(qū)動代替了輪詢霞丧。epoll_ctl中注冊的文件描述符在事件觸發(fā)的時候會通過回調(diào)機(jī)制激活該文件描述符。epoll_wait便會收到通知冕香。最后蛹尝,epoll還采用了mmap虛擬內(nèi)存映射技術(shù)減少用戶態(tài)和內(nèi)核態(tài)數(shù)據(jù)傳輸?shù)拈_銷

  1. 信號驅(qū)動式IO
  • 使用信號后豫,內(nèi)核在數(shù)據(jù)準(zhǔn)備就緒時通過信號來進(jìn)行通知

  • 首先開啟信號驅(qū)動io套接字,并使用sigaction系統(tǒng)調(diào)用來安裝信號處理程序突那,內(nèi)核直接返回挫酿,不會阻塞用戶態(tài)

  • 數(shù)據(jù)準(zhǔn)備好時,內(nèi)核會發(fā)送SIGIO信號愕难,收到信號后開始進(jìn)行io操作

  1. 異步IO
  • 異步IO依賴信號處理程序來進(jìn)行通知

  • 不過異步IO與前面IO模型不同的是:前面的都是數(shù)據(jù)準(zhǔn)備階段的阻塞與非阻塞早龟,異步IO模型通知的是IO操作已經(jīng)完成,而不是數(shù)據(jù)準(zhǔn)備完成

  • 異步IO才是真正的非阻塞猫缭,主進(jìn)程只負(fù)責(zé)做自己的事情葱弟,等IO操作完成(數(shù)據(jù)成功從內(nèi)核緩存區(qū)復(fù)制到應(yīng)用程序緩沖區(qū))時通過回調(diào)函數(shù)對數(shù)據(jù)進(jìn)行處理

  • unix中異步io函數(shù)以aio_或 lio打頭

各種IO模型對比

  • 前面四種IO模型的主要區(qū)別在第一階段,他們第二階段是一樣的:數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到調(diào)用者緩沖區(qū)期間都被阻塞撞碌ぁ芝加!

  • 前面四種IO都是同步IO:IO操作導(dǎo)致請求進(jìn)程阻塞,直到IO操作完成

  • 異步IO:IO操作不導(dǎo)致請求進(jìn)程阻塞

select射窒、poll藏杖、epoll的區(qū)別?
  1. 支持一個線程所能打開的最大連接數(shù)

    image
  2. FD劇增后帶來的IO效率問題

    image.png
  1. 消息傳遞方式

    image

綜上脉顿,在選擇select制市,poll,epoll時要根據(jù)具體的使用場合以及這三種方式的自身特點:

  1. 表面上看epoll的性能最好弊予,但是在連接數(shù)少并且連接都十分活躍的情況下祥楣,select和poll的性能可能比epoll好,畢竟epoll的通知機(jī)制需要很多函數(shù)回調(diào)汉柒。

  2. select低效是因為每次它都需要輪詢误褪。但低效也是相對的兽间,視情況而定,也可通過良好的設(shè)計改善嘀略。

redis熱key問題帜羊?如何發(fā)現(xiàn)以及如何解決讼育?

熱點問題概述

熱點問題一般出現(xiàn)在讀多寫少的場景

在日常工作生活中一些突發(fā)的的事件奶段,諸如:“雙11”期間某些熱門商品的降價促銷痹籍,當(dāng)這其中的某一件商品被數(shù)萬次點擊、購買時刺洒,會形成一個較大的需求量,這種情況下就會產(chǎn)生一個單一的Key渔肩,這樣就會引起一個熱點拇惋;同理,當(dāng)被大量刊發(fā)蓉坎、瀏覽的熱點新聞蛉艾,熱點評論等也會產(chǎn)生熱點衷敌;另外缴罗,在服務(wù)端讀數(shù)據(jù)進(jìn)行訪問時面氓,往往會對數(shù)據(jù)進(jìn)行分片切分,此類過程中會在某一主機(jī)Server上對相應(yīng)的Key進(jìn)行訪問掘譬,當(dāng)訪問超過主機(jī)Server極限時屁药,就會導(dǎo)致熱點Key問題的產(chǎn)生酿箭。

當(dāng)某一熱點的Key在某一主機(jī)上超過該主機(jī)網(wǎng)卡上線時,由于流量的過度集中缔御,會導(dǎo)致服務(wù)器中其它服務(wù)無法進(jìn)行耕突。

此外评架,熱點Key的緩存過多纵诞,超過目前的緩存容量時浙芙,就會導(dǎo)致緩存分片服務(wù)被打垮現(xiàn)象的產(chǎn)生嗡呼。當(dāng)緩存服務(wù)崩潰后,此時再有請求產(chǎn)生揍很,會緩存到后臺DB上女轿,由于其本身性能較弱壕翩,在面臨大請求時很容易發(fā)生請求穿透現(xiàn)象放妈,會進(jìn)一步導(dǎo)致“雪崩”現(xiàn)象芜抒,嚴(yán)重影響設(shè)備的性能宅倒。

如何發(fā)現(xiàn)

對于db上熱點數(shù)據(jù)的發(fā)現(xiàn),首先會在一個周期內(nèi)對Key進(jìn)行請求統(tǒng)計疗绣,在達(dá)到請求量級后會對熱點Key進(jìn)行熱點定位多矮,并將所有的熱點Key放入一個小的LRU鏈表內(nèi)哈打,在通過Proxy請求進(jìn)行訪問時料仗,若Redis發(fā)現(xiàn)待訪點是一個熱點,就會進(jìn)入一個反饋階段格粪,同時對該數(shù)據(jù)進(jìn)行標(biāo)記肺孵。

如何解決

首先Client會將請求發(fā)送至Server上平窘,而Server又是一個多線程的服務(wù)瑰艘,本地就具有一個小的緩存空間紫新。當(dāng)Server本身就擁堵時芒率,Server不會將請求進(jìn)一步發(fā)送給DB而是直接返回偶芍,只有當(dāng)Server本身暢通時才會將Client請求發(fā)送至DB匪蟀,并且將該數(shù)據(jù)重新寫入到Cache中材彪。

https://blog.csdn.net/qq_35956041/article/details/81195826

redis數(shù)據(jù)分布方式段化?有什么優(yōu)點惩坑?一致性hash呢柑船?
分布方式:
  • 節(jié)點取余

    客戶端分片:哈希+取余

    節(jié)點伸縮:數(shù)據(jù)節(jié)點關(guān)系變化,導(dǎo)致數(shù)據(jù)遷移

    遷移數(shù)量和添加節(jié)點數(shù)量有關(guān):建議翻倍擴(kuò)容

  • 一致性哈希

    客戶端分片:哈希+順時針(優(yōu)化取余)

    節(jié)點伸縮:只影響鄰近節(jié)點仔沿,但是還是有數(shù)據(jù)遷移

    翻倍伸縮:保證最小遷移數(shù)據(jù)和負(fù)載均衡

  • 虛擬槽分區(qū)

    預(yù)設(shè)虛擬槽:每個槽映射一個數(shù)據(jù)子集封锉,一般比節(jié)點數(shù)大

    良好的哈希函數(shù):例如CRC16

    服務(wù)端管理節(jié)點成福、槽奴艾、數(shù)據(jù):例如Redis Cluster

redis主從復(fù)制蕴潦,主從切換俘闯,集群
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市此疹,隨后出現(xiàn)的幾起案子秀菱,更是在濱河造成了極大的恐慌衍菱,老刑警劉巖脊串,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琼锋,死亡現(xiàn)場離奇詭異放闺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)缕坎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門怖侦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谜叹,你說我怎么就攤上這事匾寝。” “怎么了荷腊?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵艳悔,是天一觀的道長。 經(jīng)常有香客問我女仰,道長,這世上最難降的妖魔是什么杨幼? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘邪码。我一直安慰自己影钉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布昂勉。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪志膀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天惊奇,我揣著相機(jī)與錄音,去河邊找鬼舟奠。 笑死咙俩,一個胖子當(dāng)著我的面吹牛脖阵,可吹牛的內(nèi)容都是我干的悍募。 我是一名探鬼主播喜鼓,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼启搂,長吁一口氣:“原來是場噩夢啊……” “哼牢撼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起曲横,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤孽椰,失蹤者是張志新(化名)和其女友劉穎迈嘹,沒想到半個月后壶笼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炮障,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡胁赢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年送漠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筷厘,靈堂內(nèi)的尸體忽然破棺而出鸣峭,到底是詐尸還是另有隱情,我是刑警寧澤酥艳,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布摊溶,位于F島的核電站,受9級特大地震影響玖雁,放射性物質(zhì)發(fā)生泄漏更扁。R本人自食惡果不足惜盖腕,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一赫冬、第九天 我趴在偏房一處隱蔽的房頂上張望浓镜。 院中可真熱鬧,春花似錦劲厌、人聲如沸膛薛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哄啄。三九已至,卻和暖如春风范,著一層夾襖步出監(jiān)牢的瞬間咨跌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工硼婿, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留锌半,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓寇漫,卻偏偏與公主長得像刊殉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子州胳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355