在Linux服務器程序中,讓系統可以提供以更少的資源提供更多的併發和響應效率決定了程序設計價值!怎樣去實現這個目標,它實際上是這麼多年以來一直追逐的東西。最開始寫代碼時候,省去一個條件語句、用更好的算法使程序時間\空間複雜度下降;到後來爲了讓數據結構更簡單方便的完成數據操做而無心中使用的數據庫3範式。這一系列的小細節都有欣慰,今天我在這裏的需求是:如何讓一個單進程去併發完成多任務?
單進程併發完成多任務?不能呀,咱們並不能要求單進程同時完成不一樣的任務,由於單進程只能同時擁有一個core!
咱們把進程的任務分割成出來,讓各個任務的子任務片逐個輪流在cpu裏面執行,那麼當子任務片足夠細緻的話,CPU每段時間都會處理不少子任務,進程又確實在處理不少個不一樣的任務。因此在這種狀況下,整體感知上就能體會到進程在不停的處理多個任務。
爲什麼要把任務拆分?搞這麼複雜又有什麼好處,爲什麼不能一個任務一個任務的接下去處理呢?
回憶下大學時候的操做系統,CPU時間片、狀態機、就緒隊列、多任務系統這些名詞,就會發現一般狀況下程序運行過程當中會存在一些開銷比較大的片斷,在這個時間裏面若是CPU還繼續出來這個程序,就會不少的浪費資源。因此,這個時候操做系統把那些阻塞的程序切換出內核,再把那些就緒狀態的任務換入繼續處理。
實際上在大型的服務器系統中,一個單任務可能會通過接口轉換、業務鑑權、數據更新等等多個步驟,也極可能經歷讀寫文件、讀寫數據庫、等待外部輸入等多種耗時量很是大的工做。這些單任務的組織能夠徹底參照Linux系統對進程調度的理論來更好的實現,其關鍵就在於怎樣實現對單任務的切割和任務調度。任務的切割和系統的業務綁定很是之緊密,通常會把設計文件操做、數據庫操做、等待消息和外部驅動等操做的程序片切割出來。
任務管理器則實現對任務調度管理工做,它主要根據任務的狀態機來實現對任務的調度,提供虛擬接口來實現統一的調度窗口。
任務單元:一個內存塊class\struct,包含該任務的頭部信息,如任務編號、當前狀態、指向任務內存塊的指針等等一系列公共信息。
任務池:由任務單元數組,進程每一個處理的任務都在任務池裏面分配一個節點
任務管理器:完成任務池的統一管理、實現快速索引,任務管理基於幾個HashList實現。包括空閒任務隊列、超時控制任務隊列數組、已超時任務數組等。
基於以上分析,那麼新設計出來的系統就會變成一個這樣的機器模型:一個不停接收外部處理,而後把任務切割成多個小塊,分別釋放到不一樣服務進程進行處理,最後把小任務處理結果進行歸併的任務管理進程。這個是否是有點那啥的影子,其實現階段系統最終演化出來都具體他們共同的一組特性,即:把系統拆分紅數據接口、任務管理、業務提供這三類子系統。也許是本身所見太少,可是最少我接觸到的系統都具備這種共同特性,並且它們所在的關鍵就在於怎麼去更好的組織管理具體的任務,hadoop成功就在於此。
上面就是我所涉及的一個數據系統,因爲數據資料龐大,每張表的數據量要求達到億級,查詢流程須要很是高的性能保證,而更新須要保證數據準確性和一致性。咱們在設計系統基礎結構的時候,首先考慮採用的是分庫及多點併發,可是這樣就必須存在多個備份點並且須要高度的數據一致性,加上主機成本因數。最終採用的是PC機+多點備份的模型,經過增長總線控制模塊來實現多點備份的數據一致性和高可用性,總線模塊即基於上述任務管理器理念設計,它將一個數據更新拆分紅多個小任務,分發到多個子業務節點處理,而後再根據各個節點處理結果進行合併,若是失敗則進行數據回滾,若是成功則把其它備份節點一併發到備份的兄弟節點去。它將一個查詢拆根據備份節點業務量負載到不一樣備份節點進行出來,以多節點同步處理的方式進行併發。