Redis 介紹
Redis是一個開源的使用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 類型是二進制安全的。Redis的string可以包含任何數(shù)據(jù),比如jpg圖片或者序列化的對象。
String 類型是redis最基本的數(shù)據(jù)類型,一個鍵最大能存儲512MB。 - Hash(哈希)
格式:hmset name key1 value1 key2 value2
Redis hash是一個鍵值(key=>value)對集合,
Redis hash是一個string類型的field和value的映射表,hash特別適合用于存儲對象。 - List(列表)
- Redis列表是簡單的字符串列表,按照插入插入順序排序??梢蕴砑右粋€元素到列表的頭部或者尾部。
格式:lpush name value
在key對應(yīng)list的頭部添加元素
格式:rpush name value
在key對應(yīng)list的尾部添加元素
格式:lrem name index
Key 對應(yīng)list中刪除count個和value相同的元素
格式:llen name
返回key對應(yīng)的list長度 - Set(集合)
格式:sadd name value
Redis的set是string類型的無序集合。
集合是通過哈希表實現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是0。 - Zset(sorted set:有序集合)
格式:zadd name score value
Redis zset和set一樣也是string類型元素的集合,且不允許重復(fù)的成員。
不同的是每個元素都會關(guān)聯(lián)一個 double類型的分數(shù)。Redis正是通過分數(shù)來為集合中的成員進行從小到大排序的。
Zset 的成員是唯一的,但分數(shù)(score)卻可以重復(fù)。
什么是redis持久化?Redis有那幾種持久化方式,優(yōu)缺點。持久化是把內(nèi)存中的數(shù)據(jù)寫到磁盤中去,防止服務(wù)器宕機內(nèi)存中的數(shù)據(jù)丟失。
Redis提供了兩種持久化的方式:RDB(默認)和AOF
-
Rdb
Rdb是redis DataBase縮寫功能核心函數(shù)rdbSave(生成rdb文件)和rdbLoad(從文件加載內(nèi)存)兩個函數(shù)。
圖片1.png
-
AOF
Aof是append-only file縮寫
每當執(zhí)行服務(wù)器(定時)任務(wù)或者函數(shù)flushAppendOnlyFile函數(shù)都會被調(diào)用,這個函數(shù)執(zhí)行以下兩個工作。
圖片2.png
Aof寫入保存:
WRITE:根據(jù)條件,將aof_buf中的緩存寫入到AOF文件
SAVE:根據(jù)條件,調(diào)用fsync或fdatasync函數(shù),將AOF文件保存到磁盤。
存儲結(jié)構(gòu):內(nèi)容是redis通訊協(xié)議(RESP)格式的命令文本存儲。
RESP是redis客戶端和服務(wù)端之間使用的一種通訊協(xié)議;
RESP的特點:實現(xiàn)簡單、快速解析、可讀性好
- Rdb與Aof對比
1、aof文件比rdb更新頻率高,優(yōu)先使用aof還原數(shù)據(jù)。
2、Aof比rdb更安全也更大
3、Rdb性能比aof好
4、如果兩個都配置了優(yōu)先加載aof
redis架構(gòu)模式,各自的特點
-
單機版
圖片3.png
特點:簡單
問題:1、內(nèi)存容量有限2、處理能力有限3、無法高可用
-
主從復(fù)制
圖片4.png
Redis的復(fù)制(replicstion)功能允許用戶根據(jù)一個Redis服務(wù)器來創(chuàng)建任意多個該服務(wù)的復(fù)制品,其中被復(fù)制的服務(wù)器為主服務(wù)器(master),而通過復(fù)制創(chuàng)建出來的服務(wù)器復(fù)制品則為從服務(wù)器(slave)。只要主從服務(wù)器之間的網(wǎng)絡(luò)連接正常,主從服務(wù)器兩者會具有相同數(shù)據(jù),主服務(wù)器就會一直將發(fā)生在自己身上的數(shù)據(jù)更新同步給從服務(wù)器,從而一直保證主從服務(wù)器的數(shù)據(jù)相同。
特點:
1、master/slave角色
2、Master/slave數(shù)據(jù)相同
3、降低master讀壓力在轉(zhuǎn)交從庫
問題:
無法保證高可用,沒有解決master寫的壓力
-
哨兵
圖片5.png
Redis sentinel是一個分布式系統(tǒng)中監(jiān)控redis主從服務(wù)器,并在主服務(wù)器下線時自動進行故障轉(zhuǎn)移。其中三個特性:
監(jiān)控(Monitoring):Sentinel會不斷地檢查你的主服務(wù)器和從服務(wù)器是否運作正常。
提醒(Notification):當被監(jiān)控的某個redis服務(wù)器出現(xiàn)問題是,Sentinel可以通過API向管理員或者其他應(yīng)用程序發(fā)送通知。
自動故障遷移(Automatic failover):當一個主服務(wù)器不能正常工作時,Sentinel會開始一次自動故障遷移操作。
特點:
1、保證高可用
2、監(jiān)控各個節(jié)點
3、自動故障遷移
確定:主從模式,切換需要時間丟數(shù)據(jù),沒辦法解決master寫的壓力
-
集群(proxy型)
圖片6.png
Twemproxy是一個Twitter開源的一個redis和memcache快速/輕量級代理服務(wù)器;Twemproxy是一個快速的單線程代理程序,支持Memcached ASCII協(xié)議和redis協(xié)議。
特點:
1、多種hash算法:MD5、CRC16、CRC32、CRC32a、hsish、murmur、jenkins
2、支持失敗節(jié)點自動刪除
3、后端Sharding分片邏輯對業(yè)務(wù)透明,業(yè)務(wù)方的讀寫方式和操作單個Redis一致。
缺點:添加了新的proxy,需要維護其高可用。
Failover邏輯需要自己實現(xiàn),其本身不能支持故障的自動轉(zhuǎn)移可擴展性差,進行擴縮容都需要手動干預(yù)
-
集群(直連型)
圖片7.png
從redis 3.0之后版本支持redis-cluster采用務(wù)中心結(jié)構(gòu),每個節(jié)點保存數(shù)據(jù)和整個集群狀態(tài),每個節(jié)點都和其他所以節(jié)點連接。
特點:
1、無中心架構(gòu)(不存在哪個節(jié)點影響性能瓶頸),少了proxy層。
2、數(shù)據(jù)按照slot存儲分布式在多個節(jié)點,節(jié)點間數(shù)據(jù)共享,可動態(tài)調(diào)整數(shù)據(jù)分布。
3、可擴展性,可線性擴展到1000個節(jié)點,節(jié)點可動態(tài)添加或刪除。
4、高可用性,部分節(jié)點不可用時,集群仍可用。通過添加slave做備份數(shù)據(jù)副本。
5、實現(xiàn)故障自動failover,節(jié)點之間通過gossip協(xié)議交換狀態(tài)信息,用投票機制完成Slave到Master的角色提升。
缺點:
1、資源隔離型較差,容易出現(xiàn)相互影響的情況。
2、數(shù)據(jù)通過異步復(fù)制,不保證數(shù)據(jù)的一致性。
使用過Redis分布式鎖嗎,他是怎么實現(xiàn)的?
先拿setnx來爭搶鎖,搶到之后,再用expire給鎖加一個過期時間防止鎖忘記釋放。
如果在setnx之后執(zhí)行expire之前進程意外crash或者要重啟維護了該怎么辦?
Set指令有非常復(fù)雜的參數(shù),這個應(yīng)該是可以同事把setnx和expire合成一條指令來用的。
使用過redis做異步隊列嗎,你是怎么用的,有什么缺點?
一般使用list結(jié)構(gòu)作為隊列,rpush生產(chǎn)消息,lpop消費消息,當lpop沒有消息的時候,要適當sleep一會在重試。
缺點:
在消費者下線的情況下,生產(chǎn)的消息會丟失,得使用專業(yè)的消息隊列如rabbitmq等。
能不能生產(chǎn)一次消費多次呢?
使用pub/sub主題訂閱者模式,可以實現(xiàn)1:N的消息隊列。
什么是緩存穿透?如何避免?什么是緩存雪崩?如何避免?
緩存穿透:
一般的緩存系統(tǒng),都是按照key去緩存查詢,如果不存在對應(yīng)的value值,就應(yīng)該去后端系統(tǒng)查詢(比如DB)。一些惡意的請求會故意查詢不存在的key,請求量很大,就會對后臺系統(tǒng)造成很大的壓力。這就叫緩存穿透。
如何避免:
1、對查詢結(jié)果為空的情況下也進行緩存,緩存時間設(shè)置短一點,或者該key對應(yīng)的數(shù)insert了之后清理緩存。
2、對一定不存在的key值進行過濾??梢园阉械目赡艽嬖诘膋ey放到一個大的bitmap中,查詢是通過bitmap過濾。
緩存雪崩:
當緩存服務(wù)器重啟或者緩存集中在某一個時間段失效,這樣在失效的時候,會給后端系統(tǒng)帶來很大的壓力。導(dǎo)致系統(tǒng)崩潰。
如何避免:
1、在緩存失效后,通過加鎖或者隊列來控制讀數(shù)據(jù)庫寫緩存的線程數(shù)量。比如對某個key只允許一個線程查詢和寫緩存,其他線程等待。
2、做二級緩存,a1為原始緩存,a2為拷貝緩存,a1失效時,可以訪問a2,a1緩存時間設(shè)置短期,a2設(shè)置為長期。
3、不同的key,設(shè)置不同的過期時間,讓緩存失效的時間點盡量均勻。






