php redis 投票_高可用Redis服務架構分析與搭建

8696a635cbdefa34497fd6f74705b62b.png
HorstXuhttps://www.cnblogs.com/xuning/p/8464625.html

基于內存的Redis應該是目前各種web開發業務中最為常用的key-value數據庫了,我們經常在業務中用其存儲用戶登陸態(Session存儲),加速一些熱數據的查詢(相比較mysql而言,速度有數量級的提升),做簡單的消息隊列(LPUSH和BRPOP)、訂閱發布(PUB/SUB)系統等等。規模比較大的互聯網公司,一般都會有專門的團隊,將Redis存儲以基礎服務的形式提供給各個業務調用。

不過任何一個基礎服務的提供方,都會被調用方問起的一個問題是:你的服務是否具有高可用性?最好不要因為你的服務經常出問題,導致我這邊的業務跟著遭殃。最近我所在的項目中也自己搭了一套小型的“高可用”Redis服務,在此做一下自己的總結和思考。

首先我們要定義一下對于Redis服務來說怎樣才算是高可用,即在各種出現異常的情況下,依然可以正常提供服務。或者寬松一些,出現異常的情況下,只經過很短暫的時間即可恢復正常服務。所謂異常,應該至少包含了以下幾種可能性:

  • 【異常1】某個節點服務器的某個進程突然down掉(例如某開發手殘,把一臺服務器的redis-server進程kill了)
  • 【異常2】某臺節點服務器down掉,相當于這個節點上所有進程都停了(例如某運維手殘,把一個服務器的電源拔了;例如一些老舊機器出現硬件故障)
  • 【異常3】任意兩個節點服務器之間的通信中斷了(例如某臨時工手殘,把用于兩個機房通信的光纜挖斷了)

其實以上任意一種異常都是小概率事件,而做到高可用性的基本指導思想就是:多個小概率事件同時發生的概率可以忽略不計。只要我們設計的系統可以容忍短時間內的單點故障,即可實現高可用性。

對于搭建高可用Redis服務,網上已有了很多方案,例如Keepalived,Codis,Twemproxy,Redis Sentinel。其中Codis和Twemproxy主要是用于大規模的Redis集群中,也是在Redis官方發布Redis Sentinel之前twitter和豌豆莢提供的開源解決方案。我的業務中數據量并不大,所以搞集群服務反而是浪費機器了。最終在Keepalived和Redis Sentinel之間做了個選擇,選擇了官方的解決方案Redis Sentinel。

Redis Sentinel可以理解為一個監控Redis Server服務是否正常的進程,并且一旦檢測到不正常,可以自動地將備份(slave)Redis Server啟用,使得外部用戶對Redis服務內部出現的異常無感知。我們按照由簡至繁的步驟,搭建一個最小型的高可用的Redis服務。

方案1:單機版Redis Server,無Sentinel

afb7a23542ff23a9d2f0ff02ac5d1680.png

為了實現高可用,解決方案1中所述的單點故障問題,我們必須增加一個備份服務,即在兩臺服務器上分別各啟動一個Redis Server進程,一般情況下由master提供服務,slave只負責同步和備份。與此同時,在額外啟動一個Sentinel進程,監控兩個Redis Server實例的可用性,以便在master掛掉的時候,及時把slave提升到master的角色繼續提供服務,這樣就實現了Redis Server的高可用。這基于一個高可用服務設計的依據,即單點故障本身就是個小概率事件,而多個單點同時故障(即master和slave同時掛掉),可以認為是(基本)不可能發生的事件。

對于Redis服務的調用方來說,現在要連接的是Redis Sentinel服務,而不是Redis Server了。常見的調用過程是,client先連接Redis Sentinel并詢問目前Redis Server中哪個服務是master,哪些是slave,然后再去連接相應的Redis Server進行操作。當然目前的第三方庫一般都已經實現了這一調用過程,不再需要我們手動去實現(例如Nodejs的ioredis,PHP的predis,Golang的go-redis/redis,JAVA的jedis等)。

然而,我們實現了Redis Server服務的主從切換之后,又引入了一個新的問題,即Redis Sentinel本身也是個單點服務,一旦Sentinel進程掛了,那么客戶端就沒辦法鏈接Sentinel了。所以說,方案2的配置并無法實現高可用性。

方案3:主從同步Redis Server,雙實例Sentinel

fd646e78d5dc7ff7aeb1271318b0f1bd.png

為了解決方案2的問題,我們把Redis Sentinel進程也額外啟動一份,兩個Sentinel進程同時為客戶端提供服務發現的功能。對于客戶端來說,它可以連接任何一個Redis Sentinel服務,來獲取當前Redis Server實例的基本信息。通常情況下,我們會在Client端配置多個Redis Sentinel的鏈接地址,Client一旦發現某個地址連接不上,會去試圖連接其他的Sentinel實例,這當然也不需要我們手動實現,各個開發語言中比較熱門的redis連接庫都幫我們實現了這個功能。我們預期是:即使其中一個Redis Sentinel掛掉了,還有另外一個Sentinel可以提供服務。

然而,愿景是美好的,現實卻是很殘酷的。如此架構下,依然無法實現Redis服務的高可用。方案3示意圖中,紅線部分是兩臺服務器之間的通信,而我們所設想的異常場景(【異常2】)是,某臺服務器整體down機,不妨假設服務器1停機,此時,只剩下服務器2上面的Redis Sentinel和slave Redis Server進程。這時,Sentinel其實是不會將僅剩的slave切換成master繼續服務的,也就導致Redis服務不可用,因為Redis的設定是只有當超過50%的Sentinel進程可以連通并投票選取新的master時,才會真正發生主從切換。本例中兩個Sentinel只有一個可以連通,等于50%并不在可以主從切換的場景中。

你可能會問,為什么Redis要有這個50%的設定?假設我們允許小于等于50%的Sentinel連通的場景下也可以進行主從切換。試想一下【異常3】,即服務器1和服務器2之間的網絡中斷,但是服務器本身是可以運行的。如下圖所示:

aebb4ec71eadad6475947906c332e7b7.png

實際上對于服務器2來說,服務器1直接down掉和服務器1網絡連不通是一樣的效果,反正都是突然就無法進行任何通信了。假設網絡中斷時我們允許服務器2的Sentinel把slave切換為master,結果就是你現在擁有了兩個可以對外提供服務的Redis Server。Client做任何的增刪改操作,有可能落在服務器1的Redis上,也有可能落在服務器2的Redis上(取決于Client到底連通的是哪個Sentinel),造成數據混亂。即使后面服務器1和服務器2之間的網絡又恢復了,那我們也無法把數據統一了(兩份不一樣的數據,到底該信任誰呢?),數據一致性完全被破壞。

方案4:主從同步Redis Server,三實例Sentinel

dcc51c777783199a386e184358d95def.png

鑒于方案3并沒有辦法做到高可用,我們最終的版本就是上圖所示的方案4了。實際上這就是我們最終搭建的架構。我們引入了服務器3,并且在3上面又搭建起一個Redis Sentinel進程,現在由三個Sentinel進程來管理兩個Redis Server實例。這種場景下,不管是單一進程故障、還是單個機器故障、還是某兩個機器網絡通信故障,都可以繼續對外提供Redis服務。

實際上,如果你的機器比較空閑,當然也可以把服務器3上面也開啟一個Redis Server,形成1 master + 2 slave的架構,每個數據都有兩個備份,可用性會提升一些。當然也并不是slave越多越好,畢竟主從同步也是需要時間成本的。

在方案4中,一旦服務器1和其他服務器的通信完全中斷,那么服務器2和3會將slave切換為master。對于客戶端來說,在這么一瞬間會有2個master提供服務,并且一旦網絡恢復了,那么所有在中斷期間落在服務器1上的新數據都會丟失。如果想要部分解決這個問題,可以配置Redis Server進程,讓其在檢測到自己網絡有問題的時候,立即停止服務,避免在網絡故障期間還有新數據進來(可以參考Redis的min-slaves-to-write和min-slaves-max-lag這兩個配置項)。

至此,我們就用3臺機器搭建了一個高可用的Redis服務。其實網上還有更加節省機器的辦法,就是把一個Sentinel進程放在Client機器上,而不是服務提供方的機器上。只不過在公司里面,一般服務的提供方和調用方并不來自同一個團隊。兩個團隊共同操作同一個機器,很容易因為溝通問題導致一些誤操作,所以出于這種人為因素的考慮,我們還是采用了方案4的架構。并且由于服務器3上面只跑了一個Sentinel進程,對服務器資源消耗并不多,還可以用服務器3來跑一些其他的服務。

易用性:像使用單機版Redis一樣使用Redis Sentinel

作為服務的提供方,我們總是會講到用戶體驗問題。在上述方案當中始終有一個讓Client端用的不是那么舒服的地方。對于單機版Redis,Client端直接連接Redis Server,我們只需要給一個ip和port,Client就可以使用我們的服務了。而改造成Sentinel模式之后,Client不得不采用一些支持Sentinel模式的外部依賴包,并且還要修改自己的Redis連接配置,這對于“矯情”的用戶來講顯然是不能接收的。有沒有辦法還是像在使用單機版的Redis那樣,只給Client一個固定的ip和port就可以提供服務呢?

59452a035e0b64429a8805293a486051.png

答案當然是肯定的。這可能就要引入虛擬IP(Virtual IP,VIP),如上圖所示。我們可以把虛擬IP指向Redis Server master所在的服務器,在發生Redis主從切換的時候,會觸發一個回調腳本,回調腳本中將VIP切換至slave所在的服務器。這樣對于Client端來說,他仿佛在使用的依然是一個單機版的高可用Redis服務。

結語

搭建任何一個服務,做到“能用”其實是非常簡單的,就像我們運行一個單機版的Redis。不過一旦要做到“高可用”,事情就會變得復雜起來。業務中使用了額外的兩臺服務器,3個Sentinel進程+1個Slave進程,只是為了保證在那小概率的事故中依然做到服務可用。在實際業務中我們還啟用了supervisor做進程監控,一旦進程意外退出,會自動嘗試重新啟動。

4dde4b4e8c3303b5a1a969d0767ef49d.png
關注公眾號《架構文摘》,每天一篇架構領域重磅好文,涉及一線互聯網公司應用架構(高可用、高性能、高穩定)、大數據、機器學習、Java架構等各個熱門領域

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/533480.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/533480.shtml
英文地址,請注明出處:http://en.pswp.cn/news/533480.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

android studio 啟動畫面,Android Studio 利用Splash制作APP啟動界面的方法

public class SplashActivity extends Activity {// private final int SPLASH_DISPLAY_LENGHT 2000; // 兩秒后進入系統Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getWindow().addFlags(WindowManager.LayoutParams.…

android驅動測試,Android: 通過 cucumber 驅動 monkey 做穩定性測試

主要內容穩定性測試是什么Monkey 介紹自動化 Monkey穩定性測試是什么通過隨機點擊屏幕一段時間,看看 app 會不會奔潰,能不能維持正常運行。Monkey 介紹Monkey 是一個命令行工具,它可以運行在我們的模擬器或者設備當中。它可以發送一些偽隨機(…

gradle 查看依賴類庫版本_Android studio中查看依賴的第三方庫的歷史版本和最新版本...

在日常開發過程中,我們通過會依賴很多的第三方庫項目。類似這樣:dependencies {compile com.android.support:support-v4:24.2.1compile com.google.code.gson:gson:2.4compile com.lzy.net:okhttputils:1.7.0compile com.github.ybq:Android-SpinKit:1.…

set和map去重調用什么方法_【ES6】Set、Map

SetSet 是 ES6 提供給我們的構造函數,能夠造出一種新的存儲數據的結構特點:只有屬性值沒有屬性名,成員值唯一用途:可以轉成數組,其本身具備去重(自動去重),交集,并集,差集的作用等參…

cygwin 編譯 android vlc,Cygwin?編譯?VLC?問題

Cygwin 編譯 VLC遇到了這么多問題,不過還好最后編譯過去了。問題1:gcc -mno-cygwin -Wsign-compare-Wall -mms-bitfields -pipe -o libaccess_output_dummy_plugin.dll-g-shared -u _vlc_entry__0_8_6 -L/usr/win32/liblibaccess_output_dummy_plugin.a …

kvm上添加萬兆網卡_爛泥:為KVM虛擬機添加網卡

本文首發于爛泥行天下。前幾篇文章介紹了有關KVM安裝虛擬機以及如何給虛擬機添加硬盤,今天我們再來介紹下有關如何給KVM虛擬機添加網卡。給KVM虛擬機添加網卡,可以分為兩種形式:圖形界面的和virsh attach-interface命令的。圖形界面的很簡單&…

android studio日歷小程序,android studio無法加載日歷界面

LayoutInflater inflater (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); //載入界面view inflater.inflate(R.layout.pumkin_calendar,null);AlertDialog.Builder ad;ad new AlertDialog.Builder(pumkinLand.this);ad.setView(view);…

gazebo 直接獲取傳感器數據_5個使傳感器更簡單的技巧

傳感器遍布地球表面和周圍空間,為世界提供數據。這些廉價的傳感器是物聯網背后的驅動力之一,也是我們社會現在面臨的數字革命。然而,連接到傳感器并從傳感器獲取數據并不總是直截了當或容易的。這里有五個提示,可以幫助工程師第一…

paylinks.php_畢業設計-基于PHP的網上購物網站系統設計

畢業設計-基于PHP的網上購物網站系統設計,共45頁,14912字,附完整的程序源代碼。包括前臺,后臺的實現,先運行phpStudyAdmin后打開dzsw/install.php摘要隨著Internet技術的發展,人們的日常生活已經離不開網絡…

com/android/dx/command/main,com/android/dx/command/dexer/Main : Unsupported major.minor version 52.0

如果你在開發過程中遇到了上述的Bug,基本上是JDK版本不一致造成的,指的是高版本的JDK編譯的class不能放在低版本的JDK上運行。如果是Version 52,就表示JDK8編譯的class不能運行在JDK7上,所以需要在本地安裝JDK8. 如果是Version 51…

谷歌瀏覽器怎么重發請求_Googel 瀏覽器 模擬發送請求工具--Advanced REST Client

Advanced REST Client是 Chrome 瀏覽器下的一個插件,通過它可以發送 http、https、WebSocket 請求。在 Chrome 商店下搜索 Advanced REST Client,即可找到如果搜索不到的可到CSDN 下載:1.下載插件:Advanced Rest Client2.因為最新…

鴻蒙os吃內存嗎,終于上手機!華為鴻蒙 OS 2.0 系統:128KB 內存就能跑

終于上手機!華為鴻蒙 OS 2.0 系統:128KB 內存就能跑2020-09-11 10:51:480點贊0收藏0評論9月11日消息,華為昨天下午在東莞松山湖舉辦了全球開發者大會,本次大會帶來了全新的 EMUI 11 系統和備受期待的鴻蒙 OS 2.0 操作系統&#xf…

flink 不設置水印_區分理解Flink水印延遲與窗口允許延遲的概念

link 在開窗處理事件時間(Event Time) 數據時,可設置水印延遲以及設置窗口允許延遲(allowedLateness)以保證數據的完整性。這兩者因都是設置延遲時間所以剛接觸時容易混淆。本文接下將展開討論分析“水印延遲”與“窗口允許延遲”概念及區別。水印延遲(WaterMark)(1…

愛特php文件管理器2.8_查找「超級蜘蛛池開發者中心 摳:44564876易」安卓應用 - 豌豆莢...

8.6萬人安裝開發者頭條 - 程序員分享平臺 2015 年獲「最美應用」官方推薦,程序員必裝的應用。 開發者頭條是由一群程序員創建的,我們運營了 developerWorks 的微博、微信,創建了碼農周刊,已覆蓋百萬程序員; 我們更懂程…

談華為鴻蒙內核和操作系統,談華為鴻蒙內核和操作系統

作者 | 陸首群談到華為自研鴻蒙內核和操作系統,從華為透漏出來的信息來看,有點自相矛盾、撲朔迷離!我曾說過:真真假假,虛虛實實!這里有技術原因,也有外部原因。一開始(大概是 2016 年左右)&…

彈跳機器人 桌游_MIT機器人輕松搞定桌游疊疊樂:你能玩過它算我輸 |《科學》子刊...

乾明 發自 凹非寺 量子位 報道 | 公眾號 QbitAI江湖上,一直流傳著一種疊疊樂的試煉。規則很簡單,從下方的積木中,抽一根往上搭。你能往上搭幾層?對MIT團隊研發的機器人來說,玩這個游戲基本上不費吹灰之力。而且&#x…

華為鴻蒙無人駕駛,特斯拉最大的對手竟是華為?Hicar+鴻蒙OS無人駕駛技術不再一家獨大!...

原標題:特斯拉最大的對手竟是華為?Hicar鴻蒙OS無人駕駛技術不再一家獨大!短短幾個月的時間,特斯拉的市值翻了近4倍,對于一個超級企業來說一切都顯得那么不可思議,如果把它單純的看成一家車企,恐…

new_picview_一款漂亮的圖片查看器PictureViewer

前段時間寫了一款查看妹子圖片的客戶端宅男福利妹子客戶端SuperGank,于是后來就把其中的一個圖片查看的功能封裝成了一個library,使用簡單,可以進行多項設置。先來看一眼效果圖吧!下面來看看如何使用它:首先把圖片url的…

鴻蒙系統會不會影響游戲,令人擔心,鴻蒙系統會不會讓人失望?未來難說

如今,一直被炒的沸沸揚揚的鴻蒙系統,終于在2019年8月9日發布了,次日,也就是8月10日,榮耀的智慧屏又帶著鴻蒙系統出現了一次,榮耀智慧屏也成為了首次搭載鴻蒙系統的終端,見證了中國操作系統的歷史…

buck電路上下管_推薦 | 學好電路設計與仿真?你不能錯過這兩本書籍 ~

網 友小編,有沒有 Saber 相關書籍可以推薦一下?還有,Saber 軟件下載那個版本比較好?當然有啦!小 編《Saber 電路仿真及開關電源設計》柯福波 等編著本書以 Saber 開關電源為基礎,以具體工程電路為范例&am…