Redis 介紹
Redis是一個(gè)開源的使用ANSI C語言編寫、遵循BSD協(xié)議、支持網(wǎng)絡(luò)襟铭、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫锣笨,并提供多種語言API的非關(guān)系型數(shù)據(jù)庫蝌矛。
Redis 支持的數(shù)據(jù)類型
- String (字符串)
格式:set key value
String 類型是二進(jìn)制安全的。Redis的string可以包含任何數(shù)據(jù)错英,比如jpg圖片或者序列化的對(duì)象入撒。
String 類型是redis最基本的數(shù)據(jù)類型,一個(gè)鍵最大能存儲(chǔ)512MB椭岩。 - Hash(哈希)
格式:hmset name key1 value1 key2 value2
Redis hash是一個(gè)鍵值(key=>value)對(duì)集合茅逮,
Redis hash是一個(gè)string類型的field和value的映射表,hash特別適合用于存儲(chǔ)對(duì)象判哥。 - List(列表)
- Redis列表是簡(jiǎn)單的字符串列表献雅,按照插入插入順序排序∷疲可以添加一個(gè)元素到列表的頭部或者尾部挺身。
格式:lpush name value
在key對(duì)應(yīng)list的頭部添加元素
格式:rpush name value
在key對(duì)應(yīng)list的尾部添加元素
格式:lrem name index
Key 對(duì)應(yīng)list中刪除count個(gè)和value相同的元素
格式:llen name
返回key對(duì)應(yīng)的list長度 - Set(集合)
格式:sadd name value
Redis的set是string類型的無序集合。
集合是通過哈希表實(shí)現(xiàn)的锌仅,所以添加章钾,刪除,查找的復(fù)雜度都是0热芹。 - Zset(sorted set:有序集合)
格式:zadd name score value
Redis zset和set一樣也是string類型元素的集合贱傀,且不允許重復(fù)的成員。
不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè) double類型的分?jǐn)?shù)伊脓。Redis正是通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大排序的府寒。
Zset 的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)报腔。
什么是redis持久化?Redis有那幾種持久化方式株搔,優(yōu)缺點(diǎn)。持久化是把內(nèi)存中的數(shù)據(jù)寫到磁盤中去纯蛾,防止服務(wù)器宕機(jī)內(nèi)存中的數(shù)據(jù)丟失邪狞。
Redis提供了兩種持久化的方式:RDB(默認(rèn))和AOF
-
Rdb
Rdb是redis DataBase縮寫功能核心函數(shù)rdbSave(生成rdb文件)和rdbLoad(從文件加載內(nèi)存)兩個(gè)函數(shù)。
-
AOF
Aof是append-only file縮寫
每當(dāng)執(zhí)行服務(wù)器(定時(shí))任務(wù)或者函數(shù)flushAppendOnlyFile函數(shù)都會(huì)被調(diào)用茅撞,這個(gè)函數(shù)執(zhí)行以下兩個(gè)工作帆卓。
Aof寫入保存:
WRITE:根據(jù)條件巨朦,將aof_buf中的緩存寫入到AOF文件
SAVE:根據(jù)條件,調(diào)用fsync或fdatasync函數(shù)剑令,將AOF文件保存到磁盤糊啡。
存儲(chǔ)結(jié)構(gòu):內(nèi)容是redis通訊協(xié)議(RESP)格式的命令文本存儲(chǔ)。
RESP是redis客戶端和服務(wù)端之間使用的一種通訊協(xié)議吁津;
RESP的特點(diǎn):實(shí)現(xiàn)簡(jiǎn)單棚蓄、快速解析、可讀性好
- Rdb與Aof對(duì)比
1碍脏、aof文件比rdb更新頻率高梭依,優(yōu)先使用aof還原數(shù)據(jù)。
2典尾、Aof比rdb更安全也更大
3役拴、Rdb性能比aof好
4、如果兩個(gè)都配置了優(yōu)先加載aof
redis架構(gòu)模式钾埂,各自的特點(diǎn)
-
單機(jī)版
特點(diǎn):簡(jiǎn)單
問題:1河闰、內(nèi)存容量有限2、處理能力有限3褥紫、無法高可用
-
主從復(fù)制
Redis的復(fù)制(replicstion)功能允許用戶根據(jù)一個(gè)Redis服務(wù)器來創(chuàng)建任意多個(gè)該服務(wù)的復(fù)制品姜性,其中被復(fù)制的服務(wù)器為主服務(wù)器(master),而通過復(fù)制創(chuàng)建出來的服務(wù)器復(fù)制品則為從服務(wù)器(slave)髓考。只要主從服務(wù)器之間的網(wǎng)絡(luò)連接正常部念,主從服務(wù)器兩者會(huì)具有相同數(shù)據(jù),主服務(wù)器就會(huì)一直將發(fā)生在自己身上的數(shù)據(jù)更新同步給從服務(wù)器氨菇,從而一直保證主從服務(wù)器的數(shù)據(jù)相同儡炼。
特點(diǎn):
1、master/slave角色
2门驾、Master/slave數(shù)據(jù)相同
3、降低master讀壓力在轉(zhuǎn)交從庫
問題:
無法保證高可用多柑,沒有解決master寫的壓力
-
哨兵
Redis sentinel是一個(gè)分布式系統(tǒng)中監(jiān)控redis主從服務(wù)器奶是,并在主服務(wù)器下線時(shí)自動(dòng)進(jìn)行故障轉(zhuǎn)移。其中三個(gè)特性:
監(jiān)控(Monitoring):Sentinel會(huì)不斷地檢查你的主服務(wù)器和從服務(wù)器是否運(yùn)作正常竣灌。
提醒(Notification):當(dāng)被監(jiān)控的某個(gè)redis服務(wù)器出現(xiàn)問題是聂沙,Sentinel可以通過API向管理員或者其他應(yīng)用程序發(fā)送通知。
自動(dòng)故障遷移(Automatic failover):當(dāng)一個(gè)主服務(wù)器不能正常工作時(shí)初嘹,Sentinel會(huì)開始一次自動(dòng)故障遷移操作及汉。
特點(diǎn):
1、保證高可用
2屯烦、監(jiān)控各個(gè)節(jié)點(diǎn)
3坷随、自動(dòng)故障遷移
確定:主從模式房铭,切換需要時(shí)間丟數(shù)據(jù),沒辦法解決master寫的壓力
-
集群(proxy型)
Twemproxy是一個(gè)Twitter開源的一個(gè)redis和memcache快速/輕量級(jí)代理服務(wù)器温眉;Twemproxy是一個(gè)快速的單線程代理程序缸匪,支持Memcached ASCII協(xié)議和redis協(xié)議。
特點(diǎn):
1类溢、多種hash算法:MD5凌蔬、CRC16、CRC32闯冷、CRC32a砂心、hsish、murmur蛇耀、jenkins
2辩诞、支持失敗節(jié)點(diǎn)自動(dòng)刪除
3、后端Sharding分片邏輯對(duì)業(yè)務(wù)透明蒂窒,業(yè)務(wù)方的讀寫方式和操作單個(gè)Redis一致躁倒。
缺點(diǎn):添加了新的proxy,需要維護(hù)其高可用洒琢。
Failover邏輯需要自己實(shí)現(xiàn)秧秉,其本身不能支持故障的自動(dòng)轉(zhuǎn)移可擴(kuò)展性差,進(jìn)行擴(kuò)縮容都需要手動(dòng)干預(yù)
-
集群(直連型)
從redis 3.0之后版本支持redis-cluster采用務(wù)中心結(jié)構(gòu)衰抑,每個(gè)節(jié)點(diǎn)保存數(shù)據(jù)和整個(gè)集群狀態(tài)象迎,每個(gè)節(jié)點(diǎn)都和其他所以節(jié)點(diǎn)連接。
特點(diǎn):
1呛踊、無中心架構(gòu)(不存在哪個(gè)節(jié)點(diǎn)影響性能瓶頸)砾淌,少了proxy層。
2谭网、數(shù)據(jù)按照slot存儲(chǔ)分布式在多個(gè)節(jié)點(diǎn)汪厨,節(jié)點(diǎn)間數(shù)據(jù)共享,可動(dòng)態(tài)調(diào)整數(shù)據(jù)分布愉择。
3劫乱、可擴(kuò)展性,可線性擴(kuò)展到1000個(gè)節(jié)點(diǎn)锥涕,節(jié)點(diǎn)可動(dòng)態(tài)添加或刪除衷戈。
4、高可用性层坠,部分節(jié)點(diǎn)不可用時(shí)殖妇,集群仍可用。通過添加slave做備份數(shù)據(jù)副本破花。
5谦趣、實(shí)現(xiàn)故障自動(dòng)failover疲吸,節(jié)點(diǎn)之間通過gossip協(xié)議交換狀態(tài)信息,用投票機(jī)制完成Slave到Master的角色提升蔚润。
缺點(diǎn):
1磅氨、資源隔離型較差,容易出現(xiàn)相互影響的情況嫡纠。
2烦租、數(shù)據(jù)通過異步復(fù)制,不保證數(shù)據(jù)的一致性除盏。
使用過Redis分布式鎖嗎叉橱,他是怎么實(shí)現(xiàn)的?
先拿setnx來爭(zhēng)搶鎖者蠕,搶到之后窃祝,再用expire給鎖加一個(gè)過期時(shí)間防止鎖忘記釋放。
如果在setnx之后執(zhí)行expire之前進(jìn)程意外crash或者要重啟維護(hù)了該怎么辦踱侣?
Set指令有非常復(fù)雜的參數(shù)粪小,這個(gè)應(yīng)該是可以同事把setnx和expire合成一條指令來用的。
使用過redis做異步隊(duì)列嗎抡句,你是怎么用的探膊,有什么缺點(diǎn)?
一般使用list結(jié)構(gòu)作為隊(duì)列待榔,rpush生產(chǎn)消息逞壁,lpop消費(fèi)消息,當(dāng)lpop沒有消息的時(shí)候锐锣,要適當(dāng)sleep一會(huì)在重試腌闯。
缺點(diǎn):
在消費(fèi)者下線的情況下,生產(chǎn)的消息會(huì)丟失雕憔,得使用專業(yè)的消息隊(duì)列如rabbitmq等姿骏。
能不能生產(chǎn)一次消費(fèi)多次呢?
使用pub/sub主題訂閱者模式斤彼,可以實(shí)現(xiàn)1:N的消息隊(duì)列分瘦。
什么是緩存穿透?如何避免畅卓?什么是緩存雪崩擅腰?如何避免蟋恬?
緩存穿透:
一般的緩存系統(tǒng)翁潘,都是按照key去緩存查詢,如果不存在對(duì)應(yīng)的value值歼争,就應(yīng)該去后端系統(tǒng)查詢(比如DB)拜马。一些惡意的請(qǐng)求會(huì)故意查詢不存在的key渗勘,請(qǐng)求量很大,就會(huì)對(duì)后臺(tái)系統(tǒng)造成很大的壓力俩莽。這就叫緩存穿透旺坠。
如何避免:
1、對(duì)查詢結(jié)果為空的情況下也進(jìn)行緩存扮超,緩存時(shí)間設(shè)置短一點(diǎn)取刃,或者該key對(duì)應(yīng)的數(shù)insert了之后清理緩存。
2出刷、對(duì)一定不存在的key值進(jìn)行過濾璧疗。可以把所有的可能存在的key放到一個(gè)大的bitmap中馁龟,查詢是通過bitmap過濾崩侠。
緩存雪崩:
當(dāng)緩存服務(wù)器重啟或者緩存集中在某一個(gè)時(shí)間段失效,這樣在失效的時(shí)候坷檩,會(huì)給后端系統(tǒng)帶來很大的壓力却音。導(dǎo)致系統(tǒng)崩潰。
如何避免:
1矢炼、在緩存失效后系瓢,通過加鎖或者隊(duì)列來控制讀數(shù)據(jù)庫寫緩存的線程數(shù)量。比如對(duì)某個(gè)key只允許一個(gè)線程查詢和寫緩存裸删,其他線程等待八拱。
2、做二級(jí)緩存涯塔,a1為原始緩存肌稻,a2為拷貝緩存,a1失效時(shí)匕荸,可以訪問a2爹谭,a1緩存時(shí)間設(shè)置短期,a2設(shè)置為長期榛搔。
3诺凡、不同的key,設(shè)置不同的過期時(shí)間践惑,讓緩存失效的時(shí)間點(diǎn)盡量均勻腹泌。