本文包括:30 個 Redis 基礎知識;10個 Redis 架構和運維必懂的知識;Redis 調優、監控知識和10個具體應用難點。
本篇文檔已整理成pdf文檔,需要的同學文末自取
30 個 Redis 基礎知識
1、Redis支持哪幾種數據類型?
String、List、Set、Sorted Set、hashes
2、Redis主要消耗什么物理資源?
Redis是一種基于內存高性能的數據庫--- 主要依賴于內存
3、Redis有哪幾種數據淘汰策略?
noeviction:返回錯誤當內存限制達到并且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
allkeys-lru:嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
volatile-lru:嘗試回收最少使用的鍵(LRU),但僅限于在過期集合的鍵,使得新添加的數據有空間存放。
allkeys-random:回收隨機的鍵使得新添加的數據有空間存放。
volatile-random:回收隨機的鍵使得新添加的數據有空間存放,但僅限于在過期集合的鍵。
volatile-tt:回收在過期集合的鍵,并且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。
4、為什么Redis需要把所有數據放到內存中?
Redis為了達到最快的讀寫速度將數據都讀到內存中,并通過異步的方式將數據寫入磁盤。所以redis具有快速和數據持久化的特征。如果不將數據放在內存中,磁盤I/O速度為嚴重影響redis的性能。在內存越來越便宜的今天,redis將會越來越受歡迎。如果設置了最大使用的內存,則數據已有記錄數達到內存限值后不能繼續插入新值。
5、Redis集群方案應該怎么做?都有哪些方案?
twemproxy,大概概念是,它類似于一個代理方式,使用方法和普通redis無任何區別,設置好它下屬的多個redis實例后,使用時在本需要連接redis的地方改為連接twemproxy,它會以一個代理的身份接收請求并使用一致性hash算法,將請求轉接到具體redis,將結果再返回twemproxy。使用方式簡便(相對redis只需修改連接端口),對舊項目擴展的首選。問題:twemproxy自身單端口實例的壓力,使用一致性hash后,對redis節點數量改變時候的計算值的改變,數據無法自動移動到新的節點。
codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在 節點數量改變情況下,舊節點數據可恢復到新hash節點。
redis cluster3.0自帶的集群,特點在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持節點設置從節點。具體看官方文檔介紹。
在業務代碼層實現,起幾個毫無關聯的redis實例,在代碼層,對key 進行hash計算,然后去對應的redis實例操作數據。這種方式對hash層代碼要求比較高,考慮部分包括,節點失效后的替代算法方案,數據震蕩后的自動腳本恢復,實例的監控,等等。
6、Redis集群方案什么情況下會導致整個集群不可用?
有A,B,C三個節點的集群,在沒有復制模型的情況下,如果節點B失敗了,那么整個集群就會以為缺少5501-11000這個范圍的槽而不可用。
7、Redis如何設置密碼及驗證密碼?
設置密碼:config set requirepass 123456
授權密碼:auth 123456
8、說說Redis哈希槽的概念?
Redis集群沒有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384個哈希槽,每個key通過CRC16校驗后對16384取模來決定放置哪個槽,集群的每個節點負責一部分hash槽。
9、Redis集群的主從復制模型是怎樣的?
為了使在部分節點失敗或者大部分節點無法通信的情況下集群仍然可用,所以集群使用了主從復制模型,每個節點都會有N-1個復制品.
10、Redis集群會有寫操作丟失嗎?為什么?
Redis并不能保證數據的強一致性,這意味著在實際中集群在特定的條件下可能會丟失寫操作。
11、Redis集群之間是如何復制的?
異步復制
12、怎么理解Redis事務?
事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。
事務是一個原子操作:事務中的命令要么全部被執行,要么全部都不執行。
13、Redis事務相關的命令有哪幾個?
MULTI、EXEC、DISCARD、WATCH
14、Redis key的過期時間和永久有效分別怎么設置?
EXPIRE和PERSIST命令。
15、Redis如何做內存優化?
盡可能使用散列表(hashes),散列表(是說散列表里面存儲的數少)使用的內存非常小,所以你應該盡可能的將你的數據模型抽象到一個散列表里面。比如你的web系統中有一個用戶對象,不要為這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而是應該把這個用戶的所有信息存儲到一張散列表里面.
16、Redis回收進程如何工作的?
一個客戶端運行了新的命令,添加了新的數據。
Redi檢查內存使用情況,如果大于maxmemory的限制, 則根據設定好的策略進行回收。
一個新的命令被執行,等等。
所以我們不斷地穿越內存限制的邊界,通過不斷達到邊界然后不斷地回收回到邊界以下。
如果一個命令的結果導致大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。
17、Redis回收使用的是什么算法?
LRU算法
18、Redis如何做大量數據插入?
Redis2.6開始redis-cli支持一種新的被稱之為pipe mode的新模式用于執行大量數據插入工作。
19、為什么要做Redis分區?
分區可以讓Redis管理更大的內存,Redis將可以使用所有機器的內存。如果沒有分區,你最多只能使用一臺機器的內存。分區使Redis的計算能力通過簡單地增加計算機得到成倍提升,Redis的網絡帶寬也會隨著計算機和網卡的增加而成倍增長。
20、Redis持久化數據和緩存怎么做擴容?
如果Redis被當做緩存使用,使用一致性哈希實現動態擴容縮容。
如果Redis被當做一個持久化存儲使用,必須使用固定的keys-to-nodes映射關系,節點的數量一旦確定不能變化。否則的話(即Redis節點需要動態變化的情況),必須使用可以在運行時進行數據再平衡的一套系統,而當前只有Redis集群可以做到這樣。
21、分布式Redis是前期做還是后期規模上來了再做好?為什么?
既然Redis是如此的輕量(單實例只使用1M內存),為防止以后的擴容,最好的辦法就是一開始就啟動較多實例。即便你只有一臺服務器,你也可以一開始就讓Redis以分布式的方式運行,使用分區,在同一臺服務器上啟動多個實例。
一開始就多設置幾個Redis實例,例如32或者64個實例,對大多數用戶來說這操作起來可能比較麻煩,但是從長久來看做這點犧牲是值得的。
這樣的話,當你的數據不斷增長,需要更多的Redis服務器時,你需要做的就是僅僅將Redis實例從一臺服務遷移到另外一臺服務器而已(而不用考慮重新分區的問題)。一旦你添加了另一臺服務器,你需要將你一半的Redis實例從第一臺機器遷移到第二臺機器。
22、都有哪些辦法可以降低Redis的內存使用情況呢?
如果你使用的是32位的Redis實例,可以好好利用Hash,list,sorted set,set等集合類型數據,因為通常情況下很多小的Key-Value可以用更緊湊的方式存放到一起。
23、查看Redis使用情況及狀態信息用什么命令?
info
24、Redis的內存用完了會發生什么?
如果達到設置的上限,Redis的寫命令會返回錯誤信息(但是讀命令還可以正常返回。)或者你可以將Redis當緩存來使用配置淘汰機制,當Redis達到內存上限時會沖刷掉舊的內容。
25、Redis是單線程的,如何提高多核CPU的利用率?
可以在同一個服務器部署多個Redis的實例,并把他們當作不同的服務器來使用,在某些時候,無論如何一個服務器是不夠的, 所以,如果你想使用多個CPU,你可以考慮一下分片(shard)。
26、一個Redis實例最多能存放多少的keys?List、Set、Sorted Set他們最多能存放多少元素?
理論上Redis可以處理多達232的keys,并且在實際中進行了測試,每個實例至少存放了2億5千萬的keys。我們正在測試一些較大的值。
任何list、set、和sorted set都可以放232個元素。
換句話說,Redis的存儲極限是系統中的可用內存值。
27、Redis常見性能問題和解決方案?
(1) Master最好不要做任何持久化工作,如RDB內存快照和AOF日志文件
(2) 如果數據比較重要,某個Slave開啟AOF備份數據,策略設置為每秒同步一次
(3) 為了主從復制的速度和連接的穩定性,Master和Slave最好在同一個局域網內
(4) 盡量避免在壓力很大的主庫上增加從庫
(5) 主從復制不要用圖狀結構,用單向鏈表結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3…
這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。
28、Redis提供了哪幾種持久化方式?
RDB持久化方式能夠在指定的時間間隔能對你的數據進行快照存儲。
AOF持久化方式記錄每次對服務器寫的操作,當服務器重啟的時候會重新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫的操作到文件末尾。Redis還能對AOF文件進行后臺重寫,使得AOF文件的體積不至于過大。
如果你只希望你的數據在服務器運行的時候存在,你也可以不使用任何持久化方式。
你也可以同時開啟兩種持久化方式,在這種情況下,當redis重啟的時候會優先載入AOF文件來恢復原始的數據,因為在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整。
最重要的事情是了解RDB和AOF持久化方式的不同,讓我們以RDB持久化方式開始。
29、如何選擇合適的持久化方式?
一般來說, 如果想達到足以媲美PostgreSQL的數據安全性, 你應該同時使用兩種持久化功能。如果你非常關心你的數據, 但仍然可以承受數分鐘以內的數據丟失,那么你可以只使用RDB持久化。
有很多用戶都只使用AOF持久化,但并不推薦這種方式:因為定時生成RDB快照(snapshot)非常便于進行數據庫備份, 并且 RDB 恢復數據集的速度也要比AOF恢復的速度要快,除此之外, 使用RDB還可以避免之前提到的AOF程序的bug。
30、修改配置不重啟Redis會實時生效嗎?
針對運行實例,有許多配置選項可以通過 CONFIG SET 命令進行修改,而無需執行任何形式的重啟。從 Redis 2.2 開始,可以從 AOF 切換到 RDB 的快照持久性或其他方式而不需要重啟 Redis。檢索 ‘CONFIG GET *’ 命令獲取更多信息。
但偶爾重新啟動是必須的,如為升級 Redis 程序到新的版本,或者當你需要修改某些目前 CONFIG 命令還不支持的配置參數的時候。
10個 Redis 架構和運維必懂的知識
一、高可用相關
1、Redis 常用高可用架構有哪些?
Redis 高可用架構如下:
Redis Sentinel 集群 + 內網 DNS + 自定義腳本
Redis Sentinel 集群 + VIP + 自定義腳本
封裝客戶端直連 Redis Sentinel 端口
JedisSentinelPool,適合 Java
PHP 基于 phpredis 自行封裝
Redis Sentinel 集群 + Keepalived/Haproxy
Redis M/S + Keepalived
Redis Cluster
Twemproxy
Codis
2、Redis 高可用架構優劣對比?
—Redis Sentinel 集群 + 內網 DNS + 自定義腳本
優點:
秒級切換
腳本自定義,架構可控
對應用透明
缺點:
維護成本略高
依賴 DNS,存在解析延時
Sentinel 模式存在短時間的服務不可用
—Redis Sentinel 集群 + VIP + 自定義腳本
優點:
秒級切換
腳本自定義,架構可控
對應用透明
缺點:
維護成本略高
Sentinel 模式存在短時間的服務不可用
—封裝客戶端直連 Redis Sentinel 端口
優點:
服務探測故障及時
DBA 維護成本低
缺點:
依賴客戶端支持 Sentinel
Sentinel 服務器需要開放訪問權限
對應用有侵入性
—Redis Sentinel 集群 + Keepalived/Haproxy
優點:
秒級切換
對應用透明
缺點:
維護成本高
存在腦裂
Sentinel 模式存在短時間的服務不可用
—Redis M/S +Keepalived
優點:
秒級切換
對應用透明
部署簡單,維護成本低
缺點:
需要腳本實現切換功能
存在腦裂
(Redis Cluster、Twemproxy、Codis 優劣對比見下個問題)
3、常見的 Redis 集群方案有哪些優缺點?
Twemproxy:
多個同構 Twemproxy(配置相同)同時工作,接受客戶端的請求,根據 hash 算法,轉發給對應的 Redis。
優點:
開發簡單,對應用幾乎透明
歷史悠久,方案成熟
缺點:
代理影響性能
LVS 和 Twemproxy 會有節點性能瓶頸
Redis 擴容非常麻煩
Twitter 內部已放棄使用該方案,新使用的架構未開源
Codis:
ZooKeeper
存放路由表和代理節點元數據
分發Codis-Config的命令
Codis-Config 集成管理工具,有web界面
Codis-Proxy
無狀態代理,兼容Redis協議
對業務透明
Codis-Redis
基于2.8版本,二次開發
加入slot支持和遷移命令
優點:
開發簡單,對應用幾乎透明
性能比 Twemproxy 好
有圖形化界面,擴容容易,運維方便
缺點:
代理依舊影響性能
組件過多,需要很多機器資源
修改了 Redis 代碼,導致和官方無法同步,新特性跟進緩慢
開發團隊準備主推基于 Redis 改造的 reborndb
Redis Cluster:
P2P模式,無中心化。把 key 分成 16384 個 slot,每個實例負責一部分 slot。客戶端請求若不在連接的實例,該實例會轉發給對應的實例。通過Gossip協議同步節點信息。
優點:
組件 all-in-box,部署簡單,節約機器資源
性能比 proxy 模式好
自動故障轉移、Slot 遷移中數據可用
官方原生集群方案,更新與支持有保障
缺點:
架構比較新,最佳實踐較少
多鍵操作支持有限(驅動可以曲線救國)
為了性能提升,客戶端需要緩存路由表信息
節點發現、reshard 操作不夠自動化
二、Redis 通用
1、Redis 相對 MySQL、PostgreSQL 這些關系型數據庫,有什么優缺點?
觀點一:
Redis 主要是用來做緩存,它有持久化,但也只是為了緩存的可靠而已。優點是數據全放內存,速度快。缺點就是,數據大小不能超過內存大小。兩個用在不同業務場景,Redis 無法取代傳統關系型數據庫。
觀點二:
Redis 首先它是一種內存數據庫,最大的優勢在于效率高。尤其在某些特定場合下,例如熱點數據量非常大,而數據從內存和磁盤之間的換入換出代價比較高的情況下,Redis 就會體現它的價值。
傳統關系型數據庫在于它對數據的一致性保障,它的數據模型范式是遵循嚴格事務規則的結構化數據,由于其數據的高度抽象化,它調度到內存的數據一般場合下不會占用很大的內存空間。
總的來說,兩種數據庫各有各的優點和缺點。不同的業務場合有特定的追求目標,redis 首要的是效率,適用的是一些單純二維結構化數據無法表達的數據模型,而關系型數據庫處理的是可以用范式模型表達的二維數據,追求的是數據的高度一致性。隨著 IT 的發展,每一類型的數據庫都會在其特定的場合內發揮出無可比擬的優勢,最終的趨勢是大家趨于平衡,沒有最好,只有最適合。
觀點三:
記住一句話:任何數據庫都有自己的應用場景,應該關注數據流、數據屬性。
個人的經驗來說,Redis 不可能取代 MySQL 或者 PG。
2、Redis 有哪些應用場景?
Redis 是一個高性能的緩存,一般應用在 Session 緩存、隊列、排行榜、計數器、最近最熱文章、最近最熱評論、發布訂閱等。
更多應用場景,可以參考此處。
可以這樣講,Redis 適用于 數據實時性要求高、數據存儲有過期和淘汰特征的、不需要持久化或者只需要保證弱一致性、邏輯簡單的場景。
3、新接手一個復雜的 Redis 集群(Sentinel 模式),如何了解它
剛剛接手一套 Redis 集群,想要了解這套集群的相關配置。應該如何入手。難道只能通過 info 命令去查看各個配置嗎?
這是筆者的建議:
通讀 Sentinel 官方文檔:https://redis.io/topics/sentinel
Google 搜索 Redis Sentinel,找幾篇中英文的文章看看
進入 Sentinel 集群后,使用 info 查看集群信息
查看 Sentinel 配置文件,配合文檔搞清楚每個參數的含義
使用幾臺虛擬機模擬線上環境,然后做測試,在實踐中深入理解
思考當前 Sentinel 集群是否有不合理的地方,如有,提出并改進
三、Redis 故障排查
1、Redis 實例中,存在大量的 FIN_WAIT2 連接
客戶端 TCP 狀態遷移:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
服務器 TCP 狀態遷移:
CLOSED->LISTEN->SYN 收到 ->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
這個狀態存在于主動發起斷開請求的一端,如果服務器存在大量的這個狀態,那么這個服務器就充當客戶端的角色,如網絡爬蟲,出現的原因是由于客戶端發起 FIN 請求結束連接之后,收到了服務端的應答之后進入 FIN_WAIT2,之后就沒收到服務端發送的 FIN 信號導致。
PS:線上 Web 客戶端用的什么語言?
此問題的評論值得一看:http://www.aixchina.net/Question/231035-1406575
2、如何知道當前 Redis 實例是處于阻塞狀態?
解答一:
隨便 get 一個 key,然后卡著不動就行,簡單粗暴。優雅一點是看 latency 的延遲,blocked_clients 的數量,rejected_connections 的數量等。
解答二:
方法一:登錄 Redis,執行 info,查看 blocked_clients
方法二:執行 redis-cli --latency -h -p 查看延時情況
3、Redis 運維的故障有哪些?
回答一:
常見的運維故障
使用 keys * 把庫堵死,——建議使用別名把這個命令改名
超過內存使用后,部分數據被刪除——這個有刪除策略的,選擇適合自己的即可
沒開持久化,卻重啟了實例,數據全掉——記得非緩存的信息需要打開持久化
RDB 的持久化需要 vm.overcommit_memory=1,否則會持久化失敗
沒有持久化情況下,主從,主重啟太快,從還沒認為主掛的情況下,從會清空自己的數據——人為重啟主節點前,先關閉從節點的同步
回答二:
我簡單說下 Redis 故障的排查方法吧。
了解清楚業務數據流是怎么樣的
結合 Redis 監控查看 QPS、緩存命中率、內存使用率等信息
確認機器層面的資源是否有異常
故障時及時上機,使用 redis-cli monitor 打印出操作日志,然后分析(事后分析此條失效)
和研發溝通,確認是否有大 Key 在堵塞(大 Key 也可以在日常的巡檢中獲得)
和組內同事溝通,確實是否有誤操作
和運維同事、研發一起排查流量是否正常,是否存在被刷的情況
更多的排查需要對線上系統的分析。
四、Redis 性能優化
1、提高 Redis 內存數據庫的性能,有哪些措施?
這個問題有點偏題了,還是回答下吧。整理下工作中積累的經驗:
根據不同業務選擇數據類型,有必要時對數據結構進行審核,減少數據冗余
精簡鍵名和鍵值,控制鍵值的大小
使用前綴管理好 key
使用 scan 代替 keys,將遍歷 Redis DB 中所有 key 的操作放到客戶端來做
避免使用 O(N) 復雜度的命令
配置使用 ziplist 來優化 list
合理配置 maxmemory
數據量大的情況,做好 key 和 value 的壓縮
利用管道,批量處理命令
根據不同業務選擇短鏈接或者長鏈接
定期使用 redis-cli --big-keys 檢測大 Key
Redis 調優、監控知識和10個具體應用難點
一、Redis數據庫的優缺點及適用場景
Redis持久服務的特點,key-value鍵值類型存儲系統,支持數據可靠存儲,單進程單線程高性能服務器,恢復比較慢單機qps(秒并發)可以達到10W,適合小數據高速讀寫訪問。
Redis存儲系統優、缺點:可以持久化存儲數據,支持每秒10W的讀寫頻率,支持豐富的數據類型,所有操作都是原子性的,支持異機主從復制,內存管理開銷大(低于物理內存的3/5),不同命令延遲差別大,官方網站:http://www.redis.io
主要使用場景分為兩大塊:
1、緩存:熱點數據放到緩存里,大部分情況命中緩存,不命中時,訪問磁盤存儲并更新緩存
2、鍵值存儲,獨立使用緩存作為數據提供方。依賴于緩存服務的可靠性不高,業務對事務和數據的一致性要求不高。具體的,一般由架構師和開發人員,根據業務的特性,設計出具體的使用方法。
二、Redis的調優參數
Redis的參數調優問題,根據場景不同,有不同的調優方法,以下列舉踩過的一些坑的參數調優。我們的場景的海量數據,高并發。
(1)timeout參數,非常需要關注,官方對timeout的解釋如下:該參數表示當某一個客戶端連接上來并閑置timeout(單位秒)的時間后,Redis服務端就主動關閉這個客戶端連接。我們發現如果客戶端對連接處理比較差的時候,存在連接不釋放的問題,導致連接池耗盡,單個redis默認的連接數是1000.所以需要在timeout參數做文章,強制釋放無效連接,我們的參數調整為timeout 30000
(2)持久化參數,RDB和AOF究竟開哪個,很多人很糾結。其實選擇很簡單,兩者的區別是持久化的顆粒度不一樣,如果你關注數據的強一致性,選擇AOF,如果你選擇更好的性能,選型RDB。如果你選擇極致的性能,又能容忍數據的丟失,那你可以完全不用開啟持久化,當然了,集群是一定要開持久化的。
(3)tcp-backlog和maxclient,這兩個參數可能大家也比較迷糊,maxclient模式10000,一般情況下是夠了,但是在高并發海量訪問的時候,還是會出現客戶端緩慢的情況,那就是系統的限制,就是backlog參數,你可以理解為在三次握手時進入accept queue隊列的最大值,也就是send_Q,所以這個值設大點是沒有壞處的,我們的設置是1024
(4)重點提一下安全的參數,requirepass foobared 個人認為,如果你們覺得你們hold住,那就不用開,如果在DMZ區,數據又比較重要,那就開。個人認為,密碼的作用不是你想象中的帶給你安全,第一redis一分鐘可以訪問你想象不到的次數,如果弱密碼,分分鐘破解,第二auth命令是明文的,破解也很容易。
(5)maxmemory,這個參數比較常見,但是也非常的坑。如果你選擇用,有個原則,你是當數據庫用還是當緩存用,如果當數據庫用,就不要開,如果當緩存用,可以開。曾經有個BUG,多個salve的情況下,會導致擦除主節點的數據。如果你開啟這個參數,記得預留一些空間給系統的buffer。
遵循你的使用場景和你對參數的了解。寧愿逐步踩坑逐步解決問題逐步深入了解,也不要盲從的調整參數。
三、Redis 的監控指標
內存使用。如果 Redis 使用的內存超出了可用的物理內存大小,那么 Redis 很可能系統會被殺掉。針對這一點,你可以通過 info 命令對 used_memory 和 used_memory_peak 進行監控,為使用內存量設定閥值,并設定相應的報警機制。當然,報警只是手段,重要的是你得預先計劃好,當內存使用量過大后,你應該做些什么,是清除一些沒用的冷數據,還是把 Redis 遷移到更強大的機器上去。
持久化。如果因為你的機器或 Redis 本身的問題導致 Redis 崩潰了,那么你唯一的救命稻草可能就是 dump 出來的rdb文件了,所以,對 Redis dump 文件進行監控也是很重要的。可以通過對rdb_last_save_time 進行監控,了解最近一次 dump 數據操作的時間,還可以通過對rdb_changes_since_last_save進行監控來獲得如果這時候出現故障,會丟失(即已改變)多少數據。
Keys。通過獲取Keyspace中的結果得到各個數據庫中key的數量
QPS。即每分鐘執行的命令個數,即:(total_commands_processed2-total_commands_processed1)/span,為了實時得到QPS,可以設定腳本在后臺運行,記錄過去幾分鐘的total_commands_processed。在計算QPS時,利用過去的信息和當前的信息得出QPS的估計值。
四、如何更好更合理的使用Redis——10個具體應用難點解讀
1.Redis與Oracle中存有同一份數據,當數據發生變化時,應用程序是先寫Redis然后再同步到Oracle,還是先寫Oracle然后再同步到Redis呢,使用何種同步機制可以有效的解決這個時間差中兩份數據的不一致性呢?
答:如果你是當數據庫用,那就類似于電商搶購場景。搶購的場景中有個需要解決的問題是超買和超賣,意思就是說,我要控制庫存數量,而且要保證可用庫存的數量為0,不能出現負數。一般是把數據從Oracle刷到Redis,貼合題主的問題,那就是同樣有一份數據,當數據變化的時候,是先寫Redis還是先寫Oracle?是先寫Redis,再寫Oracle,因為代碼層面保證數據的一致性,在高并發情況下,悲觀鎖機制并不會很友好,而且影響性能。而redis天然的原子性事務,是可以保證數據的一致性。
如果你當緩存用,又要確保數據的強一致性,是可以先寫Redis,也可以先寫Oracle,如果先寫Redis,參考前一段話,采取Redis的強一致性;如果先寫Oracle,那就采取悲觀鎖來實現。
2.目前的監控系統是Python到Oracle取配置信息,經過運算之后再寫回Oracle,然后根據閥值來觸發告警,在這樣的模式之下Redis是否有可以應用的空間呢?**
答:當你的監控的需求具備秒級監控的能力后,你的web-db的架構就不再滿足了
比如說以下場景
1:基于日志的流式計算
2:監控指標的基線
3:數據的統計分析
4:通用的計算周期
5:多維度的告警規則:如無數據告警、基于同環比的告警、基于基線的告警、
越來越多的監控場景、監控指標、觸發器,redis的作用就是提供你更快、更優質的服務
3.我們的系統現在使用了兩套Redis;分別用作熱點數據緩存、會話保持保存全局ID。熱點數據緩存采用的是一主一從三哨兵(分別獨立,共五個節點);會話保持采用的是一主三從四個哨兵(共四個節點,每個節點上啟動了一個哨兵進程);這個是乙方給的方案,請教大神,這個方案可靠嗎?能否使用cluster方案來替代呢?有必要嗎?
答:你有兩套Redis,A作為熱數據緩存,B作為回話保持。
缺點:A有5個節點,B有4個節點,9個節點中只有2個節點是主節點,提供服務,備節點只是冗余,存在比較大的資源浪費。
優點:sentinel集群,客戶端可以隨意地連接任意一個sentinel來獲得關于redis集群中的信息,做到代理層的可用性。切換至cluster后在資源使用率方面,按照9節點的規模,實際組網只能有8臺,4主4從,資源使用率得到很大的提升,而且代理層分別由8個節點負擔,因此,也能保證了可用性。
4.主機房部署了Redis集群,并數據持久化。問題:要求在主機房發生災難并不可修復的情況下,容災機房能在一定時間內承擔起主機房的業務能力。如何保障容災機房的Redis集群數據跟主機房一致?如何操作??
答:主要看你采用集群的方式,如果是cluster,請參考,關于雙活機房中cluster模式的組網,根據你的業務場景來決定。如果redis的使用中并不處在核心鏈路上,完全當做cache來使用,且在擊穿情況下有后續的數據庫來支撐,可以放在同一機房內。如果Redis的使用在核心鏈路上,當做數據庫來使用,在單側機房部署,不能保證多機房環境下的多活。以雙活機房為例,集群有A、a、B、b、C、c節點,A、B、C三個節點部署在甲機房,a、b、c三個節點部署在乙機房,甲乙兩個機房使用波分線路進行大二層透傳,能夠使某一業務同時在某一都使用同一網段地址。基于Redis本身,能夠實現雙數據副本模式,當甲機房單側異常時,乙機房單側接管,重新完成組網,提供服務。
如果是其他集群,請描述,我再補充。我大概明白你的意思了,我猜測1:你應該沒有使用集群模式,而且采取了無狀態的三個節點,進行組網。2:你采取的cluster,三主三從都是部署在單側機房。目前你的做法是AB兩個機房,你集群部署在A單側機房,另外在B機房又復制了A機房的集群鏡像,當單側機房故障時,B機的Redis進行啟動進行加載數據提供服務。目前我有個問題,你們有沒有演練過?且應用要不要改Redis的IP?如果你們對Redis的場景沒有橫向擴展的要求,建議在Redis集群上加一層代理,比如sentinel、twemproxy通過代理去路由Redis,同時Redis的主備分別部署兩側機房,當主節點異常,備節點進行選舉接管。
5.多個系統共用Redis集群,如何防止某個系統獨占大量資源,導致其他系統不可用?
答:多個系統共用一套redis的前提,那就是不能對其他業務有影響。1:key-value的命名規范、2:定義使用場景、3:完善的監控、4:定期巡檢慢查詢日志
6.Redis生產部署中集群方案是否有簡化部署?
目前,在實際生產部署中,已經在使用Redis主備方案的部署,但還僅是依靠硬件負載均衡設備進行應用分發后,由2臺Redis服務器實現主備。基于Redis在系統僅是做為數據寫入緩存的單一功能。想了解一下除了Redis多機集群,是否有簡單的Redis雙機部署方案,性能如何?(2臺物理機,我們是電力行業系統 ,用于將通信端抄送上來的并發數20萬左右的報文緩存,然后存于數據庫!)
答:20萬的數據量不大,可以采用Redis主從方式,搭配sentinel進行自動主從切換。如果團隊開發能力較強,可以研究一下twemproxy開源架構。另外,Redis是單線程模式運行的,為了充分使用機器的CPU資源,可以搭建多個Redis實例,部署多套主從架構,或者使用twemproxy開源架構對數據進行分片,適應將來的業務量上漲。
7.Redis cluster在多活機房中采取怎樣的架構?
答:關于雙活機房中cluster模式的組網,根據你的業務場景來決定。
如果Redis的使用中并不處在核心鏈路上,完全當做cache來使用,且在擊穿情況下有后續的數據庫來支撐,可以放在同一機房內。如果Redis的使用在核心鏈路上,當做數據庫來使用,在單側機房部署,不能保證多機房環境下的多活。以雙活機房為例,集群有A、a、B、b、C、c節點,A、B、C三個節點部署在甲機房,a、b、c三個節點部署在乙機房,甲乙兩個機房使用波分線路進行大二層透傳,能夠使某一業務同時在某一都使用同一網段地址。基于Redis本身,能夠實現雙數據副本模式,當甲機房單側異常時,乙機房單側接管,重新完成組網,提供服務。
8.Redis Cluster什么情況下會導致數據丟失,應該怎么避免?
答:cluster模式下數據丟失,有兩種可能1:請求擊穿,寫入失敗,這個要從代碼層面來解決;2:主從切換,從節點的數據跟主節點數據有差異。這個解決方式可以采取配置always參數,保持數據的大概率的一致性。
9.Redis主從間是異步復制,這里提到強一致是如何做到的?應用層的工作嗎?
答:不得不說,Redis的數據同步,強一致性是有前置條件的,強一致性的根據有兩個前提,1:持久化文件的生成的一致性;2:持久化文件的寫入的一致性。針對1,目前有兩種持久化方式,RDB和AOF,針對兩者而言,其實都是異步的,兩個都有優缺點,但針對落地數據而言,都是異步的,所以能做到準實時,不能做到真正意義上的實時。很多人有疑問了,appendfsync always這個參數明明是同步的,是能犧牲性能保證數據的一致性的。仔細看官網的介紹,AOF持久化中的文件寫入操作其實是將aof_buf緩沖區的內容存放到了內存緩沖區中,這時還沒有真正寫入到磁盤中,這個緩沖區達到同步條件時,才會執行fsync將這個緩沖區的內容寫入到硬盤中,完成文件同步。所以持久化和REDIS事務的原子性是解耦的。針對2,取決于持久化文件的大小,曾遇到一種情況,當持久化文件非常大的時候,同步也是需要時間的。綜上所述,不能做到絕對的強一致性,只能做到可接受的范圍的強一致性。
10.在金融行業,為了保證數據的強一致性,應該選擇哪種持久化方式?換句話說,在主從切換中,通過哪些途徑保持數據的強一致性?
答:持久化并且要保證數據不丟失:可以開啟aof備份,并且把appendfsync參數設置為 always ,保證收到寫命令后就立即寫入磁盤,但是效率最差,一般的sata盤只能支持幾百的QPS。可以使用高效的SSD磁盤提升性能。但是這也違背了redis高速緩存的初衷。主從切換:目前原生redis不支持同步復制,它的主從只能是異步復制,也就是無法保證數據強一致性。有些公司通過修改復制內核支持主從完全同步的復制。這也犧牲了性能和QPS。redis出現的目的是為了作為緩存提升訪問性能,對數據一致性的支持相對比較弱。
作者:馬哥高薪IT實戰