1.redis有哪些好處姑原?
NoSQL :not-only sql,泛指非關(guān)系型數(shù)據(jù)庫
1)性能高
Redis能支持超過 100K+ 每秒的讀寫頻率呜舒。
2)豐富的數(shù)據(jù)類型
支持字符串(strings)锭汛、散列(hashes)、列表(lists)袭蝗、集合(sets)唤殴、有序集合(sorted sets)等。
3)原子性
Redis的所有操作都是原子性的到腥,同時(shí)Redis還支持對(duì)幾個(gè)操作全并后的原子性執(zhí)行朵逝。
4)豐富的特性
- 支持?jǐn)?shù)據(jù)持久化。
可以將內(nèi)存中數(shù)據(jù)保存在磁盤中左电,重啟時(shí)加載廉侧。 - 主從復(fù)制,哨兵篓足,高可用段誊。
- 可以用作分布式鎖。
- 可以作為消息中間件使用栈拖,支持發(fā)布訂閱连舍。
2.redis是單線程還是多線程
答:單線程
為什么那么快?
(1) 絕大部分請(qǐng)求是純粹的內(nèi)存操作(非成矗快速)
(2)采用單線程,避免了不必要的上下文切換和競(jìng)爭(zhēng)條件
(3) 非阻塞IO - IO多路復(fù)用
底層原理:
3.list底層怎么實(shí)現(xiàn)
4持久化的方式
Redis 為了保證效率索赏,數(shù)據(jù)緩存在了內(nèi)存中,但是會(huì)周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件中贴彼,以保證數(shù)據(jù)的持久化潜腻。
RDB:快照形式是直接把內(nèi)存中的數(shù)據(jù)保存到一個(gè) dump 的文件中,定時(shí)保存器仗,保存策略融涣。
RDB原理:默認(rèn) Redis 是會(huì)以快照"RDB"的形式將數(shù)據(jù)持久化到磁盤的一個(gè)二進(jìn)制文件 dump.rdb。工作原理簡單說一下:當(dāng) Redis 需要做持久化時(shí)精钮,Redis 會(huì) fork 一個(gè)子進(jìn)程威鹿,子進(jìn)程將數(shù)據(jù)寫到磁盤上一個(gè)臨時(shí) RDB 文件中。當(dāng)子進(jìn)程完成寫臨時(shí)文件后轨香,將原來的 RDB 替換掉忽你,這樣的好處是可以 copy-on-write。
RDB 的優(yōu)點(diǎn)是:這種文件非常適合用于備份:比如臂容,你可以在最近的 24 小時(shí)內(nèi)科雳,每小時(shí)備份一次根蟹,并且在每個(gè)月的每一天也備份一個(gè) RDB 文件。這樣的話炸渡,即使遇上問題娜亿,也可以隨時(shí)將數(shù)據(jù)集還原到不同的版本。RDB 非常適合災(zāi)難恢復(fù)蚌堵。
RDB 的缺點(diǎn)是:如果你需要盡量避免在服務(wù)器故障時(shí)丟失數(shù)據(jù),那么RDB不合適你沛婴。AOF:把所有的對(duì) Redis 的服務(wù)器進(jìn)行修改的命令都存到一個(gè)文件里吼畏,命令的集合。Redis 默認(rèn)是快照 RDB 的持久化方式嘁灯。
當(dāng) Redis 重啟的時(shí)候泻蚊,它會(huì)優(yōu)先使用 AOF 文件來還原數(shù)據(jù)集,因?yàn)?AOF 文件保存的數(shù)據(jù)集通常比 RDB 文件所保存的數(shù)據(jù)集更完整丑婿。你甚至可以關(guān)閉持久化功能性雄,讓數(shù)據(jù)只在服務(wù)器運(yùn)行時(shí)存。AOF原理:使用 AOF 做持久化羹奉,每一個(gè)寫命令都通過 write 函數(shù)追加到 appendonly.aof 中秒旋,配置方式如下:
appendfsync yes
appendfsync always #每次有數(shù)據(jù)修改發(fā)生時(shí)都會(huì)寫入AOF文件。
appendfsync everysec #每秒鐘同步一次诀拭,該策略為AOF的缺省策略迁筛。
AOF 可以做到全程持久化,只需要在配置中開啟 appendonly yes耕挨。這樣 Redis 每執(zhí)行一個(gè)修改數(shù)據(jù)的命令细卧,都會(huì)把它添加到 AOF 文件中,當(dāng) Redis 重啟時(shí)筒占,將會(huì)讀取 AOF 文件進(jìn)行重放贪庙,恢復(fù)到 Redis 關(guān)閉前的最后時(shí)刻。
使用 AOF 的優(yōu)點(diǎn)是會(huì)讓 Redis 變得非常耐久翰苫≈褂剩可以設(shè)置不同的 Fsync 策略,AOF的默認(rèn)策略是每秒鐘 Fsync 一次革骨,在這種配置下农尖,就算發(fā)生故障停機(jī),也最多丟失一秒鐘的數(shù)據(jù)良哲。
缺點(diǎn)是對(duì)于相同的數(shù)據(jù)集來說盛卡,AOF 的文件體積通常要大于 RDB 文件的體積。根據(jù)所使用的 Fsync 策略筑凫,AOF 的速度可能會(huì)慢于 RDB滑沧。
-
總結(jié):
如果你非常關(guān)心你的數(shù)據(jù)并村,但仍然可以承受數(shù)分鐘內(nèi)的數(shù)據(jù)丟失,那么可以額只使用 RDB 持久滓技。
AOF 將 Redis 執(zhí)行的每一條命令追加到磁盤中哩牍,處理巨大的寫入會(huì)降低Redis的性能,不知道你是否可以接受令漂。
數(shù)據(jù)庫備份和災(zāi)難恢復(fù):定時(shí)生成 RDB 快照非常便于進(jìn)行數(shù)據(jù)庫備份膝昆,并且 RDB 恢復(fù)數(shù)據(jù)集的速度也要比 AOF 恢復(fù)的速度快。
當(dāng)然了叠必,Redis 支持同時(shí)開啟 RDB 和 AOF荚孵,系統(tǒng)重啟后,Redis 會(huì)優(yōu)先使用 AOF 來恢復(fù)數(shù)據(jù)纬朝,這樣丟失的數(shù)據(jù)會(huì)最少收叶。
5.key的過期策略
6緩存穿透和緩存雪崩及解決辦法
-
緩存雪崩:如果首頁所有 Key 的失效時(shí)間都是 12 小時(shí),中午 12 點(diǎn)刷新的共苛,我零點(diǎn)有個(gè)大促活動(dòng)大量用戶涌入判没,假設(shè)每秒 6000 個(gè)請(qǐng)求,本來緩存可以抗住每秒 5000 個(gè)請(qǐng)求隅茎,但是緩存中所有 Key 都失效了澄峰。
此時(shí) 6000 個(gè)/秒的請(qǐng)求全部落在了數(shù)據(jù)庫上,數(shù)據(jù)庫必然扛不住患膛,真實(shí)情況可能 DBA 都沒反應(yīng)過來直接掛了摊阀。 -
雪崩解決辦法:處理緩存雪崩簡單,在批量往 Redis 存數(shù)據(jù)的時(shí)候踪蹬,把每個(gè) Key 的失效時(shí)間都加個(gè)隨機(jī)值就好了胞此,這樣可以保證數(shù)據(jù)不會(huì)再同一時(shí)間大面積失效。
setRedis(key, value, time+Math.random()*10000);
如果 Redis 是集群部署跃捣,將熱點(diǎn)數(shù)據(jù)均勻分布在不同的 Redis 庫中也能避免全部失效漱牵。或者設(shè)置熱點(diǎn)數(shù)據(jù)永不過期疚漆,有更新操作就更新緩存就好了(比如運(yùn)維更新了首頁商品酣胀,那你刷下緩存就好了,不要設(shè)置過期時(shí)間)娶聘,電商首頁的數(shù)據(jù)也可以用這個(gè)操作闻镶,保險(xiǎn)。 - 緩存擊穿和緩存穿透
1.擊穿:緩存擊穿丸升,這個(gè)跟緩存雪崩有點(diǎn)像铆农,但是又有一點(diǎn)不一樣,緩存雪崩是因?yàn)榇竺娣e的緩存失效,打崩了 DB羞迷。緩存擊穿不同的是緩存擊穿是指一個(gè) Key 非常熱點(diǎn),在不停地扛著大量的請(qǐng)求宰闰,大并發(fā)集中對(duì)這一個(gè)點(diǎn)進(jìn)行訪問岭皂,當(dāng)這個(gè) Key 在失效的瞬間郊霎,持續(xù)的大并發(fā)直接落到了數(shù)據(jù)庫上,就在這個(gè) Key 的點(diǎn)上擊穿了緩存爷绘。
2.穿透:緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù)书劝,而用戶(黑客)不斷發(fā)起請(qǐng)求。通過不符合條件的參數(shù)進(jìn)行參數(shù)攻擊揉阎,導(dǎo)致數(shù)據(jù)庫壓力過大庄撮,嚴(yán)重會(huì)擊垮數(shù)據(jù)庫。
7.五種基本數(shù)據(jù)類型詳細(xì)介紹
-
String 是 Redis 最基本的類型毙籽,可以理解成與 Memcached一模一樣的類型,一個(gè) Key 對(duì)應(yīng)一個(gè) Value毡庆。Value 不僅是 String坑赡,也可以是數(shù)字。
String 類型是二進(jìn)制安全的么抗,意思是 Redis 的 String 類型可以包含任何數(shù)據(jù)毅否,比如 jpg 圖片或者序列化的對(duì)象。String 類型的值最大能存儲(chǔ) 512M蝇刀。 - Hash是一個(gè)鍵值(key-value)的集合螟加。Redis 的 Hash 是一個(gè) String 的 Key 和 Value 的映射表,Hash 特別適合存儲(chǔ)對(duì)象吞琐。常用命令:hget捆探,hset,hgetall 等站粟。
- List 列表是簡單的字符串列表黍图,按照插入順序排序∨樱可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊) 常用命令:lpush助被、rpush、lpop切诀、rpop揩环、lrange(獲取列表片段)等。
- List 列表是簡單的字符串列表幅虑,按照插入順序排序丰滑。可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊) 常用命令:lpush翘单、rpush吨枉、lpop蹦渣、rpop、lrange(獲取列表片段)等貌亭。
-
Set 是 String 類型的無序集合柬唯。集合是通過 hashtable 實(shí)現(xiàn)的。Set 中的元素是沒有順序的圃庭,而且是沒有重復(fù)的锄奢。常用命令:sdd、spop剧腻、smembers拘央、sunion 等。
應(yīng)用場(chǎng)景:Redis Set 對(duì)外提供的功能和 List 一樣是一個(gè)列表书在,特殊之處在于 Set 是自動(dòng)去重的灰伟,而且 Set 提供了判斷某個(gè)成員是否在一個(gè) Set 集合中。 -
Zset 和 Set 一樣是 String 類型元素的集合儒旬,且不允許重復(fù)的元素栏账。常用命令:zadd、zrange栈源、zrem挡爵、zcard 等。
使用場(chǎng)景:Sorted Set 可以通過用戶額外提供一個(gè)優(yōu)先級(jí)(score)的參數(shù)來為成員排序甚垦,并且是插入有序的茶鹃,即自動(dòng)排序。
當(dāng)你需要一個(gè)有序的并且不重復(fù)的集合列表艰亮,那么可以選擇 Sorted Set 結(jié)構(gòu)闭翩。 -
Set 和ZSet 的對(duì)比
和 Set 相比,Sorted Set關(guān)聯(lián)了一個(gè) Double 類型權(quán)重的參數(shù) Score垃杖,使得集合中的元素能夠按照 Score 進(jìn)行有序排列男杈,Redis 正是通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大的排序。
實(shí)現(xiàn)方式:Redis Sorted Set 的內(nèi)部使用 HashMap 和跳躍表(skipList)來保證數(shù)據(jù)的存儲(chǔ)和有序调俘,HashMap 里放的是成員到 Score 的映射伶棒。
而跳躍表里存放的是所有的成員,排序依據(jù)是 HashMap 里存的 Score彩库,使用跳躍表的結(jié)構(gòu)可以獲得比較高的查找效率肤无,并且在實(shí)現(xiàn)上比較簡單。
8.Redis 和 Memcached 的區(qū)別
- 存儲(chǔ)方式上:Memcache 會(huì)把數(shù)據(jù)全部存在內(nèi)存之中骇钦,斷電后會(huì)掛掉宛渐,數(shù)據(jù)不能超過內(nèi)存大小。Redis 有部分?jǐn)?shù)據(jù)存在硬盤上,這樣能保證數(shù)據(jù)的持久性窥翩。
- 數(shù)據(jù)支持類型上:Memcache 對(duì)數(shù)據(jù)類型的支持簡單业岁,只支持簡單的 key-value,寇蚊,而 Redis 支持五種數(shù)據(jù)類型笔时。
- 使用底層模型不同:它們之間底層實(shí)現(xiàn)方式以及與客戶端之間通信的應(yīng)用協(xié)議不一樣。Redis 直接自己構(gòu)建了 VM 機(jī)制仗岸,因?yàn)橐话愕南到y(tǒng)調(diào)用系統(tǒng)函數(shù)的話允耿,會(huì)浪費(fèi)一定的時(shí)間去移動(dòng)和請(qǐng)求。
- Value 的大邪遣馈:Redis 可以達(dá)到 1GB较锡,而 Memcache 只有 1MB。