歡迎關注
CSDN:程序員小羊
微信公衆號:程序員小羊
博客園:程序員小羊html
- 一、什麼是 Redis?
- 二、Redis 與其餘 key-value 存儲有什麼不一樣?
- 三、Redis 的數據類型?
- 四、使用 Redis 有哪些好處?
- 五、Redis 相比 Memcached 有哪些優點?
- 六、Memcache 與 Redis 的區別都有哪些?
- 七、Redis 是單進程單線程的?
- 八、一個字符串類型的值能存儲最大容量是多少?
- 九、Redis持久化機制
- 十、緩存雪崩、緩存穿透、緩存預熱、緩存更新、緩存降級等問題
- 十一、熱點數據和冷數據是什麼
- 十二、單線程的redis爲何這麼快
- 1三、redis的數據類型,以及每種數據類型的使用場景
- 1四、redis的過時策略以及內存淘汰機制
- 1五、Redis 常見性能問題和解決方案?
- 1六、爲何Redis的操做是原子性的,怎麼保證原子性的?
- 1七、Redis事務
- 1八、Redis 的持久化機制是什麼?各自的優缺點?
- 1九、Redis 常見性能問題和解決方案:
- 20、redis 過時鍵的刪除策略?
- 2一、Redis 的回收策略(淘汰策略)(重複)?
- 2二、爲何 edis 須要把全部數據放到內存中?
- 2三、Redis 的同步機制瞭解麼?
- 2四、Pipeline 有什麼好處,爲何要用 pipeline?
- 2五、是否使用過 Redis 集羣,集羣的原理是什麼?
- 2五、是否使用過 Redis 集羣,集羣的原理是什麼?
- 2六、Redis 集羣方案什麼狀況下會致使整個集羣不可用?
- 2七、Redis 支持的 Java 客戶端都有哪些?官方推薦用哪一個?
- 2八、Jedis 與 Redisson 對比有什麼優缺點?
- 2九、Redis 如何設置密碼及驗證密碼?
- 30、說說 Redis 哈希槽的概念?
- 3一、Redis 集羣的主從複製模型是怎樣的?
- 3二、Redis 集羣會有寫操做丟失嗎?爲何?
- 3三、Redis 集羣之間是如何複製的?
- 3四、Redis 集羣最大節點個數是多少?
- 3五、Redis 集羣如何選擇數據庫?
- 3六、怎麼測試 Redis 的連通性?
- 3七、怎麼理解 Redis 事務?
- 3八、Redis 事務相關的命令有哪幾個?
- 3九、Redis key 的過時時間和永久有效分別怎麼設置?
- 4一、Redis 回收進程如何工做的?
- 4二、都有哪些辦法能夠下降 Redis 的內存使用狀況呢?
- 4三、Redis 的內存用完了會發生什麼?
- 4四、一個 Redis 實例最多能存放多少的 keys?List、Set、Sorted Set 他們最多能存放多少元素
- 4五、MySQL 裏有 2000w 數據,redis 中只存 20w 的數據,如何保證 redis 中的數據都是熱點數據?
- 4六、Redis 最適合的場景?
- 4七、假如 Redis 裏面有 1 億個 key,其中有 10w 個 key 是以某個固定的已知的前綴開頭的,若是將它們所有找出來?
- 4八、若是有大量的 key 須要設置同一時間過時,通常須要注意什麼?
- 4九、使用過 Redis 作異步隊列麼,你是怎麼用的?
- 50、使用過 Redis 分佈式鎖麼,它是什麼回事
一、什麼是 Redis?
Redis 是徹底開源免費的,遵照 BSD 協議,是一個高性能的 key-value 數據庫。
Redis 與其餘 key - value 緩存產品有如下三個特色:
Redis 支持數據的持久化,能夠將內存中的數據保存在磁盤中,重啓的時候能夠再次加載進行使用。
Redis 不只僅支持簡單的 key-value 類型的數據,同時還提供 list,set,zset,hash 等數據結構的存儲。
Redis 支持數據的備份,即 master-slave 模式的數據備份。
Redis 優點
性能極高 – Redis 能讀的速度是 110000 次/s,寫的速度是 81000 次/s 。豐富的數據類型 – Redis 支持二進制案例的 Strings, Lists, Hashes,
Sets 及Ordered Sets 數據類型操做。
原子 – Redis 的全部操做都是原子性的,意思就是要麼成功執行要麼失敗徹底不執行。單個操做是原子性的。多個操做也支持事務,即原子性,經過 MULTI 和 EXEC指令包起來。
豐富的特性 – Redis 還支持 publish/subscribe, 通知, key 過時等等特性。java
二、Redis 與其餘 key-value 存儲有什麼不一樣?
Redis 有着更爲複雜的數據結構而且提供對他們的原子性操做,這是一個不一樣於其餘數據庫的進化路徑。Redis 的數據類型都是基於基本數據結構的同時對程序員透明,無需進行額外的抽象。Redis 運行在內存中可是能夠持久化到磁盤,因此在對不一樣數據集進行高速讀寫時須要權衡內存,由於數據量不能大於硬件內存。在內存數據庫方面的另外一個優勢是,相比在磁盤上相同的複雜的數據結構,在內存中操做起來很是簡單,這樣 Redis能夠作不少內部複雜性很強的事情。同時,在磁盤格式方面他們是緊湊的以追加的方式產生的,由於他們並不須要進行隨機訪問。mysql
三、Redis 的數據類型?
Redis 支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及 zsetsorted set:有序集合)。
咱們實際項目中比較經常使用的是 string,hash 若是你是 Redis 中高級用戶,還須要加上下面幾種數據結構 HyperLogLog、Geo、Pub/Sub。若是你說還玩過 Redis Module,像 BloomFilter,RedisSearch,Redis-ML,面試官得眼睛就開始發亮了。程序員
四、使用 Redis 有哪些好處?
- 速度快,由於數據存在內存中,相似於 HashMap,HashMap 的優點就是查找和操做的時間複雜度都是 O1)
- 支持豐富數據類型,支持 string,list,set,Zset,hash 等
- 支持事務,操做都是原子性,所謂的原子性就是對數據的更改要麼所有執行,要麼所有不執行
- 豐富的特性:可用於緩存,消息,按 key 設置過時時間,過時後將會自動刪除
五、Redis 相比 Memcached 有哪些優點?
- Memcached 全部的值均是簡單的字符串,redis 做爲其替代者,支持更爲豐富的數據類
- Redis 的速度比 Memcached 快很
- Redis 能夠持久化其數據
六、Memcache 與 Redis 的區別都有哪些?
- 存儲方式 Memecache 把數據所有存在內存之中,斷電後會掛掉,數據不能超過內存大小。 Redis 有部份存在硬盤上,這樣能保證數據的持久性。
- 數據支持類型 Memcache 對數據類型支持相對簡單。 Redis 有複雜的數據類型。
- 使用底層模型不一樣 它們之間底層實現方式 以及與客戶端之間通訊的應用協議不同。 Redis 直接本身構建了 VM 機制 ,由於通常的系統調用系統函數的話,會浪費必定的時間去移動和請求。
七、Redis 是單進程單線程的?
Redis 是單進程單線程的,redis 利用隊列技術將併發訪問變爲串行訪問,消除了傳統數據庫串行控制的開銷。web
八、一個字符串類型的值能存儲最大容量是多少?
512M面試
九、Redis持久化機制
Redis是一個支持持久化的內存數據庫,經過持久化機制把內存中的數據同步到硬盤文件來保證數據持久化。當Redis重啓後經過把硬盤文件 從新加載到內存,就能達到恢復數據的目的。
實現:單首創建fork()一個子進程,將當前父進程的數據庫數據複製到子進程的內存中,而後由子進程寫入到臨時文件中,持久化的過程結束了,再用這個臨時文件替換上次的快照文件,而後子進程退出,內存釋放。
RDB是Redis默認的持久化方式。按照必定的時間週期策略把內存的數據以快照的形式保存到硬盤的二進制文件。即Snapshot快照存儲,對應產生的數據文件爲dump.rdb,經過配置文件中的save參數來定義快照的週期。( 快照能夠是其所表示的數據的一個副本,也能夠是數據的一個複製品。)
AOF:Redis會將每個收到的寫命令都經過Write函數追加到文件最後,相似於MySQL的binlog。當Redis重啓是會經過從新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。當兩種方式同時開啓時,數據恢復Redis會優先選擇AOF恢復。redis
十、緩存雪崩、緩存穿透、緩存預熱、緩存更新、緩存降級等問題
1、緩存雪崩
咱們能夠簡單的理解爲:因爲原有緩存失效,新緩存未到期間(例如:咱們設置緩存時採用了相同的過時時間,在同一時刻出現大面積的緩存過時),全部本來應該訪問緩存的請求都去查詢數據庫了,而對數據庫CPU和內存形成巨大壓力,嚴重的會形成數據庫宕機。從而造成一 系列連鎖反應,形成整個系統崩潰。
解決辦法:
大多數系統設計者考慮用加鎖( 最多的解決方案)或者隊列的方式保證來保證不會有大量的線程對數據庫一次性進行讀寫,從而避免失效時大量的併發請求落到底層存儲系統上。還有一個簡單方案就時講緩存失效時間分散開。
2、緩存穿透
緩存穿透是指用戶查詢數據,在數據庫沒有,天然在緩存中也不會有。這樣就致使用戶查詢的時候,在緩存中找不到,每次都要去數據庫再查詢一遍,而後返回空(至關於進行了兩次無用的查詢)。這樣請求就繞過緩存直接查數據庫,這也是常常提的緩存命中率問題。
解決辦法;
最多見的則是採用布隆過濾器,將全部可能存在的數據哈希到一個足夠大的bitmap中,一個必定不存在的數據會被這個bitmap攔截掉,從 而避免了對底層存儲系統的查詢壓力。另外也有一個更爲簡單粗暴的方法,若是一個查詢返回的數據爲空(無論是數據不存在,仍是系統故障),咱們仍然把這個空結果進行緩存,但它的過時時間會很短,最長不超過五分鐘。經過這個直接設置的默認值存放到緩存,這樣第二次到緩衝中獲取就有值了,而不會繼續訪問數據庫,這種辦法最簡單粗暴。
5TB的硬盤上放滿了數據,請寫一個算法將這些數據進行排重。若是這些數據是一些32bit大小的數據該如何解決?若是是64bit的呢?
對於空間的利用到達了一種極致,那就是Bitmap和布隆過濾器(Bloom Filter)。
Bitmap: 典型的就是哈希表
缺點是,Bitmap對於每一個元素只能記錄1bit信息,若是還想完成額外的功能,恐怕只能靠犧牲更多的空間、時間來完成了算法
布隆過濾器(推薦)
就是引入了k(k>1)k(k>1)個相互獨立的哈希函數,保證在給定的空間、誤判率下,完成元素判重的過程。它的優勢是空間效率和查詢時間都遠遠超過通常的算法,缺點是有必定的誤識別率和刪除困難。
Bloom-Filter算法的核心思想就是利用多個不一樣的Hash函數來解決「衝突」。
Hash存在一個衝突(碰撞)的問題,用同一個Hash獲得的兩個URL的值有可能相同。爲了減小衝突,咱們能夠多引入幾個Hash,若是經過其中的一個Hash值咱們得出某元素不在集合中,那麼該元素確定不在集合中。只有在全部的Hash函數告訴咱們該元素在集合中時,才能肯定該元素存在於集合中。這即是Bloom-Filter的基本思想。
Bloom-Filter通常用於在大數據量的集合中斷定某元素是否存在。
3、緩存預熱
緩存預熱這個應該是一個比較常見的概念,相信不少小夥伴都應該能夠很容易的理解,緩存預熱就是系統上線後,將相關的緩存數據直接加載到緩存系統。這樣就能夠避免在用戶請求的時候,先查詢數據庫,而後再將數據緩存的問題!用戶直接查詢事先被預熱的緩存數據!
解決思路:
一、直接寫個緩存刷新頁面,上線時手工操做下;
二、數據量不大,能夠在項目啓動的時候自動進行加載;
三、定時刷新緩存
4、緩存更新
除了緩存服務器自帶的緩存失效策略以外(Redis默認的有6中策略可供選擇),咱們還能夠根據具體的業務需求進行自定義的緩存淘汰,常見的策略有兩種:
(1)定時去清理過時的緩存;
(2)當有用戶請求過來時,再判斷這個請求所用到的緩存是否過時,過時的話就去底層系統獲得新數據並更新緩存。
二者各有優劣,第一種的缺點是維護大量緩存的key是比較麻煩的,第二種的缺點就是每次用戶請求過來都要判斷緩存失效,邏輯相對比較複雜!具體用哪一種方案,你們能夠根據本身的應用場景來權衡
5、緩存降級
當訪問量劇增、服務出現問題(如響應時間慢或不響應)或非核心服務影響到核心流程的性能時,仍然須要保證服務仍是可用的,即便是有損服務。系統能夠根據一些關鍵數據進行自動降級,也能夠配置開關實現人工降級。
降級的最終目的是保證核心服務可用,即便是有損的。並且有些服務是沒法降級的(如加入購物車、結算)。以參考日誌級別設置預案:
(1)通常:好比有些服務偶爾由於網絡抖動或者服務正在上線而超時,能夠自動降級;
(2)警告:有些服務在一段時間內成功率有波動(如在95~100%之間),能夠自動降級或人工降級,併發送告警;
(3)錯誤:好比可用率低於90%,或者數據庫鏈接池被打爆了,或者訪問量忽然猛增到系統能承受的最大閥值,此時能夠根據狀況自動降級或者人工降級;
(4)嚴重錯誤:好比由於特殊緣由數據錯誤了,此時須要緊急人工降級。服務降級的目的,是爲了防止Redis服務故障,致使數據庫跟着一塊兒發生雪崩問題。所以,對於不重要的緩存數據,能夠採起服務降級策略,例如一個比較常見的作法就是,Redis出現問題,不去數據庫查詢,而是直接返回默認值給用戶sql
十一、熱點數據和冷數據是什麼
熱點數據,緩存纔有價值
對於冷數據而言,大部分數據可能尚未再次訪問到就已經被擠出內存,不只佔用內存,並且價值不大。頻繁修改的數據,看狀況考慮使用緩存
對於上面兩個例子,壽星列表、導航信息都存在一個特色,就是信息修改頻率不高,讀取一般很是高的場景。
對於熱點數據,好比咱們的某IM產品,生日祝福模塊,當天的壽星列表,緩存之後可能讀取數十萬次。再舉個例子,某導航產品,咱們將導航信息,緩存之後可能讀取數百萬次。
數據更新前至少讀取兩次,緩存纔有意義。這個是最基本的策略,若是緩存尚未起做用就失效了,那就沒有太大價值了。
那存不存在,修改頻率很高,可是又不得不考慮緩存的場景呢?有!好比,這個讀取接口對數據庫的壓力很大,可是又是熱點數據,這個時候就須要考慮經過緩存手段,減小數據庫的壓力,好比咱們的某助手產品的,點贊數,收藏數,分享數等是很是典型的熱點數據,可是又不斷變化,此時就須要將數據同步保存到Redis緩存,減小數據庫壓力數據庫
十二、單線程的redis爲何這麼快
- 純內存操做
- 單線程操做,避免了頻繁的上下文切換
- 採用了非阻塞I/O多路複用機制
1三、redis的數據類型,以及每種數據類型的使用場景
一共五種
- String
這個其實沒啥好說的,最常規的set/get操做,value能夠是String也能夠是數字。通常作一些複雜的計數功能的緩存。 - hash
這裏value存放的是結構化的對象,比較方便的就是操做其中的某個字段。博主在作單點登陸的時候,就是用這種數據結構存儲用戶信息, 以cookieId做爲key,設置30分鐘爲緩存過時時間,能很好的模擬出相似session的效果。 - list
使用List的數據結構,能夠作簡單的消息隊列的功能。另外還有一個就是,能夠利用lrange命令,作基於redis的分頁功能,性能極佳,用戶體驗好。本人還用一個場景,很合適—取行情信息。就也是個生產者和消費者的場景。LIST能夠很好的完成排隊,先進先出的原則。 - set
由於set堆放的是一堆不重複值的集合。因此能夠作全局去重的功能。爲何不用JVM自帶的Set進行去重?由於咱們的系統通常都是集羣部 署,使用JVM自帶的Set,比較麻煩,難道爲了一個作一個全局去重,再起一個公共服務,太麻煩了。
另外,就是利用交集、並集、差集等操做,能夠計算共同喜愛,所有的喜愛,本身獨有的喜愛等功能。 - sorted set
sorted set多了一個權重參數score,集合中的元素可以按score進行排列。能夠作排行榜應用,取TOP N操做
1四、redis的過時策略以及內存淘汰機制
redis採用的是按期刪除+惰性刪除策略。
爲何不用定時刪除策略?
定時刪除,用一個定時器來負責監視key,過時則自動刪除。雖然內存及時釋放,可是十分消耗CPU資源。在大併發請求下,CPU要將時間應用 在處理請求,而不是刪除key,所以沒有采用這一策略.
按期刪除+惰性刪除是如何工做的呢?
按期刪除,redis默認每一個100ms檢查,是否有過時的key,有過時key則刪除。須要說明的是,redis不是每一個100ms將全部的key檢查一次, 而是隨機抽取進行檢查(若是每隔100ms,所有key進行檢查,redis豈不是卡死)。所以,若是隻採用按期刪除策略,會致使不少key到時間沒有刪除。因而,惰性刪除派上用場。也就是說在你獲取某個key的時候,redis會檢查一下,這個key若是設置了過時時間那麼是否過時了? 若是過時了此時就會刪除。
採用按期刪除+惰性刪除就沒其餘問題了麼?
不是的,若是按期刪除沒刪除key。而後你也沒即時去請求key,也就是說惰性刪除也沒生效。這樣,redis的內存會愈來愈高。那麼就應該採用內存淘汰機制。在redis.conf中有一行配置
maxmemory-policy volatile-lru
該配置就是配內存淘汰策略的(什麼,你沒配過?好好檢討一下本身)
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(驅逐):禁止驅逐數據,新寫入操做會報錯
ps:若是沒有設置 expire 的key, 不知足先決條件(prerequisites); 那麼 volatile-lru, volatile-random 和volatile-ttl 策略的行爲, 和
noeviction(不刪除) 基本上一致
1五、Redis 常見性能問題和解決方案?
- Master 最好不要作任何持久化工做,如 RDB 內存快照和 AOF 日誌文件
- 若是數據比較重要,某個 Slave 開啓 AOF 備份數據,策略設置爲每秒同步一次
- 爲了主從複製的速度和鏈接的穩定性, Master 和 Slave 最好在同一個局域網內
- 儘可能避免在壓力很大的主庫上增長從庫
- 主從複製不要用圖狀結構,用單向鏈表結構更爲穩定,即: Master <- Slave1 <- Slave2 <-Slave3...
1六、爲何Redis的操做是原子性的,怎麼保證原子性的?
對於Redis而言,命令的原子性指的是:一個操做的不能夠再分,操做要麼執行,要麼不執行。
Redis的操做之因此是原子性的,是由於Redis是單線程的。
Redis自己提供的全部API都是原子操做,Redis中的事務實際上是要保證批量操做的原子性。 多個命令在併發中也是原子性的嗎?
不必定, 將get和set改爲單命令操做,incr 。使用Redis的事務,或者使用Redis+Lua==的方式實現。
1七、Redis事務
Redis事務功能是經過MULTI、EXEC、DISCARD和WATCH 四個原語實現的
Redis會將一個事務中的全部命令序列化,而後按順序執行。
1.redis 不支持回滾「Redis 在事務失敗時不進行回滾,而是繼續執行餘下的命令」, 因此 Redis 的內部能夠保持簡單且快速。
2. 若是在一個事務中的命令出現錯誤,那麼全部的命令都不會執行;
3. 若是在一個事務中出現運行錯誤,那麼正確的命令會被執行。
- MULTI命令用於開啓一個事務,它老是返回OK。 MULTI執行以後,客戶端能夠繼續向服務器發送任意多條命令,這些命令不會當即被執行,而是被放到一個隊列中,當EXEC命令被調用時,全部隊列中的命令纔會被執行。 - EXEC:執行全部事務塊內的命令。返回事務塊內全部命令的返回值,按命令執行的前後順序排列。當操做被打斷時,返回空值 nil 。
- 經過調用DISCARD,客戶端能夠清空事務隊列,並放棄執行事務, 而且客戶端會從事務狀態中退出。
- WATCH 命令能夠爲 Redis 事務提供 check-and-set (CAS)行爲。 能夠監控一個或多個鍵,一旦其中有一個鍵被修改(或刪除),以後的事務就不會執行,監控一直持續到EXEC命令
1八、Redis 的持久化機制是什麼?各自的優缺點?
Redis 提供兩種持久化機制 RDB 和 AOF 機制:
RDBRedis DataBase)持久化方式: 是指用數據集快照的方式半持久化模式)記錄 redis 數據庫的全部鍵值對,在某個時間點將數據寫入一個臨時文件,持久化結束後,用這個臨時文件替換上次持久化的文件,達到數據恢復。
優勢:
- 只有一個文件 dump.rdb,方便持久化。
- 容災性好,一個文件能夠保存到安全的磁盤。
- 性能最大化,fork 子進程來完成寫操做,讓主進程繼續處理命令,因此是 IO最大化。使用單獨子進程來進行持久化,主進程不會進行任何 IO 操做,保證了 redis的高性能) 4.相對於數據集大時,比 AOF 的啓動效率更高。
缺點:
- 數據安全性低。RDB 是間隔一段時間進行持久化,若是持久化之間 redis 發生故障,會發生數據丟失。因此這種方式更適合數據要求不嚴謹的時候).
AOFAppend-only file)持久化方式: 是指全部的命令行記錄以 redis 命令請求協議的格式徹底持久化存儲)保存爲 aof 文件。
優勢:
- 數據安全,aof 持久化能夠配置 appendfsync 屬性,有 always,每進行一次命令操做就記錄到 aof 文件中一次。
- 經過 append 模式寫文件,即便中途服務器宕機,能夠經過 redis-check-aof工具解決數據一致性問題。
- AOF 機制的 rewrite 模式。AOF 文件沒被 rewrite 以前(文件過大時會對命令進行合併重寫),能夠刪除其中的某些命令(好比誤操做的 flushall))
缺點:
- AOF 文件比 RDB 文件大,且恢復速度慢。
- 數據集大的時候,比 rdb 啓動效率低。
1九、Redis 常見性能問題和解決方案:
- Master 最好不要寫內存快照,若是 Master 寫內存快照,save 命令調度 rdbSave函數,會阻塞主線程的工做,當快照比較大時對性能影響是很是大的,會間斷性暫停服務
- 若是數據比較重要,某個 Slave 開啓 AOF 備份數據,策略設置爲每秒同步一三、爲了主從複製的速度和鏈接的穩定性,Master 和 Slave
最好在同一個局域網 - 儘可能避免在壓力很大的主庫上增長從
- 主從複製不要用圖狀結構,用單向鏈表結構更爲穩定,即:Master <- Slave1<- Slave2 <- Slave3…這樣的結構方便解決單點故障問題, 實現 Slave 對 Master的替換。若是 Master 掛了,能夠馬上啓用 Slave1 作 Master,其餘不變。
20、redis 過時鍵的刪除策略?
- 定時刪除:在設置鍵的過時時間的同時,建立一個定時器 timer). 讓定時器在鍵的過時時間來臨時,當即執行對鍵的刪除操做。
- 惰性刪除:聽任鍵過時無論,可是每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過時,若是過時的話,就刪除該鍵;若是沒有過時,就返回該鍵。
- 按期刪除:每隔一段時間程序就對數據庫進行一次檢查,刪除裏面的過時鍵。至於要刪除多少過時鍵,以及要檢查多少個數據庫,則由算法決定。
2一、Redis 的回收策略(淘汰策略)(重複)?
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(驅逐):禁止驅逐數據
注意這裏的 6 種機制,volatile 和 allkeys 規定了是對已設置過時時間的數據集淘汰數據仍是從所有數據集淘汰數據,後面的 lru、ttl 以及 random 是三種不一樣的淘汰策略,再加上一種 no-enviction 永不回收的策略
使用策略規則:
- 若是數據呈現冪律分佈,也就是一部分數據訪問頻率高,一部分數據訪問頻率低,則使用 allkeys-lru
- 若是數據呈現平等分佈,也就是全部的數據訪問頻率都相同,則使用allkey
2二、爲何 edis 須要把全部數據放到內存中?
Redis 爲了達到最快的讀寫速度將數據都讀到內存中,並經過異步的方式將數據寫入磁盤。因此 redis 具備快速和數據持久化的特徵。若是不將數據放在內存中,磁盤 I/O 速度爲嚴重影響 redis 的性能。在內存愈來愈便宜的今,redis 將會愈來愈受歡迎。若是設置了最大使用的內存,則數據已有記錄數達到內存限值後不能繼續插入新值。
2三、Redis 的同步機制瞭解麼?
Redis 可使用主從同步,從從同步。第一次同步時,主節點作一次 bgsave,並同時將後續修改操做記錄到內存 buffer,待完成後將 rdb 文件全量同步到複製節點,複製節點接受完成後將 rdb 鏡像加載到內存。加載完成後,再通知主節點將期間修改的操做記錄同步到複製節點進行重放就完成了同步過程。
2四、Pipeline 有什麼好處,爲何要用 pipeline?
能夠將屢次 IO 往返的時間縮減爲一次,前提是 pipeline 執行的指令之間沒有因果相關性。使用 redis-benchmark 進行壓測的時候能夠發現影響 redis 的 QPS峯值的一個重要因素是 pipeline 批次指令的數目。
2五、是否使用過 Redis 集羣,集羣的原理是什麼?
- Redis Sentinal 着眼於高可用,在 master 宕機時會自動將 slave 提高爲master,繼續提供服務。
- Redis Cluster 着眼於擴展性,在單個 redis 內存不足時,使用 Cluster 進行分片存儲。]]>Redis面試題X50,全網最全(下)http://www.cnblogs.com/cxyxy/archive/2020/07/06/13254800.htmldc:creator程序員小羊</dc:creator>程序員小羊Mon, 06 Jul 2020 06:57:00 GMThttp://www.cnblogs.com/cxyxy/archive/2020/07/06/13254800.html<![CDATA[> 歡迎關注
CSDN:程序員小羊
微信公衆號:程序員小羊目錄
- 一、什麼是 Redis?
- 二、Redis 與其餘 key-value 存儲有什麼不一樣?
- 三、Redis 的數據類型?
- 四、使用 Redis 有哪些好處?
- 五、Redis 相比 Memcached 有哪些優點?
- 六、Memcache 與 Redis 的區別都有哪些?
- 七、Redis 是單進程單線程的?
- 八、一個字符串類型的值能存儲最大容量是多少?
- 九、Redis持久化機制
- 十、緩存雪崩、緩存穿透、緩存預熱、緩存更新、緩存降級等問題
- 十一、熱點數據和冷數據是什麼
- 十二、單線程的redis爲何這麼快
- 1三、redis的數據類型,以及每種數據類型的使用場景
- 1四、redis的過時策略以及內存淘汰機制
- 1五、Redis 常見性能問題和解決方案?
- 1六、爲何Redis的操做是原子性的,怎麼保證原子性的?
- 1七、Redis事務
- 1八、Redis 的持久化機制是什麼?各自的優缺點?
- 1九、Redis 常見性能問題和解決方案:
- 20、redis 過時鍵的刪除策略?
- 2一、Redis 的回收策略(淘汰策略)(重複)?
- 2二、爲何 edis 須要把全部數據放到內存中?
- 2三、Redis 的同步機制瞭解麼?
- 2四、Pipeline 有什麼好處,爲何要用 pipeline?
- 2五、是否使用過 Redis 集羣,集羣的原理是什麼?
- 2五、是否使用過 Redis 集羣,集羣的原理是什麼?
- 2六、Redis 集羣方案什麼狀況下會致使整個集羣不可用?
- 2七、Redis 支持的 Java 客戶端都有哪些?官方推薦用哪一個?
- 2八、Jedis 與 Redisson 對比有什麼優缺點?
- 2九、Redis 如何設置密碼及驗證密碼?
- 30、說說 Redis 哈希槽的概念?
- 3一、Redis 集羣的主從複製模型是怎樣的?
- 3二、Redis 集羣會有寫操做丟失嗎?爲何?
- 3三、Redis 集羣之間是如何複製的?
- 3四、Redis 集羣最大節點個數是多少?
- 3五、Redis 集羣如何選擇數據庫?
- 3六、怎麼測試 Redis 的連通性?
- 3七、怎麼理解 Redis 事務?
- 3八、Redis 事務相關的命令有哪幾個?
- 3九、Redis key 的過時時間和永久有效分別怎麼設置?
- 4一、Redis 回收進程如何工做的?
- 4二、都有哪些辦法能夠下降 Redis 的內存使用狀況呢?
- 4三、Redis 的內存用完了會發生什麼?
- 4四、一個 Redis 實例最多能存放多少的 keys?List、Set、Sorted Set 他們最多能存放多少元素
- 4五、MySQL 裏有 2000w 數據,redis 中只存 20w 的數據,如何保證 redis 中的數據都是熱點數據?
- 4六、Redis 最適合的場景?
- 4七、假如 Redis 裏面有 1 億個 key,其中有 10w 個 key 是以某個固定的已知的前綴開頭的,若是將它們所有找出來?
- 4八、若是有大量的 key 須要設置同一時間過時,通常須要注意什麼?
- 4九、使用過 Redis 作異步隊列麼,你是怎麼用的?
- 50、使用過 Redis 分佈式鎖麼,它是什麼回事
2五、是否使用過 Redis 集羣,集羣的原理是什麼?
- Redis Sentinal 着眼於高可用,在 master 宕機時會自動將 slave 提高爲master,繼續提供服務。
- Redis Cluster 着眼於擴展性,在單個 redis 內存不足時,使用 Cluster 進行分片存儲。
2六、Redis 集羣方案什麼狀況下會致使整個集羣不可用?
答:有 A,B,C 三個節點的集羣,在沒有複製模型的狀況下,若是節點 B 失敗了,那麼整個集羣就會覺得缺乏 5501-11000 這個範圍的槽而不可用。
2七、Redis 支持的 Java 客戶端都有哪些?官方推薦用哪一個?
Redisson、Jedis、lettuce 等等,官方推薦使用 Redisson。
2八、Jedis 與 Redisson 對比有什麼優缺點?
Jedis 是 Redis 的 Java 實現的客戶端,其 API 提供了比較全面的 Redis 命令的支持;Redisson 實現了分佈式和可擴展的 Java 數據結構,和
Jedis 相比,功能較爲簡單,不支持字符串操做,不支持排序、事務、管道、分區等 Redis 特性。Redisson 的宗旨是促進使用者對 Redis 的關注分離,從而讓使用者可以將精力更集中地放在處理業務邏輯上
2九、Redis 如何設置密碼及驗證密碼?
設置密碼:config set requirepass 123456
受權密碼:auth 123456
30、說說 Redis 哈希槽的概念?
Redis 集羣沒有使用一致性 hash,而是引入了哈希槽的概念,Redis 集羣有16384 個哈希槽,每一個 key 經過 CRC16 校驗後對 16384 取模來決定放置哪一個槽,集羣的每一個節點負責一部分 hash 槽。
3一、Redis 集羣的主從複製模型是怎樣的?
爲了使在部分節點失敗或者大部分節點沒法通訊的狀況下集羣仍然可用,因此集羣使用了主從複製模型,每一個節點都會有 N-1 個複製品.
3二、Redis 集羣會有寫操做丟失嗎?爲何?
Redis 並不能保證數據的強一致性,這意味這在實際中集羣在特定的條件下可能會丟失寫操做。
3三、Redis 集羣之間是如何複製的?
異步複製
3四、Redis 集羣最大節點個數是多少?
16384 個
3五、Redis 集羣如何選擇數據庫?
Redis 集羣目前沒法作數據庫選擇,默認在 0 數據庫。
3六、怎麼測試 Redis 的連通性?
使用 ping 命令
3七、怎麼理解 Redis 事務?
- 事務是一個單獨的隔離操做:事務中的全部命令都會序列化、按順序地執行。事務在執行的過程當中,不會被其餘客戶端發送來的命令請求所打斷。
- 事務是一個原子操做:事務中的命令要麼所有被執行,要麼所有都不執行。
3八、Redis 事務相關的命令有哪幾個?
MULTI、EXEC、DISCARD、WATCH
3九、Redis key 的過時時間和永久有效分別怎麼設置?
EXPIRE 和 PERSIST 命令。
40、Redis 如何作內存優化?
儘量使用散列表(hashes),散列表(是說散列表裏面存儲的數少)使用的內存很是小,因此你應該儘量的將你的數據模型抽象到一個散列表裏面。好比你的 web 系統中有一個用戶對象,不要爲這個用戶的名稱,姓氏,郵箱,密碼設置單獨的 key,而是應該把這個用戶的全部信息存儲到一張散列表裏面.
4一、Redis 回收進程如何工做的?
一個客戶端運行了新的命令,添加了新的數據。Redi 檢查內存使用狀況,若是大於 maxmemory 的限制, 則根據設定好的策略進行回收。一個新的命令被執行,等等。因此咱們不斷地穿越內存限制的邊界,經過不斷達到邊界而後不斷地回收回到邊界如下。若是一個命令的結果致使大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。
4二、都有哪些辦法能夠下降 Redis 的內存使用狀況呢?
若是你使用的是 32 位的 Redis 實例,能夠好好利用 Hash,list,sorted set,set等集合類型數據,由於一般狀況下不少小的 Key-Value 能夠用更緊湊的方式存放到一塊兒。
4三、Redis 的內存用完了會發生什麼?
若是達到設置的上限,Redis 的寫命令會返回錯誤信息(可是讀命令還能夠正常返回。)或者你能夠將 Redis 當緩存來使用配置淘汰機制, 當 Redis 達到內存上限時會沖刷掉舊的內容。
4四、一個 Redis 實例最多能存放多少的 keys?List、Set、Sorted Set 他們最多能存放多少元素
理論上 Redis 能夠處理多達 232 的 keys,而且在實際中進行了測試,每一個實例至少存放了 2 億 5 千萬的 keys。咱們正在測試一些較大的值。任何 list、set、和 sorted set 均可以放 232 個元素。換句話說,Redis 的存儲極限是系統中的可用內存值。
4五、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(驅逐):禁止驅逐數據
4六、Redis 最適合的場景?
一、會話緩存(Session Cache)
最經常使用的一種使用 Redis 的情景是會話緩存(session cache)。用 Redis 緩存會話比其餘存儲(如 Memcached)的優點在於:Redis 提供持久化。當維護一個不是嚴格要求一致性的緩存時,若是用戶的購物車信息所有丟失,大部分人都會不高興的,如今,他們還會這樣嗎? 幸運的是,隨着 Redis 這些年的改進,很容
易找到怎麼恰當的使用 Redis 來緩存會話的文檔。甚至廣爲人知的商業平臺Magento 也提供 Redis 的插件。
二、全頁緩存(FPC)
除基本的會話 token 以外,Redis 還提供很簡便的 FPC 平臺。回到一致性問題,即便重啓了 Redis 實例,由於有磁盤的持久化,用戶也不會看到頁面加載速度的降低,這是一個極大改進,相似 PHP 本地 FPC。 再次以 agento 爲例,Magento提供一個插件來使用 Redis 做爲全頁緩存後端。 此外,對 WordPress 的用戶來講,Pantheon 有一個很是好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面。
三、隊列
Reids 在內存存儲引擎領域的一大優勢是提供 list 和 set 操做,這使得 Redis能做爲一個很好的消息隊列平臺來使用。Redis 做爲隊列使用的操做,就相似於本地程序語言(如 Python)對 list 的 push/pop 操做。 若是你快速的在 Google中搜索「Redis queues」,你立刻就能找到大量的開源項目,這些項目的目的就是利用 Redis 建立很是好的後端工具,以知足各類隊列需求。例如,Celery 有一個後臺就是使用 Redis 做爲 broker,你能夠從這裏去查看。
4,排行榜/計數器
Redis 在內存中對數字進行遞增或遞減的操做實現的很是好。集合(Set)和有序集合(Sorted Set)也使得咱們在執行這些操做的時候變的很是簡單,Redis 只是正好提供了這兩種數據結構。因此,咱們要從排序集合中獲取到排名最靠前的 10個用戶–咱們稱之爲「user_scores」, 咱們只須要像下面同樣執行便可: 固然,這是假定你是根據你用戶的分數作遞增的排序。若是你想返回用戶及用戶的分數,你須要這樣執行: ZRANGE user_scores 0 10 WITHSCORES Agora Games 就是一個很好的例子,用 Ruby 實現的,它的排行榜就是使用 Redis 來存儲數據的,
你能夠在這裏看到。
五、發佈/訂閱
最後(但確定不是最不重要的)是 Redis 的發佈/訂閱功能。發佈/訂閱的使用場景確實很是多。我已看見人們在社交網絡鏈接中使用,還可做爲基於發佈/訂閱的腳本觸發器,甚至用 Redis 的發佈/訂閱功能來創建聊天系統!
4七、假如 Redis 裏面有 1 億個 key,其中有 10w 個 key 是以某個固定的已知的前綴開頭的,若是將它們所有找出來?
使用 keys 指令能夠掃出指定模式的 key 列表。 對方接着追問:若是這個 redis 正在給線上的業務提供服務,那使用 keys 指令會有什麼問題?
這個時候你要回答 redis 關鍵的一個特性:redis 的單線程的。keys 指令會致使線程阻塞一段時間,線上服務會停頓,直到指令執行完畢, 服務才能恢復。這個時候可使用 scan 指令,scan 指令能夠無阻塞的提取出指定模式的 key 列表,可是會有必定的重複機率,在客戶端作一次去重就能夠了,可是總體所花費的時間會比直接用 keys 指令長。
4八、若是有大量的 key 須要設置同一時間過時,通常須要注意什麼?
若是大量的 key 過時時間設置的過於集中,到過時的那個時間點,redis 可能會出現短暫的卡頓現象。通常須要在時間上加一個隨機值,使得過時時間分散一些。
4九、使用過 Redis 作異步隊列麼,你是怎麼用的?
通常使用 list 結構做爲隊列,rpush 生產消息,lpop 消費消息。當 lpop 沒有消息的時候,要適當 sleep 一會再重試。
若是對方追問可不能夠不用 sleep 呢?
list 還有個指令叫 blpop,在沒有消息的時候,它會阻塞住直到消息到來。若是對方追問能不能生產一次消費屢次呢?使用 pub/sub 主題訂閱者模式,能夠實現1:N 的消息隊列。
若是對方追問 pub/sub 有什麼缺點?
在消費者下線的狀況下,生產的消息會丟失,得使用專業的消息隊列如 RabbitMQ等。
若是對方追問 redis 如何實現延時隊列?
我估計如今你很想把面試官一棒打死若是你手上有一根棒球棍的話,怎麼問的這麼詳細。可是你很剋制,而後神態自若的回答道:使用sortedset,拿時間戳做爲score,消息內容做爲 key 調用 zadd 來生產消息,消費者用 zrangebyscore 指令獲取 N 秒以前的數據輪詢進行處理。到這裏,面試官暗地裏已經對你豎起了大拇指。可是他不知道的是此刻你卻豎起了中指,在椅子背後。
50、使用過 Redis 分佈式鎖麼,它是什麼回事
先拿 setnx 來爭搶鎖,搶到以後,再用 expire 給鎖加一個過時時間防止鎖忘記了釋放。
這時候對方會告訴你說你回答得不錯,而後接着問若是在 setnx 以後執行 expire以前進程意外 crash 或者要重啓維護了,那會怎麼樣?
這時候你要給予驚訝的反饋:唉,是喔,這個鎖就永遠得不到釋放了。緊接着你須要抓一抓本身得腦殼,故做思考片刻,好像接下來的結果是你主動思考出來的,而後回答:我記得 set 指令有很是複雜的參數,這個應該是能夠同時把 setnx 和expire 合成一條指令來用的!對方這時會顯露笑容,內心開始默唸:摁,這小子還不錯。
歡迎關注 CSDN:程序員小羊 微信公衆號:程序員小羊 博客園:程序員小羊