以前那篇文章寫出來之後我就以爲會有不少不一樣的意見,哈哈,那隻表明我我的的意見啊,歡迎討論。前端
先說說以前那一篇,我舉例子舉的OA系統
,並非說OA必定要這麼設計,只是一種誇張的手法,爲了說明後面的徹底脫離了業務場景來進行技術架構的設計就是過分設計
,並非說OA系統太簡單因此不能這麼設計,另外,寫PHP
效率低也只是打個比方,並不是貶低全世界最好的語言,不少人拿這兩個來噴實在不必。nginx
好了,說今天這一篇的正題了,上一篇寫了總體架構設計中的過分設計,這篇來講說高可用吧。redis
高可用
,我知道一旦帶上這個詞,無論寫什麼都會有人有不一樣意見,我說說我認爲的高可用
下的坑吧。緩存
我想不少人理解的高可用
就是單臺機器掛掉了整個服務不會掛掉,因此寫代碼的時候使用集羣的思想去寫代碼,好比作成無狀態的服務,保證在集羣使用的時候無狀態,單機故障不影響服務,從而達到高可用
的效果。微信
由這種思想搭建起來的系統極可能長成下面這個樣子,我想不少人都看到過這種架構模式吧。網絡
首先,這種架構模式自己並沒什麼問題,並且也確實很好,有服務發現,有集羣,單臺機器掛掉了還有其餘機器可以使用,在搜索系統,推薦系統,廣告系統,網站後臺系統中都在大量使用。架構
不少人接收到的信息是有了上圖的那種架構,那麼這個系統就變成了一個高可用的系統了,以爲這種架構模式就是高可用
的一顆銀彈
了。併發
但實際上,上圖的系統解決的主要是下面的兩個問題。分佈式
除了上面兩個問題之外,最後纔是解決所謂的高可用
的問題,這裏用了所謂
兩個字,由於我以爲高可用
這種東西不是一個架構的模式能解決的,一個高可用的系統是代碼級別解決的,不是靠幾個開源模塊能解決的。高併發
有些人總認爲高可用
系統有銀彈
,在各類論壇,會議上看到各類架構,並且基本上都用到了一些成熟的開源軟件,因此以爲有了這些之後就能夠是一個高可用的系統了,我有zookeeper,那麼服務單機掛了,服務照常跑,但實際上然並卵,zookeeper解決的是外部不可控因素致使的機器掛了,好比機器硬盤壞了,網絡斷了,這種因素致使的服務掛了,zookeeper能解決,你代碼出問題致使機器掛了,zookeeper下掛1000臺機器也解決不了啊,通常狀況下仍是一掛全掛。
好比一個分佈式的搜索系統,索引分片了,因此有個集羣,有50臺機器,每一個分片大概10臺機器,而且機器能夠動態增長減小,集羣用zookeeper管理,這算高可用
系統嗎?這但是一個標準的搜索系統的高可用
架構,也只能說,在代碼優秀的前提下,這個系統高可用
了,網絡問題和機器硬件問題已經比較難搞掛整個集羣了。但一旦代碼有個小bug,或者索引數據生成的時候出現了點問題,通常狀況下,集羣就全掛了,談何高可用。
高可用
沒有銀彈
,你在各處看到的,聽到的,學習到的各類高可用
架構,他們只會告訴你這個系統架構多麼牛逼,用幾個框框框住某幾個模塊,而後告訴你,這個框框裏的服務各類突發狀況都能自適應,流量洪峯來了線性加機器就能解決,對你來講倒是然並卵,他們沒有告訴你他們的代碼有多牛逼,而且只有在這個前提下才高可用
的,想純粹靠幾個框框來架構出一個高可用
的系統,那是PPT架構師。
真正的高可用
不用糾結架構設計,只須要代碼的健壯,健壯的代碼加上主備系統設計,不須要其餘的,基本上就是一個高可用的系統了,銀行的核心數據處理中心加上異地災備就是這樣子的,你敢說他不是高可用的?
因此,寫好代碼吧,才能高可用,學習架構,更多的只是對提升系統全局性認識的一種補充,高可用的架構不存在,存在的只有高可用的代碼
。
我前段時間看到過這樣一個系統,這是一個O2O的創業公司的後臺的一個模塊,主要功能是給剛打開APP的用戶提供一個個性化的推薦頁面,外部接入了一些其餘系統產生的一些數據。
數據從其餘系統推過來之後,先是接入到一個kafka
的消息隊列,數據進來了之後有一個服務的集羣獲取這個數據,不一樣的服務經過kafka
不一樣的topic
獲取,而後二次加工這些數據,生成一個結構化的個性化數據,把生成的數據存到redis
集羣中,每一個APP用戶對應redis
中一個key,前面的APP調用API之後,直接從redis
集羣中獲取數據返回,這些個集羣都用zookeeper管理的。
這麼架構出來,消息隊列是爲了解決第三方數據推送太猛,作緩存用的,而redis集羣實際上是爲了解決前端APP的高併發訪問的。
我先問了一下,消息隊列這個集羣在其餘系統模塊也在用,這沒問題,你們都要用嘛,部署一個集羣也很應該哈。
可是這個redis
集羣只有這裏在用,這裏我以爲有點問題了,有必要作個帶zookeeper的集羣嗎?只是爲了打開APP的個性化頁面,用個redis集羣?不是你們共用資源的話,我以爲徹底不必redis集羣,一主一備足矣,還容易維護。若是你以爲單機內存不夠大,能夠用redis2.0,開啓VM功能,突破物理內存的限制,redis還能本身在內存保持熱點數據。
你說這樣是爲了解決高併發下的高可用,若是redis掛了,還能自動切換,這麼說吧,我以爲一個系統中,排除硬件故障的問題,通常狀況下,等你的服務全掛光了,redis也還堅挺着。而且redis的併發能力簡直只能用恐怖來形容,單機2,3萬的QPS(數據大小2,3kb左右)徹底沒什麼問題,一個創業公司的日活用戶量通常狀況下也不必用集羣去抗併發吧?
後來,我建議他們把redis集羣幹掉,換成單機主備的,並且我發現所謂的個性化推薦其實大部分人看到的頁面是同樣的,這也很好理解,初期沒數據的狀況下,個性化推薦出來的東西也不夠豐富,redis集羣的內存使用率其實很低,因而我進一步建議他們用nginx+lua
的本地字典來緩存最熱的數據,後面掛個redis,變成一個三級緩存(redis本地磁盤,redis內存,nginx本地字典)。若是真的業務量上來了,換成redis集羣也很容易,如今就不必浪費機器資源了,畢竟創業公司嘛。
恩,最後他們衝我投來鄙夷的目光,這架構,人家看不上,萬一忽然一天用戶量暴增怎麼辦,並且最關鍵的是人家不差錢,好吧,呵呵。
瞎扯了這麼多,有沒有高可用的銀彈呢?恩,優秀的代碼就是一切高可用架構的基石和銀彈,優秀的代碼加上合理的架構就是高可用的架構,一個高可用的架構不是靠開源軟件搭積木來獲得的,成熟的開源軟件解決的是把一部分本應該你寫的代碼變得更優秀。
好吧,歡迎你們繼續討論:)
若是你以爲不錯,歡迎轉發給更多人看到,也歡迎關注個人公衆號,主要聊聊搜索,推薦,廣告技術,還有瞎扯。。文章會在這裏首先發出來:)掃描或者搜索微信號XJJ267或者搜索西加加語言就行