乾貨|建議初創團隊起初也要構建分散式應用

来源:http://www.cnblogs.com/8hao/archive/2016/04/11/5377585.html
-Advertisement-
Play Games

乾貨|建議初創團隊起初也要構建分散式應用 本文內容整理自W-Time技術分享沙龍-天津站現場演講《一切都是分佈的》,演講者:李傲,問啊聯合創始人,前中交車聯網總架構。 好多人都會問什麼是架構師?其實架構師的定義很寬泛,前端後端的定義都不一樣。作為後端出身的架構師,我認為後端並不是大家想的封裝組件,它 ...


  乾貨|建議初創團隊起初也要構建分散式應用

  本文內容整理自W-Time技術分享沙龍-天津站現場演講《一切都是分佈的》,演講者:李傲,問啊聯合創始人,前中交車聯網總架構。

  好多人都會問什麼是架構師?其實架構師的定義很寬泛,前端後端的定義都不一樣。作為後端出身的架構師,我認為後端並不是大家想的封裝組件,它要定義的是規劃,規劃模塊之前的關係。在一臺機器搞不定時怎麼辦?答:集群!這詞說著很容易,但真要給你,你發現how?怎麼去加?

  有人問我,架構師要做什麼?我認為,架構師就是要在軟體起初階段就能夠從情景當中預先想到這問題,通過架構分散式解決方案,預先把問題都埋好。可能有人會說這算不算重度設計?其實所謂重度設計,要看團隊的基本能力,如果團隊寫代碼還寫不利索的情況下,那麼這個設計就很重要。因為不能指望一個代碼都沒有寫過幾行的人去寫架構,這個是不可能的,做分散式都很難。如果團隊能力屬於中上層,那麼有兩種可能:1、團隊做過十幾年的代碼,但架構差一些,那麼也會把程式寫的非常漂亮,因為對代碼有把控能力,對底層的研究比較透徹;2、代碼寫的並不是很好,但是架構師對新技術有瞭解,那麼也是有可能做好分散式的。如果你的團隊做不到以上這些,那隻有一種方法--用伺服器抗。但伺服器是一回事,團隊能力也不能太差。

  下麵就我們“問啊”來說給大家做一下簡單的分享,“問啊”是一款訂製化IT教育平臺,可以一鍵呼叫大牛解決IT 問題。

  關於分散式存儲

  “問啊”利用了一些分散式的概念,也就是分散式存儲。我們都知道,每一臺伺服器資源占用都是有限的,我們用的是雲伺服器,一般上來都會去買本地磁碟,但無論容量多大,總有一天會用完,當這一天到來的時候,有兩種可能:1、在你不知道的時候,服務死了,怎麼也起不來。可能會不運行、cpu過高,有人會問,這什麼原因導致的?計算量太大了?其實不是,因為一直在做無謂的io操作;2、無從下手,有個公司叫emc的做的磁碟可以解決,可是太貴,300萬左右的價格初創公司老闆肯定不批,而且性能也不能保證。

  但是分散式存儲就把這個事解決了,將要存儲的文件預先就散出去,而不是放在一個地方。拿的時候就很快的知道在哪了。舉個例子,就像大家都有房子,每個房子都有地址,這個地址都是預先規劃好的,就跟分散式存儲一樣,在規劃的時候就解決了未來如果數據膨脹會怎麼樣的問題。

  關於高速緩存

  接下來再說高速緩存,這也是一個分散式緩存的概念,對存儲和緩存來講,在演算法的選擇上是不一樣的,數據分為兩種,維度數據和事實數據。維度數據可以理解為是一種屬性,人也是一種維度數據,這個數據是有盡頭的。事實數據就是我出門的時候可能會踩死一隻螞蟻,但我不知道我這一路會踩死多少只,這就是事實數據。包括廣大的女性同胞養活了淘寶,這也是最好的例子,都是事實數據。

  事實數據存儲和維度數據是不一樣的,大家一般按時間存儲是最多的,這樣數據在取得時候有一些優勢--可以單獨拿一段出來。在數據結構中,拿一段怎麼拿?肯定得是連續存儲,這樣對cpu的消耗則是最小的。那維度數據呢,數據量本身就不大,我們用hash是比較靠譜的。

  對於記憶體和磁碟的存儲來講,磁碟是一個碟片,我們在尋找一個道的時候,我們會連續去打,這樣是最快的。因為不會跳針,跳針速度是最慢的。但記憶體不是,記憶體是隨機存儲,我們在利用存儲的時候也會考慮到,如果對於連續存儲來講,記憶體就一定比磁碟快嗎?在我看來,不一定。

  關於任務隊列

  我之前做車聯網,包括現在的滴滴打車都是一樣的,大家之所以能打到車,是車的位置信息已經上傳上來了。因為在同一時間內會爆發很多小高峰,導致我存數據的時候很慢,所以我不直接存儲,我先存到另一層去。為什麼要存到另一層呢?我們存儲的目的就是為了要拿出來,簡單的說:存的目的就是拿。其實存和拿是一個悖論,好存不好拿,好拿不好存。舉一個例子,這麼說可能可以直觀一些。上大學時,放學回宿舍,書包就扔在地上。為什麼?因為懶,扔的速度特別快,但是你可能轉天再找就找不到了。問題就出在存儲快但是沒有索引。想要快速查到怎麼辦?那就在存的時候分門別類,細緻存好。這樣拿比較快,存的時候就會費一些時間。如何解決這個悖論?讀寫分離。存和查的時候一定要做分離。軟體有一個理論叫“解偶”,如何解偶?簡單來說,a層和b層之間加一個c層就是解偶。只要你發現兩層之間有一個很緊密的聯繫,你就往裡面加一個。

  所以,任務隊列就是這樣,我們先把東西寫到隊列里,讓它慢慢的去消費。也就是說你把數據拿到隊列裡面來的時候,我就認為你存了。等你取得時候,看你的消費水平,消費水平慢,最多就一個感覺:這個更新好慢,僅此而已。然後下一步就該研究怎麼把這個消費做快,你是有這個機會的。但如果你這個事兒不這麼做,你就會發現,在你存的時候就已經死了。這樣用戶的感受可能會有兩種,一個是用戶並不知道,他只會覺得你們公司的數據比較少;二是我知道,你們已經死了。這樣的用戶體驗度是非常不好的。

  關於高速查詢

  這裡我要講一下我們查詢的數據結構。對於每種查詢來說,數據結構都不太一樣。現在有一種比較好的既能查又能存的數據結構叫LSM-TREE,就是hbase一個數據結構,大家有興趣可以看一下。

  如果你是一個應用,你可能會發現其實沒有現成的東西可以用,怎麼辦?那就用最短的時間研發出來一個輕量級的分散式,像任務下發。這種東西其實比較占資源,當你的伺服器數量不夠龐大,節點數量也不夠龐大的時候,你拿到的結果可能跟你最初的預想不太一樣。

  互聯網公司都有個比較難受的事兒,就是做運維不敢動機器。我們在做“問啊”的時候也沒有完全做到不停機,這個挺難的。有的時候為了嘗試試錯,我們需要做降級指標,其實有時候比升級指標難的多,會丟數據、丟節點,之後數據還能夠均攤,這個是挺難的。我們現在降級指標還沒有做到完全不停機,但升級指標已經能夠做到了。其實這就是各種負載均衡,通過負載均衡來代替ha,那麼這兩個概念是什麼概念呢?ha,高可用。負載均衡,就是就是你一個人搞不定,四五個人一起上!ha是什麼?一個活著,另一個就得死。一般用負載均衡來解決高可用有個問題,就是機器不閑著。一般來講,做機器空閑的話,總有一臺機器是不幹活的,這個對於初創公司來說成本比較高,配置選擇就是個難題。所以各種ha方案一般就是共用,那個節點可能會分攤好多個節點的共用,但是突然間發現兩個小高峰,兩個死了這個也就算死了。對於loadbalance本身有個非常大的優勢,就是本身來講,只要有1/2以上活了,這服務也就認為是活的,這個是比較好保證的。但是有一點,做lb演算法就一定要做到線上的配額一定要高於你目前的配額,否則你是沒法做的。

  下麵分享一下我們用過得一些東西:

  Redis

  一個基於記憶體的存儲。最大優勢就是單線程處理的。肯定有人問為什麼做單線程,很慢的!但是如果你測過的話就會發現,單線程多任務有時候不一定就比多線程多任務慢,多線程多任務有個空閑的概念,交替的概念,我要去調度。這個就完全省去調度,只要存儲速度特別快,能讓一個線程別空閑了,遠比多線程多任務要快。單線程有一個不可替代的優勢:無鎖,可以做到一致性。多線程本身來講只要併發對一個數據操作的時候,你就必須得加鎖。你的鎖如果設計不合理的話,你這個數據本來可以加到5的,結果才加到2就沒了。

  如果用redis完全不用考慮這些事。包括我們做訂單號的話,單號取一個數,這是個最普通業務。我們對單號+1就會考慮一個線程去做,如果可以搞定的話,那速度就快了,那我為什麼要去做多線程?那麼做多線程有一個方法,你可以先把訂單號切割,就是預計今年的訂單號能有多少,你先把他分好了。然後每一個進程怎麼樣操作,這樣不會出問題。但是訂單是跳躍,永遠不要用訂單號去做排序,這是最不合理的。就像大家都玩過搖紅包,其實都是一樣的,搖紅包為什麼能做到這麼快。其實不可能快,這個事情不是一個快的動作,有交互就不可能快。只能先把交互的紅包預先切好了,存在緩存里。甚至最狠的是用一些空池,就是沒獎。結果你的ip正好打到這一核了,hash到這一核里。不換ip拿不出來。

  Redis本身來講,它的存儲速度包括查詢速度是可以上到10萬級的,是非常快的。但是我們線上測的話。可能也是因為我們用的是雲平臺的一個服務,它本身是基於codis做的分散式服務。我們沒有時間去做自己的分散式redis,所以codis已經成為我們的瓶頸了。它大概的速度也就是1w,對於剛起步的應用來說應該夠用,那如何做到更快,只有一個方法:當你對一個事兒做到不能更快了,就三個字解決:分散式。這樣就肯定能解決,下一步再去琢磨這一個事該怎麼解決,這個就更高深了,有機會我會再詳細的為大家講解。

  Hbase

  有人說Hbase是大數據,其實我覺得很詫異,我認為大數據更偏重於分析。這個東西本身就是一個nosql ,為什麼要放到大數據呢?也許因為存的數據多?

  一開始起步的時候是三個節點,這算大數據嗎?這算是實驗。其實不是,它就是一個資料庫,大家不要對它有偏見,認為非要數據到多少的時候我把它遷過來,記住,數據量大的那天,你再想遷就遷不過來了。我的經驗告訴我,重構可以做局部模塊重構,但絕對不能做大遷移。只要做大遷移:丟數據、版本核對,動態版本核對,特別頭疼。

  我最怕跳槽,因為我的位置是救火的。經驗告訴我這個最好提前設計好。因為到那天了你難受,有兩方都不滿意:第一,用戶那裡,一直在用,你就得天天看著,怎麼還有用戶用?不知道該用高興還是該不用高興;第二,產品經理、運營就會使勁催你問你好了嗎?但是提前規劃好,就可以避開這些問題。

  Hbase本身來講呢,既然它能存這麼多數據,我們也不想太浪費。有兩套出報表的方案,一套是大家熟知的spark,可能用的比較多。對於一個初創團隊來講,spake本身它的worker節點配置有點高,因為它專門吃記憶體的。還有一種。Tkeyang24:06,替代hadoop,但是它本身沒有計算模塊,你還是上s,逃不過去。我們的方案呢,作為一個初創團隊來講,對於運營這一塊可能有點殘忍,但是沒有辦法,沒有這麼大的數據量,沒有必要。

  那麼插入數據方案呢,就兩個:

  1、通過集成phoenix序列化方法使用原生Hbase API插入更新數據,數據裝載速率並沒有降低;

  2、插入數據時採用雙保證,緩存和hbase均需要完全插入成功,否則記錄日誌進入修複隊列非同步保證數據同步。

  高速緩存

  關於高速緩存,剛剛有說過, redis最好的方案就是hash。這裡說兩個應用,Redis本身有個pub/sub,做數據隊列的,併列時隊列比較麻煩的是,如果想用它做一對一隊列,你是做不了的,其實一對一有很多隊列。但是作為初創團隊沒必要,那如何來解決這個問題呢?很簡單。我們分散式里,分三個redis,我這一個應用先用三個redis,寫數據的時候我在三個裡面做shard,你這一個應用shard這三個,那這一個應用就可以把這三個歸過來我用,如果兩個應用怎麼辦?有兩種方法,一種方法從k上,我監控不同的shard的隊列,a監控a隊列,b監控b隊列,每個人都監控三個,沒問題,但還有一個問題,redis本身來講,提供一個key失效的概念,緩存一定會有時效時間,但是緩存失效之後,他所定義的隊列的名字是寫死的。是跟十六庫綁定的,我們可以切16個作為拓展。如果十六不夠的話,切兩組作為拓展,這樣的話就可以無限的擴大。B監聽b的零號庫。這樣可以無限的擴大這樣可以通過闊機器,來提升一個人的消費能力。另一方面通過縱深,來分散消費能力。

  關於Redis2.8.22,可能用的比較多。3.0和3.2用的並不多。這有個毛病,TTL只要move一次庫,這個TTL就廢了,就是失效時間。本來是想用什麼巧妙的方法來做黑科技的,結果發現2.8.23解決了,所以大家用的時候從2.8.23以上用。

  我們在任務隊列主要做的事是,我們應用有個紅包的概念,為了讓大家都有學習的機會,能夠去問問題,所以我們有個紅包。如果用分散式的話,會有很多坑就可以繞過去了。

  Pub/sub,有一個比較噁心的事,當你消費的時候,如果消費函數,你沒有消費下一條的時候,pub/sub是不往後挪數據的,所以他會大量的堆積在redis里出不來,這個一定要註意。

  我推薦一個工具,現在有不少公司都在用這個:ES。這個還是比較好用的,但是現在有個問題:隨機函數。它裡面可以隨機抽量數據,在隨機抽量數據的時候我們發現兩個坑,1、散不開,大部分都一樣,隨機不太好;2、隨機速度特別慢,100w就開始特別慢了。做抽量的話,其實還有很多可以試一下。

  關於我們自主研發的,主要就是以下這幾點:1、針對服務節點運行數據決定任務的下發;2、任務之間沒有任何牽扯;3、任務死亡可以實時分裂新任務繼續執行;4、支持定時消息及紅包的應用。

  我發現很多人有個誤區,不寫代碼就真的省事嗎?我覺得吧,不寫代碼滿足需求最省事,用現成的有時候還不如自己寫,有什麼問題也好找。

  關於不停機運維

  Zookeeper這個東西挺好的。我現在註冊一些服務,立刻就會建上臨時的鏈接,臨時文件。比較坑人的地方就是它的存儲是限量的。每個節點存儲都一樣。一定要註意,存儲要省著使用,別寫進數據,不要用它做分散式事務所。Zabbix挺好用的,我們運維現在就使用這個。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Atitit。Js調用後臺語言 java c# php swing android swt的方法大總結 1. Js調用後臺語言有三種方法1 2. Swt BrowserFunction 綁定方法1 3. Android webview 可以綁定對象1 4. Js 調用Java Nashorn引擎,可 ...
  • Atitit.vod 視頻播放系統 影吧系統的架構圖 架構體系 解決方案 1. 運行平臺:跨平臺 android ios pc mobile 1.1. 前端 界面 1.2. Web組件化 Js css html的動態載入 ,容器化運行,ajax iframe 1.3. Css icon類庫 1.4. ...
  • 裝飾模式(Decorator) 定義 裝飾模式(Decorator),動態地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。 類圖 描述 Component:被裝飾者和裝飾者共有的基類; ConcreteComponent:被裝飾者的具體類; Decorator:裝飾類,包 ...
  • 編者按 與傳統意義上的紅包相比,近兩年火起來的“紅包”,似乎才是如今春節的一大重頭戲。歷經上千年時代傳承與變遷,春節發紅包早已成為歷史沉澱的文化習俗,融入了民族的血脈。按照各家公佈的數據,除夕全天微信用戶紅包總發送量達到80.8億個,紅包峰值收發量為40.9萬個/秒。春晚直播期間討論春晚的微博達到5 ...
  • 在配置cat集群時,有一些設置是我們應該註意的,從它的部署文檔中我們可以看到相關信息,但說的還不夠明確和重要,大叔今天總結一下Cat集群配置的註意事項 1 服務端datasources.xml用來設置連接的mysql,集群里的伺服器對這項配置是相同的 2 服務端的server.xml,用來設置集群里 ...
  • 在之前發佈Objective-C系列博客的時候,其中提到過OC的通知機制,請參考《Objective-C中的老闆是這樣發通知的(Notification)》這篇博客。在之前關於Notification的博客中,只介紹了Foundation框架中的通知的使用方式。正如前面博客中提到的那樣,通知是“一對 ...
  • 上一篇寫了nginx負載均衡,此篇實現高可用(HA)。系統整體設計是採用Nginx做負載均衡,若出現Nginx單機故障,則導致整個系統無法正常運行。針對系統架構設計的高可用要求,我們需要解決Nginx負載均衡出現單機故障時,系統正常運行的需求。所以系統架構引入Keepalived組件,實現系統高可用 ...
  • 組合模式(Composite) 定義 組合模式(Composite),將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。 組合模式有兩種形式:透明方式的組合模式和安全方式的組合模式。 類圖 描述 Component:它可以是介面或抽象類,為葉子 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...