1 什么是redis
Redis 是一個使用 C 語言寫成的,開源的 key-value 數據庫。。和Memcached類似,它支持存儲的value
類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和
hash(哈希類型)。
這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。
在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。
區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上
實現了master-slave(主從)同步。目前,Vmware在資助着redis項目的開發和維護。
2 Redis與Memcached的區別與比較
1 、Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
memcache支持簡單的數據類型,String。
2 、Redis支持數據的備份,即master-slave模式的數據備份。
3 、Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用,而Memecache把數據全部存在內存之中.
4、 redis的速度比memcached快很多.
5、Memcached是多線程,非阻塞IO復用的網絡模型;Redis使用單線程的IO復用模型。
3 Redis與Memcached的選擇
終極策略: 使用Redis的String類型做的事,都可以用Memcached替換,以此換取更好的性能提升; 除此以外,優先考慮Redis;
4 使用redis 有哪些好處
(1) 速度快,因為數據存在內存中,類似於HashMap,HashMap的優勢就是查找和操作的時間復雜度都是O(1)
(2)支持豐富數據類型,支持string,list,set,sorted set,hash
(3) 支持事務 :redis對事務是部分支持的,如果是在入隊時報錯,那么都不會執行;在非入隊時報錯,那么成功的就會成功執行。
(4) 豐富的特性:可用於緩存,消息,按key設置過期時間,過期后將會自動刪除.
5 Redis常見數據結構使用場景
1. String
常用命令: set,get,decr,incr,mget 等。
String數據結構是簡單的key-value類型,value其實不僅可以是String,也可以是數字。 常規key-value緩存應用; 常規計數:微博數,粉絲數等。
2.Hash
常用命令: hget,hset,hgetall 等。
Hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。 比如我們可以Hash數據結構來存儲用戶信息,商品信息等等。
3.List
常用命令: lpush,rpush,lpop,rpop,lrange等
list就是鏈表,Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如微博的關注列表,粉絲列表,最新消息排行等功能都可以用Redis的list結構來實現。
Redis list的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷。
4.Set
常用命令: sadd,spop,smembers,sunion 等
set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動排重的。 當你需要存儲一個列表數據,又不希望出現重復數據時,set是一個很好的選擇,並且set提供了判斷某個成員是否在一個set集合內的重要接口,這個也是list所不能提供的。
在微博應用中,可以將一個用戶所有的關注人存在一個集合中,將其所有粉絲存在一個集合。Redis可以非常方便的實現如共同關注、共同喜好、二度好友等功能。
5.Sorted Set
常用命令: zadd,zrange,zrem,zcard等
和set相比,sorted set增加了一個權重參數score,使得集合中的元素能夠按score進行有序排列。
舉例: 在直播系統中,實時排行信息包含直播間在線用戶列表,各種禮物排行榜,彈幕消息(可以理解為按消息維度的消息排行榜)等信息,適合使用Redis中的SortedSet結構進行存儲。
6 MySQL里有2000w數據,Redis中只存20w的數據,如何保證Redis中的數據都是熱點數據(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(驅逐):禁止驅逐數據
數據清除機制
- 惰性清除
- 定時清除
- 立即清除
7 Redis的並發競爭問題如何解決?
Redis為單進程單線程模式,采用隊列模式將並發訪問變為串行訪問。Redis本身沒有鎖的概念,Redis對於多個客戶端連接並不存在競爭,但是在Jedis客戶端對Redis進行並發訪問時會發生連接超時、數據轉換錯誤、阻塞、客戶端關閉連接等問題,這些問題均是由於客戶端連接混亂造成。對此有2種解決方法:
1.客戶端角度,為保證每個客戶端間正常有序與Redis進行通信,對連接進行池化,同時對客戶端讀寫Redis操作采用內部鎖synchronized。 2.服務器角度,利用setnx實現鎖。
注:對於第一種,需要應用程序自己處理資源的同步,可以使用的方法比較通俗,可以使用synchronized也可以使用lock;第二種需要用到Redis的setnx命令,但是需要注意一些問題。
8 Redis回收進程如何工作的? Redis回收使用的是什么算法?
9 Redis 大量數據插入
10 Redis 分區的優勢、不足以及分區類型
11 Redis持久化數據和緩存怎么做擴容?
12 redis 常見性能問題和解決方案
- Master最好不要做任何持久化工作,如RDB內存快照和AOF日志文件
- 如果數據比較重要,某個Slave開啟AOF備份數據,策略設置為每秒同步一次
- 為了主從復制的速度和連接的穩定性,Master和Slave最好在同一個局域網內
- 盡量避免在壓力很大的主庫上增加從庫
13 Redis與消息隊列
不要使用redis去做消息隊列,這不是redis的設計目標。
轉 :消息隊列面試題
14、Redis支持哪幾種數據類型?
String、List、Set、Sorted Set、hashes
15、Redis主要消耗什么物理資源?
內存。
16、Redis的全稱是什么?
Remote Dictionary Server。
17 Redis官方為什么不提供Windows版本?
因為目前Linux版本已經相當穩定,而且用戶量很大,無需開發windows版本,反而會帶來兼容性等問題。
18、一個字符串類型的值能存儲最大容量是多少?
512M
19、為什么Redis需要把所有數據放到內存中?
Redis為了達到最快的讀寫速度將數據都讀到內存中,並通過異步的方式將數據寫入磁盤。
所以redis具有快速和數據持久化的特征。如果不將數據放在內存中,磁盤I/O速度為嚴重影響redis的性能。
在內存越來越便宜的今天,redis將會越來越受歡迎。 如果設置了最大使用的內存,則數據已有記錄數達到內存限值后不能繼續插入新值。
20、Redis集群方案應該怎么做?都有哪些方案?
1.codis。
目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在 節點數量改變情況下,舊節點數據可恢復到新hash節點。
2.redis cluster3.0自帶的集群,特點在於他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持節點設置從節點。具體看官方文檔介紹。
3.在業務代碼層實現,起幾個毫無關聯的redis實例,在代碼層,對key 進行hash計算,然后去對應的redis實例操作數據。 這種方式對hash層代碼要求比較高,考慮部分包括,節點失效后的替代算法方案,數據震盪后的自動腳本恢復,實例的監控,等等。
21、Redis集群方案什么情況下會導致整個集群不可用?
有A,B,C三個節點的集群,在沒有復制模型的情況下,如果節點B失敗了,那么整個集群就會以為缺少5501-11000這個范圍的槽而不可用。
22 Redis有哪些適合的場景?
(1)會話緩存(Session Cache)
最常用的一種使用Redis的情景是會話緩存(session cache)。用Redis緩存會話比其他存儲(如Memcached)的優勢在於:Redis提供持久化。當維護一個不是嚴格要求一致性的緩存時,如果用戶的購物車信息全部丟失,大部分人都會不高興的,現在,他們還會這樣嗎?
幸運的是,隨着 Redis 這些年的改進,很容易找到怎么恰當的使用Redis來緩存會話的文檔。甚至廣為人知的商業平台Magento也提供Redis的插件。
(2)全頁緩存(FPC)
除基本的會話token之外,Redis還提供很簡便的FPC平台。回到一致性問題,即使重啟了Redis實例,因為有磁盤的持久化,用戶也不會看到頁面加載速度的下降,這是一個極大改進,類似PHP本地FPC。
再次以Magento為例,Magento提供一個插件來使用Redis作為全頁緩存后端。
此外,對WordPress的用戶來說,Pantheon有一個非常好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面。
(3)隊列
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來存儲數據的,你可以在這里看到。
(5)發布/訂閱
最后(但肯定不是最不重要的)是Redis的發布/訂閱功能。發布/訂閱的使用場景確實非常多。我已看見人們在社交網絡連接中使用,還可作為基於發布/訂閱的腳本觸發器,甚至用Redis的發布/訂閱功能來建立聊天系統!
24 Redis支持的Java客戶端都有哪些?官方推薦用哪個?
Redisson、Jedis、lettuce等等,官方推薦使用Redisson。
25、Redis和Redisson有什么關系?
Redisson是一個高級的分布式協調Redis客服端,能幫助用戶在分布式環境中輕松實現一些Java的對象.
26 Jedis與Redisson對比有什么優缺點?
Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支持;
Redisson實現了分布式和可擴展的Java數據結構,和Jedis相比,功能較為簡單,不支持字符串操作,不支持排序、事務、管道、分區等Redis特性。Redisson的宗旨是促進使用者對Redis的關注分離,從而讓使用者能夠將精力更集中地放在處理業務邏輯上。
27 Redis如何設置密碼及驗證密碼?
設置密碼:config set requirepass 123456
授權密碼:auth 123456
28、說說Redis哈希槽的概念?
Redis集群沒有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384個哈希槽,每個key通過CRC16校驗后對16384取模來決定放置哪個槽,集群的每個節點負責一部分hash槽。
29、Redis集群的主從復制模型是怎樣的?
為了使在部分節點失敗或者大部分節點無法通信的情況下集群仍然可用,所以集群使用了主從復制模型,每個節點都會有N-1個復制品.
30、Redis集群會有寫操作丟失嗎?為什么?
Redis並不能保證數據的強一致性,這意味這在實際中集群在特定的條件下可能會丟失寫操作。
31、Redis集群之間是如何復制的?
異步復制
32、Redis集群如何選擇數據庫?
Redis集群目前無法做數據庫選擇,默認在0數據庫。
24、怎么測試Redis的連通性?
PING
25、Redis中的管道有什么用?
(一次連接數據庫,批量執行數據庫操作)
一次請求/響應服務器能實現處理新的請求即使舊的請求還未被響應。這樣就可以將多個命令發送到服務器,而不用等待回復,最后在一個步驟中讀取該答復。
這就是管道(pipelining),是一種幾十年來廣泛使用的技術。例如許多POP3協議已經實現支持這個功能,大大加快了從服務器下載新郵件的過程。
26、怎么理解Redis事務?
redis 是半事務,
1 語法就有問題。(這種exec時報錯,所有語句都不執行)
2 語法本身沒有錯,但使用對象有問題。比如zadd命令操作link對象,exec之后回執行正確的語句並跳過不適當的語句。
mysql 全事務
只要出錯就全部回滾
27、Redis事務相關的命令有哪幾個?
MULTI、EXEC、DISCARD、WATCH
28 Redis key的過期時間和永久有效分別怎么設置?
EXPIRE和PERSIST命令。
29、Redis如何做內存優化?
盡可能使用散列表(hashes),散列表(是說散列表里面存儲的數少)使用的內存非常小,所以你應該盡可能的將你的數據模型抽象到一個散列表里面。
比如你的web系統中有一個用戶對象,不要為這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而是應該把這個用戶的所有信息存儲到一張散列表里面。
30、Redis回收進程如何工作的?
一個客戶端運行了新的命令,添加了新的數據。
Redi檢查內存使用情況,如果大於maxmemory的限制, 則根據設定好的策略進行回收。
一個新的命令被執行,等等。
所以我們不斷地穿越內存限制的邊界,通過不斷達到邊界然后不斷地回收回到邊界以下。
如果一個命令的結果導致大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。
摘抄參考
https://juejin.im/post/5ad6e4066fb9a028d82c4b66
http://database.51cto.com/art/201809/583141.htm