1,解決應用服務器的cpu和內存壓力前端
2,減小io的讀操做,減輕io的壓力(內存中讀取)node
3,關係型數據庫擴展性,不強,難以改變表的結構nginx
1,nosql數據庫沒有關聯關係,數據結構簡單,擴展容易redis
2,數據讀寫快,可以每秒勝任幾十萬的併發,處理速度快算法
1,數據高併發讀寫sql
2,海量數據讀寫數據庫
3,對不規則數據也就是擴展性要求高的數據後端
1,須要事務支持,雖然它也有事務可是沒有關係型數據庫的那麼成熟吧緩存
2,基於sql進行操做服務器
1,主從複製
2,哨兵模式
3,Redis官方提供的Cluster集羣模式(服務端)
4,Jedis sharding集羣(客戶端sharding)
5,利用中間件代理,好比豌豆莢的codis等
實現主從複製(Master-Slave Replication)的工做原理:Slave從節點服務啓動並鏈接到Master以後,它將主動發送一個SYNC命令。Master服務主節點收到同步命令後將啓動後臺存盤進程,同時收集全部接收到的用於修改數據集的命令,在後臺進程執行完畢後,Master將傳送整個數據庫文件到Slave,以完成一次徹底同步。而Slave從節點服務在接收到數據庫文件數據以後將其存盤並加載到內存中。此後,Master主節點繼續將全部已經收集到的修改命令,和新的修改命令依次傳送給Slaves,Slave將在本次執行這些數據修改命令,從而達到最終的數據同步。
若是Master和Slave之間的連接出現斷連現象,Slave能夠自動重連Master,可是在鏈接成功以後,一次徹底同步將被自動執行。
主從複製配置
修改從節點的配置文件:slaveof masterip masterport
若是設置了密碼,就要設置:masterauth master-password
主從模式的優缺點
優勢:
同一個Master能夠同步多個Slaves。
Slave一樣能夠接受其它Slaves的鏈接和同步請求,這樣能夠有效的分載Master的同步壓力。所以咱們能夠將Redis的Replication架構視爲圖結構。
Master Server是以非阻塞的方式爲Slaves提供服務。因此在Master-Slave同步期間,客戶端仍然能夠提交查詢或修改請求。
Slave Server一樣是以非阻塞的方式完成數據同步。在同步期間,若是有客戶端提交查詢請求,Redis則返回同步以前的數據
爲了分載Master的讀操做壓力,Slave服務器能夠爲客戶端提供只讀操做的服務,寫服務仍然必須由Master來完成。即使如此,系統的伸縮性仍是獲得了很大的提升。
Master能夠將數據保存操做交給Slaves完成,從而避免了在Master中要有獨立的進程來完成此操做。
支持主從複製,主機會自動將數據同步到從機,能夠進行讀寫分離。
缺點:
Redis不具有自動容錯和恢復功能,主機從機的宕機都會致使前端部分讀寫請求失敗,須要等待機器重啓或者手動切換前端的IP才能恢復。
主機宕機,宕機前有部分數據未能及時同步到從機,切換IP後還會引入數據不一致的問題,下降了系統的可用性。
Redis的主從複製採用全量複製,複製過程當中主機會fork出一個子進程對內存作一份快照,並將子進程的內存快照保存爲文件發送給從機,這一過程須要確保主機有足夠多的空餘內存。若快照文件較大,對集羣的服務能力會產生較大的影響,並且複製過程是在從機新加入集羣或者從機和主機網絡斷開重連時都會進行,也就是網絡波動都會形成主機和從機間的一次全量的數據複製,這對實際的系統運營形成了不小的麻煩。
Redis較難支持在線擴容,在集羣容量達到上限時在線擴容會變得很複雜。爲避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源形成了很大的浪費。
建議:
其實redis的主從模式很簡單,在實際的生產環境中是不多使用的,也不建議在實際的生產環境中使用主從模式來提供系統的高可用性,之因此不建議使用都是由它的缺點形成的,在數據量很是大的狀況,或者對系統的高可用性要求很高的狀況下,主從模式也是不穩定的。
該模式是從Redis的2.6版本開始提供的,可是當時這個版本的模式是不穩定的,直到Redis的2.8版本之後,這個哨兵模式才穩定下來,不管是主從模式,仍是哨兵模式,這兩個模式都有一個問題,不能水平擴容,而且這兩個模式的高可用特性都會受到Master主節點內存的限制。
Sentinel(哨兵)進程是用於監控redis集羣中Master主服務器工做的狀態,在Master主服務器發生故障的時候,能夠實現Master和Slave服務器的切換,保證系統的高可用。
Sentinel(哨兵)進程的做用
監控(Monitoring): 哨兵(sentinel) 會不斷地檢查你的Master和Slave是否運做正常。
提醒(Notification):當被監控的某個Redis節點出現問題時, 哨兵(sentinel) 能夠經過 API 向管理員或者其餘應用程序發送通知。
自動故障遷移(Automatic failover):當一個Master不能正常工做時,哨兵(sentinel) 會開始一次自動故障遷移操做,它會將失效Master的其中一個Slave升級爲新的Master, 並讓失效Master的其餘Slave改成複製新的Master;當客戶端試圖鏈接失效的Master時,集羣也會向客戶端返回新Master的地址,使得集羣可使用如今的Master替換失效Master。Master和Slave服務器切換後,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的內容都會發生相應的改變,即,Master主服務器的redis.conf配置文件中會多一行slaveof的配置,sentinel.conf的監控目標會隨之調換。
Sentinel(哨兵)進程的工做方式
每一個Sentinel(哨兵)進程以每秒鐘一次的頻率向整個集羣中的Master主服務器,Slave從服務器以及其餘Sentinel(哨兵)進程發送一個 PING 命令。
若是一個實例(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被 Sentinel(哨兵)進程標記爲主觀下線(SDOWN)
若是一個Master主服務器被標記爲主觀下線(SDOWN),則正在監視這個Master主服務器的全部 Sentinel(哨兵)進程要以每秒一次的頻率確認Master主服務器的確進入了主觀下線狀態
當有足夠數量的 Sentinel(哨兵)進程(大於等於配置文件指定的值)在指定的時間範圍內確認Master主服務器進入了主觀下線狀態(SDOWN), 則Master主服務器會被標記爲客觀下線(ODOWN)
在通常狀況下, 每一個 Sentinel(哨兵)進程會以每 10 秒一次的頻率向集羣中的全部Master主服務器、Slave從服務器發送 INFO 命令。
當Master主服務器被 Sentinel(哨兵)進程標記爲客觀下線(ODOWN)時,Sentinel(哨兵)進程向下線的 Master主服務器的全部 Slave從服務器發送 INFO 命令的頻率會從 10 秒一次改成每秒一次。
若沒有足夠數量的 Sentinel(哨兵)進程贊成 Master主服務器下線, Master主服務器的客觀下線狀態就會被移除。若 Master主服務器從新向 Sentinel(哨兵)進程發送 PING 命令返回有效回覆,Master主服務器的主觀下線狀態就會被移除。
哨兵模式的優缺點
優勢:
哨兵集羣模式是基於主從模式的,全部主從的優勢,哨兵模式一樣具備。
主從能夠切換,故障能夠轉移,系統可用性更好。
哨兵模式是主從模式的升級,系統更健壯,可用性更高。
缺點:
Redis較難支持在線擴容,在集羣容量達到上限時在線擴容會變得很複雜。爲避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源形成了很大的浪費。
配置複雜
Redis Cluster是一種服務器Sharding技術,3.0版本開始正式提供。
在這個圖中,每個藍色的圈都表明着一個redis的服務器節點。它們任何兩個節點之間都是相互連通的。客戶端能夠與任何一個節點相鏈接,而後就能夠訪問集羣中的任何一個節點。對其進行存取和其餘操做。
Redis集羣數據分片
在redis的每個節點上,都有這麼兩個東西,一個是插槽(slot)能夠理解爲是一個能夠存儲兩個數值的一個變量這個變量的取值範圍是:0-16383。還有一個就是cluster我我的把這個cluster理解爲是一個集羣管理的插件。當咱們的存取的key到達的時候,redis會根據crc16的算法得出一個結果,而後把結果對 16384 求餘數,這樣每一個 key 都會對應一個編號在 0-16383 之間的哈希槽,經過這個值,去找到對應的插槽所對應的節點,而後直接自動跳轉到這個對應的節點上進行存取操做。
還有就是由於若是集羣的話,是有好多個redis一塊兒工做的,那麼,就須要這個集羣不是那麼容易掛掉,因此呢,理論上就應該給集羣中的每一個節點至少一個備用的redis服務。這個備用的redis稱爲從節點(slave)。那麼這個集羣是如何判斷是否有某個節點掛掉了呢?
首先要說的是,每個節點都存有這個集羣全部主節點以及從節點的信息。
它們之間經過互相的ping-pong判斷是否節點能夠鏈接上。若是有一半以上的節點去ping一個節點的時候沒有迴應,集羣就認爲這個節點宕機了,而後去鏈接它的備用節點。若是某個節點和全部從節點所有掛掉,咱們集羣就進入faill狀態。還有就是若是有一半以上的主節點宕機,那麼咱們集羣一樣進入發力了狀態。這就是咱們的redis的投票機制,具體原理以下圖所示:
投票過程是集羣中全部master參與,若是半數以上master節點與master節點通訊超時(cluster-node-timeout),認爲當前master節點掛掉.
何時整個集羣不可用(cluster_state:fail)?
若是集羣任意master掛掉,且當前master沒有slave.集羣進入fail狀態,也能夠理解成集羣的slot映射[0-16383]不完整時進入fail狀態. ps : redis-3.0.0.rc1加入cluster-require-full-coverage參數,默認關閉,打開集羣兼容部分失敗.
若是集羣任意master掛掉,且當前master沒有slave.集羣進入fail狀態,也能夠理解成集羣的slot映射[0-16383]不完整時進入fail狀態. ps : redis-3.0.0.rc1加入cluster-require-full-coverage參數,默認關閉,打開集羣兼容部分失敗.
Redis 3.0的集羣方案有如下兩個問題。
一個Redis實例具有了「數據存儲」和「路由重定向」,徹底去中心化的設計。這帶來的好處是部署很是簡單,直接部署Redis就行,不像Codis有那麼多的組件和依賴。但帶來的問題是很難對業務進行無痛的升級,若是哪天Redis集羣出了什麼嚴重的Bug,就只能回滾整個Redis集羣。
對協議進行了較大的修改,對應的Redis客戶端也須要升級。升級Redis客戶端後誰能確保沒有Bug?並且對於線上已經大規模運行的業務,升級代碼中的Redis客戶端也是一個很麻煩的事情。
Redis Cluster是Redis 3.0之後才正式推出,時間較晚,目前能證實在大規模生產環境下成功的案例還不是不少,須要時間檢驗。
Redis Sharding能夠說是在Redis cluster出來以前業界廣泛的採用方式,其主要思想是採用hash算法將存儲數據的key進行hash散列,這樣特定的key會被定爲到特定的節點上。
慶幸的是,Java Redis客戶端驅動Jedis已支持Redis Sharding功能,即ShardedJedis以及結合緩存池的ShardedJedisPool
Jedis的Redis Sharding實現具備以下特色:
採用一致性哈希算法,將key和節點name同時hashing,而後進行映射匹配,採用的算法是MURMUR_HASH。採用一致性哈希而不是採用簡單相似哈希求模映射的主要緣由是當增長或減小節點時,不會產生因爲從新匹配形成的rehashing。一致性哈希隻影響相鄰節點key分配,影響量小。
爲了不一致性哈希隻影響相鄰節點形成節點分配壓力,ShardedJedis會對每一個Redis節點根據名字(沒有,Jedis會賦予缺省名字)會虛擬化出160個虛擬節點進行散列。根據權重weight,也可虛擬化出160倍數的虛擬節點。用虛擬節點作映射匹配,能夠在增長或減小Redis節點時,key在各Redis節點移動再分配更均勻,而不是隻有相鄰節點受影響。
ShardedJedis支持keyTagPattern模式,即抽取key的一部分keyTag作sharding,這樣經過合理命名key,能夠將一組相關聯的key放入同一個Redis節點,這在避免跨節點訪問相關數據時很重要。
固然,Redis Sharding這種輕量靈活方式必然在集羣其它能力方面作出妥協。好比擴容,當想要增長Redis節點時,儘管採用一致性哈希,畢竟仍是會有key匹配不到而丟失,這時須要鍵值遷移。
做爲輕量級客戶端sharding,處理Redis鍵值遷移是不現實的,這就要求應用層面容許Redis中數據丟失或從後端數據庫從新加載數據。但有些時候,擊穿緩存層,直接訪問數據庫層,會對系統訪問形成很大壓力。
中間件的做用是將咱們須要存入redis中的數據的key經過一套算法計算得出一個值。而後根據這個值找到對應的redis節點,將這些數據存在這個redis的節點中。
經常使用的中間件有這幾種
Twemproxy
Codis
nginx
具體用法就不贅述了,能夠自行百度。
客戶端分片(sharding)須要客戶端維護分片算法,這是一種靜態的分片方案,須要增長或者減小Redis實例的數量,須要手工調整分片的程序。利用中間件的狀況則會影響到redis的性能,具體看中間件而定,畢竟全部請求都要通過中間件一層過濾官方提供方案,現時點成功案例很少。