架構師之路--談業務的合理架構

  奶奶從路邊撿來一隻小雞。它老是喳喳的叫,可是週末我坐在那裏的時候,它就會蹲在我腳上,很安詳的樣子。而後小鮮肉就過來講:麻麻,我好想嚇唬它。小雞被嚇的處處亂串。我說了挺多話無法讓小鮮肉停下來。我就嘆了口氣在那裏看着。一個5歲的孩子原本就不具有換位思考的能力。還有一個問題,我其實根本不知道小雞是怎樣想的。只是以爲它趴在我腳上的時候很安心很安靜。晚上下班我會把手伸到籠子裏陪它待一下子,由於我想它是很想本身的媽媽的。html

  本文首發於靜兒1986的博客,原文地址是http://www.cnblogs.com/xiexj/p/6874654.html前端

  先說說咱們部門的業務。咱們部門掌管樂視網全部的視頻音頻等最核心數據的信息。全部子業務都圍繞着這個核心數據。最籠統的分能夠分爲兩塊:讀和寫。mysql

  讀數據除了直接依賴DB的內部操做以外,就是直接經過http請求的RPC調用。由於調用這個接口的業務方很是多,他們用的語言和技術很是雜,http有更好的通用性和便於運營人員等不懂技術的人排查問題,只能內網訪問,也很安全。這是部門併發量最大的服務。單臺機器QPS通常在2k多,低谷時在1k多,高峯時在3k多。線上11臺接口服務器同時工做。可是讀數據爲了提升併發量,將全量的視頻和專輯數據存在了memcached緩存裏。因此一旦其餘業務方更新了數據會直接發送MQ消息給讀數據服務,讀數據服務更新了緩存後要給業務方回覆消息。nginx

  讀數據還有一種被叫作離線數據推送。這是因爲像搜索部門這樣的,須要全部視頻相關的全量數據,不合適經過接口訪問。以前用的是他們直接依賴咱們的數據庫鏡像。可是這樣咱們這邊要進行數據庫改造,分庫分表或者其餘的表結構修改,就要通知各個依賴業務方。因此咱們就改用定時全量數據推送給他們和MQ實時數據發消息的方式進行解耦。web

  還有一個面向全部部門同事的服務,就是統一異常平臺。部門的全部子業務的異常都會異步發送到統一的Redis中。能夠在一個公共的平臺統一查看。對於特定業務的,會給特定的同事發出告警郵件。redis

  寫數據的業務方很是多,咱們部門也有。其餘部門也有。寫數據就是建立,修改和刪除。寫數據QPS很低。sql

  建立時不只要走咱們這邊,還要調用雲存儲,雲轉碼等其餘部門的接口。具體流程可參考以前的一篇文章:《一個請求過來都通過了什麼》數據庫

  修改是走咱們部門內部系統或者調用咱們的API。apache

  刪除只能走咱們部門內部系統,刪除接口目前不向其餘業務部門開放。api

  我本身目前主要作的就是讀數據的部分。離線數據算是我開發的,其餘人是拷貝的個人。目前正在進行RPC接口的改造。寫我也作過。PGC項目是專業用戶進行視頻上傳的,當年是我作的。這是一個平臺。我作過數據接入。就是咱們購買一些版權的公司將他們的視頻的介質和媒體信息直接ftp放到咱們服務器上,或者給咱們一種調用方式咱們本身去取,這種屬於後臺服務。我也維護過咱們的視頻後臺系統。是我去美國作數據接入的時候,美國運營同事老是過來找我說咱們系統的問題,因爲時差,我只能本身動手改了。

  後臺服務能夠本身想怎麼寫怎麼寫。其餘的,不論是讀接口,PGC仍是後臺系統都是採用的SOA架構將業務垂直分解爲前端(對於平臺來講就是和界面打交道的,對於讀接口來講就是業務方調用的),使用Dubbo來調用數據服務。基於這種設計,一個子業務的代碼基本模塊都分爲API模塊,WEB模塊(讀接口無此模塊),common模塊(一些公用工具或者公用POJO), client模塊(dubbo服務的接口),service服務(dubbo服務的實現,即服務提供者)。

  簡單介紹一下Dubbo:Dubbo是一種透明化的遠程方法調用,就像調用本地方法同樣調用遠程方法,只需簡單配置,沒有任何API侵入。實現了軟負載均衡及容錯機制,服務自動註冊與發現,可以平滑添加或刪除服務提供者。

 

  下面是今天的重點,吐槽一下咱們目前讀接口的架構不合理(固然不合理是很正常的,這是一個爲期三年的古董),咱們新方案已經設計好了。

  讀接口業務簡單,併發支持需求大。若是說採用Dubbo層是爲了與業務分離,提升服務的複用率,提升數據的統一性。目前一個子業務就本身弄一套Dubbo。有API和WEB兩個對前端業務的也將就起到做用了。讀接口就是一個api調服務,有啥複用的啊。Dubbo的讀接口採用默認的阻塞模式,高併發的狀況下Dubbo就會成爲性能瓶頸。

  業務方能夠進行數據的更新,他們更新DB後還要維護咱們的緩存。咱們的緩存採用的樂視統一的CouchBase集羣。CouchBase是Memcached的升級版。既然是走Memcached協議,那麼就可使用Moxi代理來提升性能。

  簡單介紹一下Moxi:它基於memcached開發,對於併發的gets請求,作合併來減小和memcahed server的交互。對熱點訪問的cache會在本地緩存,減小network hops。network hops就是網絡路由跳數,距離目的網絡所通過的路由器數目。對於某種類型的key,能夠異步set。可配置超時時間,也有錯誤重試機制。

  各個業務線反饋說Memcached很差用,有性能問題。好多業務線本身換成了Redis,解決了好多神奇問題。撇開這些數據不談,給你一個用Redis而不用Memcached理由:Memcached的各類強化和代理Memcached本身均可以作,可是沒有作。Redis卻在不斷的更新和優化。

  還有一個專門維護這個緩存數據一致性的服務。我我的以爲咱們系統過度的強調了一致性,卻犧牲了性能。下面是一些基本的理論:

  分佈式領域CAP理論:

  • Consistency(一致性),數據一致更新,全部數據變更都是同步的。
  • Availability(可用性),好的響應性能  
  • Partition tolerance(分區容錯性)可靠性。

  定理:任何分佈式系統只可同時知足兩點,無法三者兼容。

  忠告:架構師不要將精力浪費在如何設計能知足三者的完美分佈式系統,而是應該進行取捨。

  一致性模型:

  • 強一致性
  • 單調一致性
  • 會話一致性
  • 弱一致性
  • 最終一致性

  BASE理論(CAP理論的延伸):

  • 基本可用(Basically Available):容許損失部分可用性,保證核心可用
  • 軟狀態(Soft State):分佈式存儲中通常一份數據至少會有三個副本,容許不一樣節點間副本同步的延時就是軟狀態的提現。mysql replication的異步賦值也是一種體現。
  • 最終一致性(Eventual Consistency):

  核心思想:即便沒法作到強一致性,可是應用能夠採用合適的方式達到最終一致性。

  像咱們經常使用的分佈式存儲:mysql的主從讀寫分離,redis緩存的master-slave形式的主從複製都是基於操做記錄的,都會有時延,也就是保證最終一致性而已。

   

  題外話:基本的理論和名詞概念是很實用的。好比在以前公司作搜索引擎的時候,搜索引擎須要分詞,分詞的分詞組件叫Tokenizer。這個不是搜索引擎特有的概念。Java的rt.jar這個最基礎類庫裏有StringTokenizer和StreamTokenizer。若是你瞭解了這個,就很容易理解理解搜索引擎的分詞是幹什麼用的。

  

  再說咱們項目中過度強調數據一致性而損失性能和高可用的事情。徹底能夠不對一致性不那麼精益求精。這並非說不追求完美。追求完美能夠提如今哪些方面呢?

  以前作的一個信用名片的項目,有的用戶在某星手機的某些版本中上傳頭像,上傳以後頭是倒着的。經調查發現咱們拍的照片在手機上能夠各個角度拍攝,憑藉着EXIF信息,這是一種專門爲數碼相機設置的格式。裏面有拍攝時翻轉手機的信息,能夠有8種角度。不少操做系統和圖片查看軟件都會自動按照信息裏的翻轉角度,將圖片翻轉回來。可是某星的某些版本沒有這個功能。針對這個問題,開始的時候,我用了一個國外的元數據萃取的工具包將這個EXIF信息的翻轉信息提取出來。效果已經達到了。可是做爲代碼手藝人,以爲只是這麼個小須要就添加了一個1MB多的jar包,並且實際上它的實現是解析構建DOM樹的方式,意味着爲了提取翻轉信息,要解析構造整個文件對象。因此我本身又採用了直接讀取圖片二進制流的方式,取圖片前面若是以0xFFD8開頭的就是包含EXIF信息的,不然不予處理,讀取文件結束。以0xFFD8開頭的要判斷是否包含旋轉信息,包含旋轉信息的判斷是Intel標準仍是Motorola標準,由於這兩個標準高字節和低字節表明的含義正好相反。就這樣一直到讀到旋轉信息或者判斷出不存在旋轉信息,文件關閉。因此最後讀入的文件數據不多,效率大大提升。

  在以前公司用Solr搜索引擎的時候,有個需求是過濾輸入的html標籤。可是在Solr中對索引讀入後的第一個操做就是分詞,使用Solr自帶的或者外部的分詞器。而後再對分好的詞進行更細節的過濾或者近義詞之類的。可是這第一步就直接破壞了文檔的結構,變成了一個個單詞,而不是html文檔形式。再去除,能夠去除,一個個過濾符號和單詞是不是html標籤,判斷先後都是啥。能作,第一,麻煩,最重要的是效率低。因此我當時的作法是直接修改了本身用IK分詞器的源碼,讀入數據第一個操做先過濾標籤。這就很好辦了,apache有現成的工具類。這樣避免了讀入讀出帶來的性能損耗。

  

  說了這麼多,架構究竟是一個什麼概念。我我的理解,在一個組織和系統內能夠有不少維度的架構。

  好比業務架構是咱們老大要考慮的事情。他心目中有一個本身的業務架構定位,外面提了一個需求,他有本身的規劃,這個是否是應該歸入咱們的業務體系。

  好比系統架構是管理者和架構師一塊兒進行考慮的事情。業務定好了,那麼用怎樣的模塊去劃分這個業務更利於維護,更高效。

  好比技術架構是架構師的最重要責任。真正從技術角度去展現一個系統,包括硬件的,軟件的,抽象的,具體的。它包括網絡,服務器,第三方產品使用和調用,軟件架構和數據架構。

  好比軟件架構是開發人員能夠接觸到的軟件開始的部分。好比一個web系統從nginx反向代理開始到一個SOA架構的系統:包括resin服務,resin服務上有一個mvc架構的程序,調用另外一個服務的系統,系統又和緩存,數據庫,消息隊列,第三方調用打交道。

  好比數據架構,這個之因此單提出來是由於數據是服務的核心。好比對一個WEB應用來講,有一些數據是直接能夠放到客戶端的,如JS,靜態頁面。還有一些數據是要放到服務端的。服務端的數據又要考慮是放在緩存仍是數據庫仍是文件等等。放在什麼地方要綜合考慮效率,帶寬,安全,數據有效性和可靠性。

相關文章
相關標籤/搜索