Redis相關

1、Redis的數(shù)據(jù)類型
  • String:
    格式:set key value
    string是二進制安全的,可包含任何數(shù)據(jù),如jpg或序列化的對象 。string是Redis最基本的數(shù)據(jù)類型,一個鍵最大能存儲512MB。
  • List:
    list是簡單的字符串列表,按插入順序排序??梢蕴砑右粋€元素到list的頭部(左邊)或尾部(右邊)。
    格式:lpush name value //在key對應list的頭部添加字符串元素
    格式: rpush name value //在key對應list的尾部添加字符串元素
    格式: lrem name count //刪除key對應list中count個和value相同的元素
    格式: llen name //返回key對應list的長度
  • Hash:
    格式: hmset name key1 value1 key2 value2
    hash是一個鍵值(key=>value)對集合,是一個string類型的key和value的映射表,適合用于存儲對象。
  • Set:
    格式: sadd name value
    Set是string類型的無序集合,通過哈希表實現(xiàn),添加、刪除、查找的復雜度都是O(1)。
  • zset
    格式: zadd name score value
    zset也是string類型元素的集合,不允許重復的成員。每個元素都會關聯(lián)一個double類型的分數(shù)(score,分數(shù)可重復),通過分數(shù)為集合中的成員進行從小到大的排序。
2、Redis持久化方式及優(yōu)缺點?

持久化就是把內(nèi)存的數(shù)據(jù)寫到磁盤中去,防止服務宕機時內(nèi)存數(shù)據(jù)丟失。
Redis的持久化方式:RDB(默認) 和AOF。
RDB(Redis DataBase):包含rdbSave(把內(nèi)存中的數(shù)據(jù)生成RDB文件)和rdbLoad(把RDB文件加載到內(nèi)存)兩個函數(shù)。
AOF(Append-only file):當執(zhí)行服務器(定時)任務或函數(shù)時flushAppendOnlyFile函數(shù)都會被調(diào)用,函數(shù)執(zhí)行以下兩個工作aof寫入保存:
WRITE:根據(jù)條件將aof_buf中的緩存寫入到AOF文件。
SAVE:根據(jù)條件調(diào)用fsync或fdatasync函數(shù),將AOF文件保存到磁盤。
兩種方式對比:
1)aof比rdb更新頻率高,優(yōu)先使用aof還原數(shù)據(jù)。
2)aof比rdb更大更安全
3)rdb性能更好
4)若兩個都配了優(yōu)先加載aof

3、什么是RESP?有什么特點?

RESP是redis客戶端和服務端使用的一種通訊協(xié)議;
特點:實現(xiàn)簡單、快速解析、可讀性好;

4、什么是一致性哈希算法?

一致性哈希將整個哈希值空間組織成一個虛擬的圓環(huán),如假設某哈希函數(shù)H的值空間為0-232-1(即哈希值是一個32位無符號整形),整個空間按順時針方向組織。0和232-1在零點中方向重合。
下一步將各個服務器使用Hash進行一個哈希,具體可以選擇服務器的ip或主機名作為關鍵字進行哈希,這樣每臺機器就能確定其在哈希環(huán)上的位置,這里假設將上文中四臺服務器使用ip地址哈希后在環(huán)空間的位置如下:

image.png

接下來使用如下算法定位數(shù)據(jù)訪問到相應服務器:將數(shù)據(jù)key使用相同的函數(shù)Hash計算出哈希值,并確定此數(shù)據(jù)在環(huán)上的位置,從此位置沿環(huán)順時針“行走”,第一臺遇到的服務器就是其應該定位到的服務器。例如有Object A、Object B、Object C、Object D四個數(shù)據(jù)對象,經(jīng)過哈希計算后,在環(huán)空間上的位置如下:
image

根據(jù)一致性哈希算法,數(shù)據(jù)A會被定為到Node A上,B被定為到Node B上,C被定為到Node C上,D被定為到Node D上。
一致性哈希算法的容錯性和可擴展性:假設Node C宕機,此時對象A、B、D不會受到影響,只有C對象被重定位到Node D。一般在一致性哈希算法中,如果一臺服務器不可用,則受影響的數(shù)據(jù)僅僅是此服務器到其環(huán)空間中前一臺服務器(即沿著逆時針方向行走遇到的第一臺服務器)之間數(shù)據(jù),其它不會受到影響。
如果在系統(tǒng)中增加一臺服務器Node X,如下圖:
image

此時對象A、B、D不受影響,只有對象C需要重定位到新的Node X 。在一致性哈希算法中,如果增加一臺服務器,則受影響的數(shù)據(jù)僅僅是新服務器到其環(huán)空間中前一臺服務器(即沿著逆時針方向行走遇到的第一臺服務器)之間數(shù)據(jù),其它數(shù)據(jù)也不會受到影響。
綜上所述:一致性哈希算法對于節(jié)點的增減都只需重定位環(huán)空間中的一小部分數(shù)據(jù),具有較好的容錯性和可擴展性。另外,一致性哈希算法在服務節(jié)點太少時,容易因為節(jié)點分部不均勻而造成數(shù)據(jù)傾斜問題。例如系統(tǒng)中只有兩臺服務器,其環(huán)分布如下,
image

此時必然造成大量數(shù)據(jù)集中到Node A上,而只有極少量會定位到Node B上。為了解決這種數(shù)據(jù)傾斜問題,一致性哈希算法引入了虛擬節(jié)點機制,即對每一個服務節(jié)點計算多個哈希,每個計算結(jié)果位置都放置一個此服務節(jié)點,稱為虛擬節(jié)點。具體做法可以在服務器ip或主機名的后面增加編號來實現(xiàn)。如上面的情況,可以為每臺服務器計算三個虛擬節(jié)點,于是可以分別計算 “Node A#1”、“Node A#2”、“Node A#3”、“Node B#1”、“Node B#2”、“Node B#3”的哈希值,于是形成六個虛擬節(jié)點:
image

同時數(shù)據(jù)定位算法不變,只是多了一步虛擬節(jié)點到實際節(jié)點的映射,例如定位到“Node A#1”、“Node A#2”、“Node A#3”三個虛擬節(jié)點的數(shù)據(jù)均定位到Node A上。這樣就解決了服務節(jié)點少時數(shù)據(jù)傾斜的問題。在實際應用中,通常將虛擬節(jié)點數(shù)設置為32甚至更大,因此即使很少的服務節(jié)點也能做到相對均勻的數(shù)據(jù)分布。

5、什么是哈希槽?

redis3.0之后版本支持redis-cluster集群,Redis-Cluster采用無中心結(jié)構(gòu),每個節(jié)點保存數(shù)據(jù)和整個集群狀態(tài),每個節(jié)點都和其他所有節(jié)點連接。
結(jié)構(gòu)特點:
1)所有redis節(jié)點彼此互聯(lián)(PING-PONG機制),內(nèi)部使用二進制協(xié)議優(yōu)化傳輸速度和帶寬。
2)節(jié)點的fail是通過集群中超過半數(shù)的節(jié)點檢測失效時才生效。
3)客戶端與redis節(jié)點直連,不需要中間proxy層,客戶端不需要連接集群所有節(jié)點,連接集群中任何一個可用節(jié)點即可。
4)redis-cluster把所有的物理節(jié)點映射到[0-16383]slot上(不一定是平均分配),cluster負責維護node<->slot<->value。
5)Redis集群預分好16384個桶,當需要在Redis集群中放置一個key-value時,根據(jù)CRC16(key) mod 16384的值,決定將一個key放到哪個桶中。

6、Redis有哪些架構(gòu)模式?
  • 單機版
    特點:簡單
    問題:
    1)內(nèi)存容量有限
    2)處理能力有限
    3)無法高可用
  • 主從復制
    Redis的復制(replication)功能允許用戶根據(jù)一個Redis服務器來創(chuàng)建任意多個該服務器的復制品,其中被復制的服務器為主服務器(master),而通過復制創(chuàng)建出來的服務器復制品則為從服務器(slave)。 只要主從服務器之間的網(wǎng)絡連接正常,主從服務器兩者會具有相同的數(shù)據(jù),主服務器就會一直將發(fā)生在自己身上的數(shù)據(jù)更新同步 給從服務器,從而一直保證主從服務器的數(shù)據(jù)相同。
    特點:
    1)master/slave 角色
    2)master/slave 數(shù)據(jù)相同
    3)降低master讀壓力,并轉(zhuǎn)交給從庫
    問題:
    1)無法保證高可用
    2)無法解決master寫壓力
  • 哨兵
    Redis sentinel是一個分布式系統(tǒng)中監(jiān)控redis主從服務器,并在主服務器下線時自動進行故障轉(zhuǎn)移。其中三個特性:
    監(jiān)控(Monitoring):Sentinel會不斷檢查主服務器和從服務器是否運作正常。
    提醒(Notification):當被監(jiān)控的某個Redis服務器出現(xiàn)問題時,Sentinel可以通過API向管理員或者其他應用程序發(fā)送通知。
    自動故障遷移(Automatic failover):當一個主服務器不能正常工作時,Sentinel會開始一次自動故障遷移操作。
    特點:
    1)保證高可用
    2)監(jiān)控各個節(jié)點
    3)自動故障遷移
    缺點:
    1)主從模式,切換需要時間,會丟數(shù)據(jù)
    2)沒有解決master寫壓力
  • 集群(proxy型)
    Twemproxy是Twitter開源的redis和memcache快速/輕量級代理服務器,它是一個快速的單線程代理程序,支持Memcached ASCII協(xié)議和redis協(xié)議。
    特點:
    1)支持多種hash算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins
    2)支持失敗節(jié)點自動刪除
    3)后端Sharding分片邏輯對業(yè)務透明,業(yè)務方的讀寫方式和操作單個Redis一致
    缺點:
    1)增加了新的proxy,需要維護其高可用。
    2)failover邏輯需要自己實現(xiàn),其本身不支持故障的自動轉(zhuǎn)移,可擴展性差,進行擴縮容都需要手動干預。
  • 集群(直連型)
    redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用無中心結(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ù)通過異步復制,不能保證數(shù)據(jù)的強一致性。
7、Redis分布式鎖是怎么實現(xiàn)的?

先拿setnx來爭搶鎖,搶到后再用expire給鎖加一個過期時間,防止鎖忘記釋放。
如果在setnx之后執(zhí)行expire之前進程意外crash或者要重啟維護了會怎么樣?
set指令有非常復雜的參數(shù),這個應該是可以同時把setnx和expire合成一條指令來用。

8、Redis做異步隊列是怎么用的?有什么缺點?

一般使用list結(jié)構(gòu)作為隊列,rpush生產(chǎn)消息,lpop消費消息。當lpop沒有消息的時候,要適當sleep一會再重試。
可不可以不用sleep呢?
list還有個指令叫blpop,在沒有消息時,它會阻塞直到消息到來。
能不能生產(chǎn)一次消費多次呢?
使用pub/sub主題訂閱者模式,可以實現(xiàn)1:N的消息隊列,即生產(chǎn)一次消費多次。
pub/sub有什么缺點?
在消費者下線的情況下,生產(chǎn)的消息會丟失,得使用專業(yè)的消息隊列如rabbitmq等。
redis如何實現(xiàn)延時隊列?
使用sortedset,拿時間戳作為score,消息內(nèi)容作為key,調(diào)用zadd來生產(chǎn)消息,消費者用zrangebyscore指令獲取N秒之前的數(shù)據(jù),輪詢進行處理。

9、什么是緩存穿透?如何避免?

緩存穿透:一般的緩存系統(tǒng),都是按照key去緩存查詢,如果不存在對應的value,就應該去后端系統(tǒng)查找(比如DB)。一些惡意的請求會故意查詢不存在的key,請求量很大,就會對后端系統(tǒng)造成很大的壓力,這就叫緩存穿透。
避免方式:
1)對查詢結(jié)果為空的情況也進行緩存,緩存時間設置短一點,或者該key對應的數(shù)據(jù)insert之后清理緩存。
2)對一定不存在的key進行過濾,可以把所有可能存在的key放到一個大的Bitmap中,查詢時通過該bitmap過濾。

10、什么是緩存雪崩?何如避免?

緩存雪崩:當緩存服務器重啟或大量緩存集中在某個時間段失效,在失效時會給后端系統(tǒng)帶來很大壓力,導致系統(tǒng)崩潰。
避免方式:
1)在緩存失效后,通過加鎖或隊列來控制讀數(shù)據(jù)庫和寫緩存的線程數(shù)量。比如對某個key只允許一個線程查詢數(shù)據(jù)和寫緩存,其他線程等待。
2)做二級緩存,A1為原始緩存,A2為拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設置為短期,A2設置為長期。
3)不同的key,設置不同的過期時間,讓緩存失效的時間點盡量均勻。

11、Redis里面有1億個key,其中有10w個key是以某個固定的已知的前綴開頭的,如何將它們?nèi)空页鰜恚?/h6>

使用keys指令可以掃出指定模式的key列表。
redis是單線程的,keys指令會導致線程阻塞一段時間,線上服務會停頓,直到指令執(zhí)行完畢,服務才能恢復。此時可以使用scan指令,scan指令可以無阻塞的提取出指定模式的key列表,但會有一定的重復概率,在客戶端做一次去重就可以了,但整體所花費的時間會比直接用keys指令長。

12、如果有大量的key需要設置同一時間過期,需要注意什么?

如果大量的key過期時間設置的過于集中,到過期的那個時間點,redis可能會出現(xiàn)短暫的卡頓現(xiàn)象。一般需要在時間上加一個隨機值,使過期時間分散一些。

13、Redis如何做持久化的?

bgsave做鏡像全量持久化,aof做增量持久化。bgsave會耗費較長時間,在停機時會導致大量數(shù)據(jù)丟失,需要aof來配合使用。在redis實例重啟時,優(yōu)先使用aof來恢復內(nèi)存的狀態(tài),如果沒有aof日志,就會使用rdb文件來恢復。
如果aof文件過大恢復時間過長怎么辦?
Redis會定期做aof重寫,壓縮aof文件日志大小。Redis4.0之后有了混合持久化的功能,將bgsave的全量和aof的增量做了融合處理,既保證了恢復效率又兼顧了數(shù)據(jù)的安全性。
如果機器突然斷電會怎樣?
取決于aof日志sync屬性的配置,如果不要求性能,在每條寫指令時都sync一下磁盤,就不會丟失數(shù)據(jù)。在高性能的要求下每次都sync是不現(xiàn)實的,一般使用定時sync,如1s1次,最多會丟失1s的數(shù)據(jù)。

14、Pipeline有什么好處,為什么要用pipeline?

可以將多次IO往返的時間縮減為一次,前提是pipeline執(zhí)行的指令之間沒有因果相關性。使用redis-benchmark進行壓測時可以發(fā)現(xiàn)影響redis的QPS峰值的一個重要因素是pipeline批次指令的數(shù)目。

15、Redis的同步機制?

從從同步。第一次同步時,主節(jié)點做一次bgsave,并同時將后續(xù)修改操作記錄到內(nèi)存buffer,待完成后將rdb文件全量同步到復制節(jié)點,復制節(jié)點接收完成后將rdb鏡像加載到內(nèi)存。加載完成后,再通知主節(jié)點將期間修改的操作記錄同步到復制節(jié)點進行重放,就完成了同步過程。

16、Redis集群的原理?

Redis Sentinal著眼于高可用,在master宕機時會自動將slave提升為master,繼續(xù)提供服務。
Redis Cluster著眼于擴展性,在單個redis內(nèi)存不足時,使用Cluster進行分片存儲。

17、Redis有哪幾種數(shù)據(jù)淘汰策略?

noeviction:當內(nèi)存限制達到返回錯誤,并且客戶端嘗試執(zhí)行會讓更多內(nèi)存被使用的命令。
allkeys-lru:嘗試回收最少使用的鍵(LRU),使新添加的數(shù)據(jù)有空間存放。
volatile-lru:嘗試回收最少使用的鍵(LRU),僅限于在過期集合的鍵,使新添加的數(shù)據(jù)有空間存放。
allkeys-random:回收隨機的鍵使新添加的數(shù)據(jù)有空間存放。
volatile-random:回收隨機的鍵使新添加的數(shù)據(jù)有空間存放,僅限于在過期集合的鍵。
volatile-ttl:回收在過期集合的鍵,并且優(yōu)先回收存活時間(TTL)較短的鍵,使新添加的數(shù)據(jù)有空間存放。

18、為什么Redis需要把所有數(shù)據(jù)放到內(nèi)存中?

為了達到最快的讀寫速度將數(shù)據(jù)都讀到內(nèi)存中,并通過異步的方式將數(shù)據(jù)寫入磁盤。redis具有快速和數(shù)據(jù)持久化的特征,若不放在內(nèi)存中,磁盤I/O速度會嚴重影響redis的性能。 如果設置了最大使用的內(nèi)存,則數(shù)據(jù)已有記錄數(shù)達到內(nèi)存限值后不能繼續(xù)插入新值。

19、Redis有哪些適合的場景?

1)會話緩存(Session Cache)
最常用的一種情景是會話緩存(session cache),用Redis緩存會話比其他存儲(如Memcached)的優(yōu)勢在于:Redis提供持久化。
2)全頁緩存(FPC)
除基本的會話token外,Redis還提供簡便的FPC平臺。即使重啟了Redis實例,因為有磁盤的持久化,用戶也不會看到頁面加載速度的下降,這是一個極大改進,類似PHP本地FPC。
3)隊列
Reids在內(nèi)存存儲引擎領域的一大優(yōu)點是提供list和set操作,使Redis能作為一個很好的消息隊列平臺來使用。Redis作為隊列使用的操作,類似于本地程序語言對list的push/pop操作。
4)排行榜/計數(shù)器
Redis在內(nèi)存中對數(shù)字進行遞增或遞減的操作實現(xiàn)的非常好。集合(Set)和有序集合(SortedSet)使得我們在執(zhí)行這些操作的時候變的非常簡單,Redis只是正好提供了這兩種數(shù)據(jù)結(jié)構(gòu)。
5)發(fā)布/訂閱
發(fā)布/訂閱的使用場景非常多。在社交網(wǎng)絡連接中使用,還可作為基于發(fā)布/訂閱的腳本觸發(fā)器,甚至用Redis的發(fā)布/訂閱功能來建立聊天系統(tǒng)。

20、Redis集群的主從復制模型是怎樣的?

為了使在部分節(jié)點失敗或大部分節(jié)點無法通信的情況下集群仍可用,集群使用了主從復制模型,每個節(jié)點都會有N-1個復制品。

21、Redis集群會有寫操作丟失嗎?

Redis并不能保證數(shù)據(jù)的強一致性,在實際中集群在特定的條件下可能會丟失寫操作。

22、Redis集群之間是如何復制的?

異步復制

23、Redis集群最大節(jié)點個數(shù)是多少?

16384個

24、怎么理解Redis事務?

事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執(zhí)行,事務在執(zhí)行的過程中,不會被其他客戶端發(fā)送來的命令請求所打斷。事務是一個原子操作:事務中的命令要么全被執(zhí)行,要么全不執(zhí)行。

25、Redis事務相關的命令有哪幾個?

MULTI、EXEC、DISCARD、WATCH

26、Redis key的過期時間和永久有效怎么設置?

EXPIRE和PERSIST命令

27、Redis如何做內(nèi)存優(yōu)化?

盡可能使用散列表(hashes),散列表使用的內(nèi)存非常小,應該盡可能的將數(shù)據(jù)模型抽象到一個散列表里。 比如web系統(tǒng)中有一個用戶對象,不要為這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而應該把這個用戶的所有信息存儲到一張散列表里。

28、Redis回收進程如何工作的?

一個客戶端運行了新命令,添加了新數(shù)據(jù)。Redis檢查內(nèi)存使用情況,如果大于maxmemory限制, 則根據(jù)設定好的策略進行回收、一個新命令被執(zhí)行等。 所以我們不斷地穿越內(nèi)存限制的邊界,通過不斷達到邊界然后不斷地回收回到邊界以下。如果一個命令的結(jié)果導致大量內(nèi)存被使用,不用多久內(nèi)存限制就會被這個內(nèi)存使用量超越。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 一、Redis高可用概述 在介紹Redis高可用之前,先說明一下在Redis的語境中高可用的含義。 我們知道,在w...
    空語閱讀 1,686評論 0 2
  • 1、什么是Redis ??Redis是一個高性能的key/value的分布式內(nèi)存數(shù)據(jù)庫,基于內(nèi)存運行并支持持久化的...
    小胖六閱讀 471評論 3 0
  • 企業(yè)級redis集群架構(gòu)的特點 海量數(shù)據(jù) 高并發(fā) 高可用 要達到高可用,持久化是不可減少的,持久化主要是做災難恢復...
    lucode閱讀 2,285評論 0 7
  • Redis雜談 Redis是近年來發(fā)展迅速的內(nèi)存數(shù)據(jù)庫,網(wǎng)上也已經(jīng)有多Redis的文章。但不管是英文還是中文,多數(shù)...
    迷失于重逢閱讀 1,720評論 0 14
  • 羨慕十六七歲乃至更小,以為自己是個小大人了,結(jié)果一不開心就發(fā)個朋友圈,又或者過節(jié)乃至天變了都發(fā)個朋友圈艾特一大堆人...
    SlothAndSnail閱讀 383評論 0 0

友情鏈接更多精彩內(nèi)容