1. 程式人生 > >高併發服務端分散式系統設計概要(上)

高併發服務端分散式系統設計概要(上)

又是快一年沒寫部落格了,2013年也只剩尾巴,也不知道今年都忙了些什麼。寫這篇文章的目的,主要是把今年以來學習的一些東西積澱下來,同時作為之前文章《高效能分散式計算與儲存系統設計概要》的補充與提升,然而本人水平非常有限,回頭看之前寫的文章也有許多不足,甚至是錯誤,希望同學們看到了錯誤多多見諒,更歡迎與我討論並指正。

好了,下面開始說我們今天要設計的系統。

這個系統的目標很明確,針對千萬級以上PV的網站,設計一套用於後臺的高併發的分散式處理系統。這套系統包含業務邏輯的處理、各種計算、儲存、日誌、備份等方面內容,可用於類微博,SNS,廣告推送,郵件等有大量線上併發請求的場景。

如何抗大流量高併發?(不要告訴我把伺服器買的再好一點)說起來很簡單,就是“分”,如何“分”,簡單的說就是把不同的業務分拆到不同的伺服器上去跑(垂直拆分),相同的業務壓力分拆到不同的伺服器去跑(水平拆分),並時刻不要忘記備份、擴充套件、意外處理等討厭的問題。說起來都比較簡單,但設計和實現起來,就會比較困難。以前我的文章,都是“從整到零”的方式來設計一個系統,這次咱們就反著順序來。

那我們首先來看,我們的資料應該如何儲存和取用。根據我們之前確定的“分”的方法,先確定以下2點:

(1)我們的分散式系統,按不同的業務,儲存不同的資料;(2)同樣的業務,同一個資料應儲存多份,其中有的儲存提供讀寫,而有的儲存只提供讀。

好,先解釋下這2點。對於(1)應該容易理解,比如說,我這套系統用於微博(就假想我們做一個山寨的推特吧,給他個命名就叫“山推” 好了,以下都叫山推,Stwi),那麼,“我關注的人”這一個業務的資料,肯定和“我發了的推文”這個業務的資料是分開儲存的,那麼我們現在把,每一個業務所負責的資料的儲存,稱為一個group。即以group的方式,來負責各個業務的資料的儲存。接下來說(2),現在我們已經知道,資料按業務拆到group裡面去存取,那麼一個group裡面又應該有哪些角色呢?自然的,應該有一臺主要的機器,作為group的核心,我們稱它為Group Master,是的,它就是這個group的主要代表。這個group的資料,在Group Master上應該都能找到,進行讀寫。另外,我們還需要一些輔助角色,我們稱它們為Group Slaves,這些slave機器做啥工作呢?它們負責去Group Master處拿資料,並儘量保持和它同步,並提供讀服務。請注意我的用詞,“儘量”,稍後將會解釋。現在我們已經有了一個group的基本輪廓:

這裡寫圖片描述

一個group提供對外的介面(廢話否則怎麼存取資料),group的底層可以是實際的File System,甚至是HDFS。Group Master和Group Slave可以共享同一個File System(用於不能丟資料的強一致性系統),也可以分別指向不同的File System(用於弱一致性,允許停寫服務和系統宕機時丟資料的系統),但總之應認為這個”File System”是無狀態,有狀態的是Group Master和各個Group Slave。

下面來說一個group如何工作,同步等核心問題。首先,一個group的Group Master和Group Slave
間應保持強一致性還是弱一致性(最終一致性)應取決於具體的業務需求,以我們的“山推”來說,Group Master和Group Slave並不要求保持強一致性,而弱一致性(最終一致性)即能滿足要求,為什麼?因為對於“山推”來講,一個Group Master寫了一個數據,而另一個Group Slave被讀到一個“過期”(因為Group Master已經寫,但此Group Slave還未更新此資料)的資料通常並不會帶來大問題,比如,我在“山推”上發了一個推文,“關注我的人”並沒有即時同步地看到我的最新推文,並沒有太大影響,只要“稍後”它們能看到最新的資料即可,這就是所謂的最終一致性。但當Group Master掛掉時,寫服務將中斷一小段時間由其它Group Slave來頂替,稍後還要再講這個問題。假如我們要做的系統不是山推,而是淘寶購物車,支付寶一類的,那麼弱一致性(最終一致性)則很難滿足要求,同時寫服務掛掉也是不能忍受的,對於這樣的系統,應保證“強一致性”,保證不能丟失任何資料。

接下來還是以我們的“山推“為例,看看一個group如何完成資料同步。假設,現在我有一個請求要寫一個數據,由於只有Group Master能寫,那麼Group Master將接受這個寫請求,並加入寫的佇列,然後Group Master將通知所有Group Slave來更新這個資料,之後這個資料才真正被寫入File System。那麼現在就有一個問題,是否應等所有Group Slave都更新了這個資料,才算寫成功了呢?這裡涉及一些NWR的概念,我們作一個取捨,即至少有一個Group Slave同步成功,才能返回寫請求的成功。這是為什麼呢?因為假如這時候Group Master突然掛掉了,那麼我們至少可以找到一臺Group Slave保持和Group Master完全同步的資料並頂替它繼續工作,剩下的、其它的Group Slave將“非同步”地更新這個新資料,很顯然,假如現在有多個讀請求過來併到達不同的Group Slave節點,它們很可能讀到不一樣的資料,但最終這些資料會一致,如前所述。我們做的這種取捨,叫“半同步”模式。那之前所說的強一致性系統應如何工作呢?很顯然,必須得等所有Group Slave都同步完成才能返回寫成功,這樣Group Master掛了,沒事,其它Group Slave頂上就行,不會丟失資料,但是付出的代價就是,等待同步的時間。假如我們的group是跨機房、跨地區分佈的,那麼等待所有Group Slave同步完成將是很大的效能挑戰。所以綜合考慮,除了對某些特別的系統,採用“最終一致性”和“半同步”工作的系統,是符合高併發線上應用需求的。而且,還有一個非常重要的原因,就是通常線上的請求都是讀>>寫,這也正是“最終一致性”符合的應用場景。

好,繼續。剛才我們曾提到,如果Group Master宕機掛掉,至少可以找到一個和它保持同不的Group Slave來頂替它繼續工作,其它的Group Slave則“儘量”保持和Group Master同步,如前文所述。那麼這是如何做到的呢?這裡涉及到“分散式選舉”的概念,如Paxos協議,通過分散式選舉,總能找到一個最接近Group Master的Group Slave,來頂替它,從而保證系統的可持續工作。當然,在此過程中,對於最終一致性系統,仍然會有一小段時間的寫服務中斷。現在繼續假設,我們的“山推”已經有了一些規模,而負責“山推”推文的這個group也有了五臺機器,並跨機房,跨地區分佈,按照上述設計,無論哪個機房斷電或機器故障,都不會影響這個group的正常工作,只是會有一些小的影響而已。

那麼對於這個group,還剩2個問題,一是如何知道Group Master掛掉了呢?二是在圖中我們已經看到Group Slave是可擴充套件的,那麼新加入的Group Slave應如何去“偷”資料從而逐漸和其它節點同步呢?對於問題一,我們的方案是這樣的,另外提供一個類似“心跳”的服務(由誰提供呢,後面我們將講到的Global Master將派上用場),group內所有節點無論是Group Master還是Group Slave都不停地向這個“心跳”服務去申請一個證書,或認為是一把鎖,並且這個鎖是有時間的,會過期。“心跳”服務定期檢查Group Master的鎖和其有效性,一旦過期,如果Group Master工作正常,它將鎖延期並繼續工作,否則說明Group Master掛掉,由其它Group Slave競爭得到此鎖(分散式選舉),從而變成新的Group Master。對於問題二,則很簡單,新加入的Group Slave不斷地“偷”老資料,而新資料總由於Group Master通知其更新,最終與其它所有結點同步。(當然,“偷”資料所用的時間並不樂觀,通常在小時級別)

中篇連結

下篇連結

相關推薦

併發服務分散式系統設計概要

又是快一年沒寫部落格了,2013年也只剩尾巴,也不知道今年都忙了些什麼。寫這篇文章的目的,主要是把今年以來學習的一些東西積澱下來,同時作為之前文章《高效能分散式計算與儲存系統設計概要》的補充與提升,然而本人水平非常有限,回頭看之前寫的文章也有許多不足,甚至是

併發服務分散式系統設計概要

上篇我們完成了在此分散式系統中,一個group的設計。那麼接下來,我們設計系統的其他部分。如前文所述,我們的業務及其資料以group為單位,顯然在此係統中將存在many many的groups(別告訴我你的網站總共有一個業務,像我們的“山推”,那業務是一堆一堆地),那麼由誰來管理這些groups呢?由Web

Go遊戲服務框架從零搭建— 架構設計

         五邑隱俠,本名關健昌,10年遊戲生涯,現隱居海邊。   本教程以Go語言分割槽遊戲服務端框架搭建為例。   Go語言是Google開發的一種靜態強型別、編譯型、併發型、具有垃圾回收功能的程式語言。語法上近似C語言,支援介面、可通過struct

SpringBoot使用WebSocket實現服務推送--叢集實現2

書接上文,本文介紹了一種實現叢集管理和訊息傳送方式。 在叢集模式情況下,一般是Nginx反向代理到多臺Tomcat或者SLB代理到多臺Tomcat的方式,怎麼實現給某個人推送訊息?比如WebSocket1連線到Tomcat1,但是在Tomcat2需要給WebSocket1傳送訊息,怎麼辦?一

SpringBoot使用WebSocket實現服務推送---單機實現1

最近開發中需要實現服務端的推送,經過一段時間的資料查詢最終鎖定使用websocket來實現。JavaEE本身就支援WebSocket。我們只需要開發一個EndPoint來處理連線、訊息等即可。但是WebSocket的session管理是開發中的重中之重和難點,因為你需要知道推送給誰,就需要儲存代

java分散式系統部署學習ansible-playbook進階

一、併發執行 ansible預設只會建立5個程序,所以一次任務只能同時控制5臺機器執行.那如果你有大量的機器需要控制,或者你希望減少程序數,那你可以採取非同步執行.ansible的模組可以把task放進後臺,然後輪詢它.這使得在一定程序數下能讓大量需要的機器同時運作起來. 使用asy

[工程經驗] 電氣與控制系統設計方案框架

前言:                  本 電氣與控制系統設計方案 所屬領域:機器人。 電氣與控制系統設計方案     1 系統技術要求  

技術面試的系統設計

可擴充套件性 基礎 現在您已經設計了一個可靠的抽象體系結構,下一步就是將其擴充套件。如果你從來沒有建立過大規模的系統,這個任務看起來有點令人生畏。 可擴充套件的Web開發 視訊地址 課件地址 比較建議看一看視訊,視訊裡面講的非常雜亂,感覺沒有

分散式系統之Quorum NRW演算法

基於Quorum投票的冗餘控制演算法 Quorom 機制,是一種分散式系統中常用的,用來保證資料冗餘和最終一致性的投票演算法,其主要數學思想來源於鴿巢原理。 在有冗餘資料的分散式儲存系統當中,冗餘資料物件會在不同的機器之間存放多份拷貝。但是同一時刻一個數據物件的多份拷貝只能用於讀或者用於寫。 該演算法可

java分散式系統部署學習ansible Ad-hoc與commands模組

Ad-Hoc 是指ansible下臨時執行的一條命令,並且不需要儲存的命令,對於複雜的命令後面會說playbook。講到Ad-hoc 就要提到模組,所有的命令執行都要依賴於事先寫好的模組,預設安裝好的ansible 裡面已經自帶了很多模組,如:command、r

java分散式系統部署學習ansible Dynamic Inventory

Ansible Inventory實際上是包含靜態Inventory和動態Inventory兩部分,靜態Inventory指的是在檔案/etc/ansible/hosts中指定的主機和組,Dynamic Inventory指通過外部指令碼獲取主機列表,並按照an

分散式系統閱讀筆記-----分散式物件和元件

一、介紹 在分散式系統中,一個完整的中介軟體需要展現一定的對於上層程式語言的以及底層的物理設施的抽象性。而分散式物件和分散式元件恰恰是2種重要的實現方式。 1、分散式物件包集成了面向物件的語言的特徵和

java分散式系統部署學習ansible配置ansible.cfg

Ansible預設安裝好後有一個配置檔案/etc/ansible/ansible.cfg,該配置檔案中定義了ansible的主機的預設配置部分,如預設是否需要輸入密碼、是否開啟sudo認證、action_plugins外掛的位置、hosts主機組的位置、是否開啟

C# PC客戶與Android服務的Socket同步通訊USB

需求:       Android的apk獲取手機資訊,把結果發給PC client 注意地方:      1.android預設手機端的IP為“127.0.0.1”      2.要想聯通PC與android手機的sokcet,一定要用adb forward 來作下埠轉發

java分散式系統部署學習ansible的Inventory與Patterns

Ansible的Inventory檔案,可以理解為saltstack中的salt-key中的所有minion的列表以及使用者自定義的nodegroup的概念,預設情況下這個檔案是/etc/ansible/hosts ,後面還會講到Dynamic Inventor

如何進行一場質量的UI設計評審

阿里巴巴_B2B_UED – 舒舟:產品設計流程中,有必要對設計進行評審是大家的共識。在我每週的工作內容中,參加各類大大小小的設計評審是必不可少的一環。既有腦力激盪的評審讓設計方案脫胎換骨的,也有針鋒相對的評審讓設計方

分散式系統閱讀筆記-----分散式系統的特徵

1)引言 從今天開始,我將會開始學習分散式系統的一些理論知識,全方面的重新學習分散式的各個技術點,所以選用了原版本的英文教材<<Dstributed Sysytems Concepts A

進程 - 多進程之間的數據隔離問題、使用多進程實現socket服務的並發效果

rec ddr end font 兩個 con col nco span # 進程 與 進程之間的數據是隔離的,比如例子兩個變量n import osfrom multiprocessing import Processdef func(): global n

深度學習實踐系列之--身份證漢字及數字識別系統的實現

手動 ear 常用 env 窗口 mic 文件下載 oot edr 前言: 本文章將記錄我利用深度學習方法實現身份證圖像的信息識別系統的實現過程,及學習到的心得與體會。本次實踐是我投身AI的初次系統化的付諸實踐,意義重大,讓自己成長許多。終於有空閑的時間,將其

操作系統 進程

系統 span 理解 .html 來看 是什麽 方法 外部 str 一、什麽是並發   並發是什麽?很簡單,前面介紹的多道批處理系統就是典型的並發執行。這裏再次過一遍高性能的多道批處理系統,其本質在於保持對系統資源的占用,CPU運行一個任務,若這個任務中斷,如需要IO請求之