Redis面試題


1.什么是Redis?

   Redis是一中基於 key-value 對非關系型數據庫(nosql)redis 所有數據都存在內存中,所以讀寫速度非常快,因此 redis 被廣泛應用於緩存方向。另外,redis 也經常用來做分布式鎖。redis 提供了多種數據類型來支持不同的業務場景。

  因為是純內存操作,Redis的性能非常出色,每秒可以處理超過 10萬次讀寫操作,是已知性能最快的Key-Value DB。

  Redis的出色之處不僅僅是性能,Redis最大的魅力是支持保存多種數據結構

  Redis的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要局限在較小數據量的高性能操作和運算上

2.為什么要用 redis/為什么要用緩存?

  主要從“高性能”和“高並發”這兩點來看待這個問題。

高性能:

  假如用戶第一次訪問數據庫中的某些數據。這個過程會比較慢,因為是從硬盤上讀取的。將該用戶訪問的數據存在緩存中,這樣下一次再訪問這些數據的時候就可以直接從緩存中獲取了。操作緩存就是直接操作內存,所以速度相當快。如果數據庫中的對應數據改變的之后,同步改變緩存中相應的數據即可!

高並發:

  直接操作緩存能夠承受的請求是遠遠大於直接訪問數據庫的,所以我們可以考慮把數據庫中的部分數據轉移到緩存中去,這樣用戶的一部分請求會直接到緩存這里而不用經過數據庫。

3. Redis好處?

  (1) 速度快,因為數據存在內存中。類似於HashMap,HashMap的優勢就是查找和操作的時間復雜度都是O(1)

  (2) 支持豐富數據類型,支持string(字符串類型),list(列表類型),set(集合類型),sorted set(有序集合類型),hash(散列類型)

  (3) 支持事務,操作都是原子性,所謂的原子性就是對數據的更改要么全部執行,要么全部不執行

  (4) 豐富的特性:可用於緩存,消息,按key設置過期時間,過期后將會自動刪除

4、為什么要用 redis 而不用 map/guava 做緩存?

  緩存分為本地緩存和分布式緩存。以 Java 為例,

  使用自帶的 map 或者 guava 實現的是本地緩存,最主要的特點是輕量以及快速,生命周期隨着 jvm 的銷毀而結束,並且在多實例的情況下,每個實例都需要各自保存一份緩存,緩存不具有一致性

  使用 redis 或 memcached 之類的稱為分布式緩存在多實例的情況下,各實例共用一份緩存數據,緩存具有一致性。缺點是需要保持 redis 或 memcached服務的高可用,整個程序架構上較為復雜。

3.redis和memcached的區別?

  (1) redis支持更豐富的數據類型(支持更復雜的應用場景):Redis支持Srting、list,set,zset,hash等數據結構的存儲memcache只支持字符串String數據類型

  (2)Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用而Memecache把數據全部存在內存之中

  (3)Redis使用單線程的多路 IO 復用模型;Memcached是多線程、非阻塞IO復用的網絡模型。(redis的速度比memcached快很多)

  (4)集群模式:memcached沒有原生的集群模式,需要依靠客戶端來實現往集群中分片寫入數據;但redis 目前是原生支持 cluster 模式的

4.Redis支持的數據類型?

  • String(字符串類型)
    • String數據結構是簡單的key-value類型,value其實不僅可以是String,也可以是數字。 常規key-value緩存應用; 常規計數:微博數,粉絲數等。
    • 常用命令: set,get,incr,decr,mget 等:set key value 設置值、 get key 獲取值、 incr key  加一、  decr key 減一
  • hash(哈希)
    • Redis hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象,后續操作的時候,你可以直接僅僅修改這個對象中的某個字段的值
    • 常用命令: set,get,decr,incr,mget 等:
      • hset  key field value    設置值
      • hget  key field   獲取值
      • hincrby key field num  設置增數量
  • list(列表)
    • Redis list 的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷。
    • Redis list 的應用場景非常多,也是Redis最重要的數據結構之一,比如微博的關注列表,粉絲列表,消息列表等功能都可以用Redis的 list 結構來實現。
    • 可以通過 lrange 命令,就是從某個元素開始讀取多少個元素,可以基於 list 實現分頁查詢,這個很棒的一個功能,基於 redis 實現簡單的高性能分頁,可以做類似微博那種下拉不斷分頁的東西(一頁一頁的往下走),性能高。
    • 常用命令: lpush,rpush,lpop,rpop,lrange等:
      • lpush list a b c d  (從list左邊添加元素)、 rpush list 1 2 3 4  (從list右邊添加元素)
      • lrange list 0 -1(從0 到 -1 元素查看:也就表示查看所有)
      • lpop list (從list左邊取,刪除)、  rpop list (從list右邊取,刪除)
  • set(集合)
    • Redis的Set是string類型的無序集合。集合是通過哈希表實現的,所以添加,刪除,查找的復雜度都是O(1)。
    • 常用命令: sadd,spop,smembers,sunion
      • sadd set1 a b c d d    (向set1中添加元素) 元素不重復
      • smembers set1(查詢元素)、  srem set1 a(刪除元素)
  • sorted set(zset,有序集合)
    • 和set相比,sorted set增加了一個權重參數score,使得集合中的元素能夠按score進行有序排列
    • 例:在直播系統中,實時排行信息包含直播間在線用戶列表,各種禮物排行榜,彈幕消息(可以理解為按消息維度的消息排行榜)等信息,適合使用 Redis 中的 Sorted Set 結構進行存儲。
    • 常用命令: zadd,zrange,zrem,zcard等:
      • zadd zset1 1 a 2 b 3 c (添加元素 zadd key score member,這里添加元素a:1分、元素b:2分、元素c:3分 )
      • zrange zset1  0  -1   (查看zset1的所有元素,默認從小到大)
      • zrange zset1  0  -1  withscores  (查看zset1的所有元素,包括分數score)
      • zrevrange zset1 0 -1                  (查看zset1的所有元素,從大到小)
      • zincrby zset1 5 a                        (對zset1的a元素增加5分)

5.什么是Redis持久化?Redis有哪幾種持久化方式?優缺點是什么?

  持久化就是把內存的數據寫到磁盤中,防止服務宕機了內存數據丟失

  (Redis 數據都放在內存中如果機器掛掉,內存的數據就不存在。所以需要做持久化,將內存中的數據保存在磁盤,下一次啟動的時候就可以恢復數據到內存中。

 

  Redis 提供了兩種持久化方式:RDB(默認) 和AOF

  • RDB (快照)

  Redis可以通過創建快照來 獲得存儲在內存里面的數據在某個時間點上的副本。Redis創建快照之后,可以對快照進行備份,可以將快照復制到其他服務器從而創建具有相同數據的服務器副本(Redis主從結構,主要用來提高Redis性能),還可以將快照留在原地以便重啟服務器的時候使用。

  快照持久化是Redis默認采用的持久化方式,在redis.conf配置文件中默認有此下配置:

save 900 1           #在900秒(15分鍾)之后,如果至少有1個key發生變化,Redis就會自動觸發BGSAVE命令創建快照。

save 300 10          #在300秒(5分鍾)之后,如果至少有10個key發生變化,Redis就會自動觸發BGSAVE命令創建快照。

save 60 10000        #在60秒(1分鍾)之后,如果至少有10000個key發生變化,Redis就會自動觸發BGSAVE命令創建快照。
  • AOF(只追加文件):

  與快照持久化相比,AOF持久化的實時性更好,因此已成為主流的持久化方案。默認情況下Redis沒有開啟AOF(append only file)方式的持久化,可以通過appendonly參數開啟:appendonly yes

  開啟AOF持久化后每執行一條會更改Redis中的數據的命令,Redis就會將該命令寫入硬盤中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通過dir參數設置的,默認的文件名是appendonly.aof。

  在Redis的配置文件中存在三種不同的 AOF 持久化方式,它們分別是:

appendfsync always    #每次有數據修改發生時都會寫入AOF文件,這樣會嚴重降低Redis的速度
appendfsync everysec  #每秒鍾同步一次,顯示地將多個寫命令同步到硬盤
appendfsync no        #讓操作系統決定何時進行同步

  為了兼顧數據和寫入性能,用戶可以考慮 appendfsync everysec選項 ,讓Redis每秒同步一次AOF文件,Redis性能幾乎沒受到任何影響。而且這樣即使出現系統崩潰,用戶最多只會丟失一秒之內產生的數據。當硬盤忙於執行寫入操作的時候,Redis還會優雅的放慢自己的速度以便適應硬盤的最大寫入速度。

 

  • RDB (快照):快照形式  ,定期將當前時刻的數據保存磁盤中。會產生一個dump.rdb文件
    • 特點:性能較好,數據備份。但可能會存在數據丟失。
  • AOF(只追加文件) :append only file  (所有對redis的操作命令記錄在aof文件中),恢復數據,重新執行一遍即可。
    • 特點:每秒保存,數據比較完整。但耗費性能。  

  【注】如果兩個都配了優先加載AOF。(同時開啟兩個持久化方案,則按照 AOF的持久化放案恢復數據。)

6、redis 設置過期時間

  Redis中有個設置時間過期的功能,即對存儲在 redis 數據庫中的值可以設置一個過期時間。作為一個緩存數據庫,這是非常實用的。如我們一般項目中的 token 或者一些登錄信息,尤其是短信驗證碼都是有時間限制的,按照傳統的數據庫處理方式,一般都是自己判斷過期,這樣無疑會嚴重影響項目性能。

  我們 set key 的時候,都可以給一個過期時間(expire time),通過過期時間我們可以指定這個 key 可以存活的時間。

如果假設你設置了一批 key 只能存活1個小時,那么接下來1小時后,redis是怎么對這批key進行刪除的?

  定期刪除+惰性刪除

  • 定期刪除redis默認是每隔 100ms隨機抽取一些設置了過期時間的key,檢查其是否過期,如果過期就刪除。注意這里是隨機抽取的。為什么要隨機呢?你想一想假如 redis 存了幾十萬個 key ,每隔100ms就遍歷所有的設置過期時間的 key 的話,就會給 CPU 帶來很大的負載!
  • 惰性刪除 :定期刪除可能會導致很多過期 key 到了時間並沒有被刪除掉。所以就有了惰性刪除。假如你的過期 key,靠定期刪除沒有被刪除掉,還停留在內存里,除非你的系統去查一下那個 key,才會被redis給刪除掉。這就是所謂的惰性刪除

但是僅僅通過設置過期時間還是有問題的。我們想一下:如果定期刪除漏掉了很多過期 key,然后你也沒及時去查,也就沒走惰性刪除,此時會怎么樣?如果大量過期key堆積在內存里,導致redis內存塊耗盡了。怎么解決這個問題呢? redis 內存淘汰機制(數據淘汰策略)

7.Redis有哪幾種數據淘汰策略?

  問題:MySQL里有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據?

    redis內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略

redis 提供 6種數據淘汰策略:

  • volatile-lru::從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰。
  • volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰。
  • volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰。
  • allkeys-lru: 從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰。
  • allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰。
  • no-enviction:禁止驅逐數據,永不回收數據

  在Redis當中,有生存期的key被稱為volatile。在創建緩存時,要為給定的key設置生存期,當key過期的時候(生存期為0),它可能會被刪除。

  更新生存時間:可以對一個已經帶有生存時間的 key 執行EXPIRE命令,新指定的生存時間會取代舊的生存時間

  最大緩存配置:在 redis 中,允許用戶設置最大使用內存大小 server.maxmemory,默認為0,沒有指定最大緩存,如果有新的數據添加,超過最大內存,則會使redis崩潰,所以一定要設置。redis 內存數據集大小上升到一定大小的時候,就會實行數據淘汰策略。

8.Redis 有哪些架構模式?講講各自的特點

  主從模式(redis2.8版本之前的模式)、哨兵sentinel模式(redis2.8及之后的模式)、redis cluster模式(redis3.0版本之后)
 
(1)主從模式
  主從模式指的是使用一個redis實例作為主機,其余的實例作為備份機。主機和從機的數據完全一致, 主機支持數據的寫入和讀取等各項操作,而從機則只支持與主機數據的同步和讀取,也就是說, 客戶端可以將數據寫入到主機,由主機自動將數據的寫入操作同步到從機。主從模式很好的解決了數據備份問題,並且由於主從服務數據幾乎是一致的,因而 可以將寫入數據的命令發送給主機執行,而讀取數據的命令發送給不同的從機執行,從而達到讀寫分離的目的。如下所示主機redis-A分別有redis-B、redis-C、redis-D、redis-E四個從機:

  優點:

  1. 解決數據備份問題
  2. 做到讀寫分離,提高服務器性能

  缺點:

  1. 每個客戶端連接redis實例的時候都是指定了ip和端口號的,如果所連接的redis實例因為故障下線了,而主從模式也沒有提供一定的手段通知客戶端另外可連接的客戶端地址,因而需要手動更改客戶端配置重新連接。
  2. 主從模式下,如果主節點由於故障下線了,那么從節點因為沒有主節點而同步中斷,因而需要人工進行故障轉移工作。
  3. 無法實現動態擴容。
 (2)哨兵模式(sentinel)
 
   由一個或多個Sentinel實例組成的Sentinel系統可以監視任意多個主服務器,以及這些主服務器屬下的所有從服務器,並在被監視的主服務器進入下線狀態時,自動將下線主服務器屬下的某個從服務器升級為新的主服務器。
  對於一組主從節點,sentinel只是在其外部額外添加的一組用於監控作用的redis實例。在主從節點和sentinel節點集合配置好之后,sentinel節點之間會相互發送消息,以檢測其余sentinel節點是否正常工作,並且sentinel節點也會向主從節點發送消息,以檢測監控的主從節點是否正常工作。

  優點:

  • 如果主服務器異常,則會進行主從轉換,將其中一個從服務器升級為為主服務器,將之前的主服務器作為從服務器。

  缺點:

  1. 如果是從節點下線了,sentinel是不會對其進行故障轉移的,連接從節點的客戶端也無法獲取到新的可用從節點
  2. 無法實現動態擴容
(3)集群模式(cluster)

  在這個圖中,每一個藍色的圈都代表着一個redis的服務器節點。它們任何兩個節點之間都是相互連通的。客戶端可以與任何一個節點相連接,然后就可以訪問集群中的任何一個節點。對其進行存取和其他操作。

  一般集群建議搭建三主三從架構,三主提供服務,三從提供備份功能。

 

  每一個節點都存有這個集群所有主節點以及從節點的信息。

    它們之間通過互相的ping-pong判斷是否節點可以連接上。如果有一半以上的節點去ping一個節點的時候沒有回應,集群就認為這個節點宕機了,然后去連接它的備用節點。如果某個節點和所有從節點全部掛掉,我們集群就進入faill狀態。還有就是如果有一半以上的主節點宕機,那么我們集群同樣進入faill狀態。這就是我們的redis的投票機制,具體原理如下圖所示:

 投票過程:集群中所有master參與,如果半數以上master節點與master節點通信超時(cluster-node-timeout),認為當前master節點掛掉。

  優點:

  1. 有效的解決了redis在分布式方面的需求
  2. 遇到單機內存,並發和流量瓶頸等問題時,可采用Cluster方案達到負載均衡的目的
  3. 可實現動態擴容
  4. P2P模式,無中心化
  5. 通過Gossip協議同步節點信息
  6. 自動故障轉移、Slot遷移中數據可用

  缺點:

  1. 為了性能提升,客戶端需要緩存路由表信息。
  2. 節點發現、reshard操作不夠自動化。

推薦redis三種模式對比

9. 說一下Redis集群原理

   redis cluster在設計的時候,就考慮到了去中心化,去中間件,也就是說, 集群中的每個節點都是平等的關系,每個節點都保存各自的數據和整個集群的狀態。每個節點都和其他所有節點連接,而且這些連接保持活躍,這樣就保證了我們只需要連接集群中的任意一個節點,就可以獲取到其他節點的數據。

  Redis 集群沒有並使用傳統的一致性哈希來分配數據,而是采用一種叫做哈希槽 (hash slot)的方式來分配數據的。redis cluster 默認分配了 16384 個slot,當需要在 Redis 集群中放置一個 key-value 時,redis先對key使用crc16算法算出一個結果,然后把結果對16384求余數,這樣每個key都會對應一個編號在 0-16383之間的哈希槽,redis會根據節點數量大致均等的將哈希槽映射到不同的節點

  Redis 集群會把數據存在一個 master節點,然后在這個 master 和其對應的salve之間進行數據同步當讀取數據時,也根據一致性哈希算法到對應的 master 節點獲取數據只有當一個master 掛掉之后,才會啟動一個對應的 salve 節點,充當 master 。

 

需要注意的是:必須要3個或以上的主節點,否則在創建集群時會失敗,並且當存活的主節點數小於總節點數的一半時,整個集群就無法提供服務了。 

10.緩存穿透?擊穿?雪崩?

緩存穿透一般緩存系統都是按照key去查詢,如果不存在對應的value再去數據庫中查找。一些惡意的請求會故意查詢不存在的key,請求量很大,會對數據庫造成很大的壓力

解決

  1)接口層增加校驗,如對id做基礎校驗,id<=0的直接攔截。

  2)從緩存中取不到的數據在數據庫中也沒有取到,這時可以將key-value對攜程key-null,緩存有效時間設置短點。這樣可以防止攻擊用戶反復用同一個id暴力攻擊。

緩存擊穿指緩存中沒有但數據庫中有的數據(一般是緩存時間到期),這時由於並發用戶特別多,同時緩存沒讀到數據,就同時去數據庫去取數據,引起數據庫壓力瞬間增大

解決

  1)設置熱點數據永不過期。

  2)加互斥鎖。緩存中如果沒數據,就首先去獲取鎖,獲取鎖成功后(if(relock.tryLock()))后再去數據庫取數據,然后更新緩存數據。其他並行進入的線程等待100ms再重新去緩存取數據。

緩存雪崩指緩存中大批量數據到過期時間,而查詢數量巨大,引起數據庫壓力過大甚至宕機與緩存擊穿不同的是,緩存擊穿指並發查同一條數據,緩存血崩是不同數據

解決

  1)對查詢結果為空的數據也進行緩存(key-value寫成key-null),然后將它的緩存時間設置短一點,這樣可以防止攻擊用戶反復用一個id暴力攻擊。

   2)對key進行過濾。將所有可能存在的數據哈希到一個足夠大的bitmap中,一定不存在的數據會被這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。

  3)緩存失效后,通過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。比如對某個key只允許一個線程查詢數據和寫緩存,其他線程等待。

11. 如何解決 Redis 的並發競爭 Key 問題

  所謂 Redis 的並發競爭Key 的問題也就是:多個系統同時對一個 key 進行操作,但是最后執行的順序和我們期望的順序不同,這樣也就導致了結果的不同!

  推薦一種方案:分布式鎖(zookeeper 和 redis 都可以實現分布式鎖)。(如果不存在 Redis 的並發競爭 Key 問題,不要使用分布式鎖,這樣會影響性能

  基於zookeeper臨時有序節點可以實現的分布式鎖。大致思想為:每個客戶端對某個方法加鎖時,在zookeeper上的與該方法對應的指定節點的目錄下,生成一個唯一的瞬時有序節點。 判斷是否獲取鎖的方式很簡單,只需要判斷有序節點中序號最小的一個。 當釋放鎖的時候,只需將這個瞬時節點刪除即可。同時,其可以避免服務宕機導致的鎖無法釋放,而產生的死鎖問題。完成業務流程后,刪除對應的子節點釋放鎖。

  在實踐中,當然是從以可靠性為主。所以首推Zookeeper。

12.如何保證Redis緩存與數據庫的數據一致性?

采用如下策略:

  • 讀的時候:先讀緩存,讀到數據則直接返回;如果沒有讀到,就讀數據庫,同時將數據放入緩存,並返回響應。
  • 更新的時候:先更新數據庫,然后再刪除緩存。

為什么不先刪除緩存再更新數據庫?

  如果有兩個並發操作:一個更新、一個查詢。更新操作刪除刪除緩存后,查詢操作沒有從redis中查到數據,就從數據庫中取,而此時數據庫中還是老數據。查詢操作從數據庫中取得老數據后寫入緩存中,然后更新操作更新了數據庫。這樣數據庫與緩存中數據不一致,緩存中還是老數據。

先更新數據庫再刪除緩存就沒問題嗎?

  還是有的,例如一個讀操作沒有從緩存中讀到數據就去數據庫里讀,此時突然來了一個寫操作,它先更新了數據庫又刪除了緩存,之后那個讀操作再把老數據放進去,這樣這樣數據庫與緩存中數據不一致,緩存中還是老數據。         

  解決:可以為緩存設置過期時間。

為什么刪除緩存,而不是把更新的數據寫入緩存里?

  如果不刪除緩存而將更新的數據寫入緩存,這么做引發的問題是,如果A,B兩個線程同時做數據更新,A先更新了數據庫,B后更新數據庫,則此時數據庫里存的是B的數據。而更新緩存的時候,是B先更新了緩存,而A后更新了緩存,則緩存里是A的數據。這樣緩存和數據庫的數據也不一致。

 

13. Redis集群方案什么情況下會導致整個集群不可用?

(1)如果集群任意master掛掉,且當前master沒有slave,集群進入fail狀態。

(2)如果集群超過半數以上master掛掉,無論是否有slave集群,都會進入fail狀態.

17.redis事務

multi:開啟事務  

  • multi:開啟事務 
  • exec:提交事務

  Redis提供了一個 multi 命令開啟事務exec 命令提交事務,在它們之間的命令是在一個事務內的,能保證原子性。Redis在事務沒提交之前不會執行事務中的命令,會等到事務提交的那一刻再執行事務中的所有命令。

  multi 開始到 exec結束前,中間所有的命令都被加入到一個命令隊列中;當執行 exec命令后,將queue中所有的命令執行。

  • discard:放棄事務。即該事務內的所有命令都將取消。清除所有先前在一個事務中放入隊列的命令,然后恢復正常的連接狀態。
  • Watch:保證原子性。在 multi 命令之前可以使用 watch 命令來“觀察”一個或多個key,在事務提交之前Redis會確保被“觀察”的key有沒有被修改過,沒有被修改過才會執行事務中的命令,如果存在key被修改過,那么整個事務中的命令都不會執行。 (樂觀鎖CAS)
  • unwatch:取消WATCH命令對多有key的監控,所有監控鎖將會被取消。
 

事務對異常的處理機制:

  Redis執行命令的錯誤主要分為兩種: 

  • 命令錯誤執行命令語法錯誤,比如說將 set 命令寫成 sett 
  • 運行時錯誤命令語法正確,但是執行錯誤,比如說對 List 集合執行 sadd 命令
  開啟事務之后,往事務中添加的命令 如果有命令錯誤(語法錯誤),那么整個事務中的命令都不會執行
  如果語法沒有錯誤,而執行過程中發生了 運行時錯誤,Redis不僅不會回滾事務,還會跳過這個運行時錯誤,繼續向下執行命令。

 18.redis事務是否具有原子性、隔離性、一致性、持久性?

  Redis事務總是具有原子性、一致性和隔離性,當 Redis 運行在某種特定的持久化模式下(appendfsync always)時,事務也具有持久性。

  • 原子性√:事務是一個原子操作,事務中的命令要么全部執行,要么全部不執行。redis單個操作是原子的,多個操作也支持原子性,通過multi與exec命令包起來。
  • 隔離性√:redis事務是一個單獨的隔離操作,事務中的所有命令都會按順序地執行,事務在執行過程中不會被客戶端發來的其他命令打斷,如果是discard只會放棄全部命令。
  • 一致性√:redis拒絕入隊錯誤的事務,指令執行錯誤的事務不會引起整個事務失敗。
  • 持久性×:事務的持久性由redis使用的持久化模式決定:
    • (1)單純的內存模式下,事務肯定是不持久的;
    • (2)RDB模式下,服務器可能在事務執行之后、RDB文件更新之前這段時間失敗,因此也是不持久的;
    • (3)在AOF的“總是”持久化方式下(appendfsync always:每次有數據修改發生時都會寫入AOF文件)是持久的,因為事務每條命令在執行成功后都會立即調用fsync將是事務數據寫入aof文件。

13.為什么redis需要把所有數據放到內存中?

     Redis為了達到最快的讀寫速度將數據都讀到內存中,並通過異步的方式將數據寫入磁盤。所以redis具有快速和數據持久化的特征。如果不將數據放在內存中,磁盤I/O速度為嚴重影響redis的性能。在內存越來越便宜的今天,redis將會越來越受歡迎。
   如果設置了最大使用的內存,則數據已有記錄數達到內存限值后不能繼續插入新值。

14.Redis是單進程單線程的。

   redis利用隊列技術將並發訪問變為串行訪問,消除了傳統數據庫串行控制的開銷。

 

參考 redis面試題

  30道Redis面試題,面試官能問的都被我找到了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM