web站點服務中,咱們除了存在面向用戶的服務功能外,每每也存在大量的後臺離線的相關計算任務,如對前端的異步操做數據隊列進行按期處理,對數據庫中的數據進行彙總挖掘,監控,轉儲,對中間數據的進一步運算處理等等……一個web服務站點的背後,每每存在大量對應的後端處理任務的功能模塊,用於支撐正常的業務功能系統。 php
在一個web站點的初始階段,咱們可能只須要有一臺服務器,容納部署全部的業務功能,包括了面向用戶的前端web服務功能,數據存儲,後端離線處理業務功能。隨着站點的業務功能愈來愈多,用戶訪問數的增長以及數據量的增加,單臺服務器的處理能力每每就面臨瓶頸。這個時候簡單的處理就是將前端web服務功能,數據庫和後端業務模塊分開部署在不一樣的機器上,可是可能過隨着站點規模的逐漸龐大,單個服務器也沒法支撐前端web服務,數據庫服務或者後端離線業務功能。Web前端服務,數據庫服務相對是通用的技術服務,相關業務都大同小異,其分佈式化在業界有相對很成熟和典型的架構模式解決方案,可是不一樣系統的後端離線業務功能可能千差外別五花八門,不一樣開發者開發出來的功能架構也各不相同,本文介紹一種低代價的web站點離線任務分佈式改造方案,其使用了glusterfs分佈式文件系統以及gearman分佈式運算框架。 前端
咱們知道,相關離線運算要能進行分佈式化運算,作到單次執行在任意一臺機器上執行均可以,其首先的要求就是程序依賴輸入輸出數據的非本地,咱們要實現運算的分佈式化,就必須實現全部存儲數據的中心化存儲以及分佈式化。 mysql
一 存儲的中心化和分佈式化 linux
咱們知道一個web站點的業務功能必然要使用各類數據,須要存放各類數據,基本上是以關係型數據庫,nosql數據服務,session數據,cache數據,原始的服務器文件數據存儲。對於關係型數據庫,nosql數據庫,其自己就是中心化的數據存儲,其分佈式化也有成熟的解決方案,對於站點session,相關cache數據,也有成熟的memcached等利用而進行中心化存儲,以及進行分佈式的擴展。對於大多數後臺離線業務功能來講,每每是開發人員逐漸開發堆積而來,這些功能程序每每會存在大量對本地文件的直接讀寫,若是改造使用其餘存儲方式,工做量巨大並且風險大,這些數據的中心化存儲改造每每成了解決數據存儲中心化的聚焦點,並且所幸,業界有大量成熟的分佈式文件存儲系統,可以幫咱們解決本地文件存儲的中心化和分佈式化存儲。咱們介紹一種使用glusterfs進行對本地文件存儲的分佈式化處理方案。 web
分佈式文件系統(Distributed File System)是指文件系統管理的物理存儲資源不必定直接鏈接在本地節點上,而是經過計算機網絡與節點相連。分佈式文件系統的設計基於客戶機/服務器模 式。一個典型的網絡可能包括多個供多用戶訪問的服務器。另外,對等特性容許一些系統扮演客戶機和服務器的雙重角色。例如,用戶能夠「發表」一個容許其餘客 戶機訪問的目錄,一旦被訪問,這個目錄對客戶機來講就象使用本地驅動器同樣。 sql
GlusterFS是 一個高層次的分佈式文件系統解決方案。經過增長一個邏輯層,對上層使用者掩蓋了下面的實現,使用者不用瞭解也不需知道,文件的存儲形式、分佈。 數據庫
內部實現是整合了許多存儲塊(server) 經過Infiniband RDMA或者 Tcp/Ip方 式互聯的一個並行的網絡文件系統,這樣的許多存儲塊能夠經過許多廉價的x86主 機,經過網絡搭建起來。 ubuntu
其相對於傳統NAS 、SAN、Raid的 優勢就是: 後端
1.容量能夠按比例的擴展,且性能卻不會所以而降 低。 api
2.廉價且使用簡單,徹底抽象在已有的文件系統之上。
3.擴展和容錯設計的比較合理,複雜度較低。擴展使用translator方 式,擴展調度使用scheduling接口,容錯交給了本地的文件系統來處理。
4.適應性強,部署方便,對環境依賴低,使用,調試和維護便利。
支持主流的linux系統發行版,包括 fc,ubuntu,debian,suse等, 並已有若干成功應用。
對於一個站點的後端離線功能的文件存儲來講,咱們既但願能將這些文件數據存儲中心化,又但願可以兼容已有的代碼,基於這兩種考慮,咱們能夠按照以下的方案圖來進行本地文件遷移到glusterfs文件系統:
這樣,咱們就即能實現文件存儲的分佈式化,又能兼容已有業務程序,作到無縫遷移。
二運算任務分佈式化
當咱們的業務程序依賴的存儲和數據都中心化,而不依賴於本地存儲的時候,咱們的運算任務就能夠在任何一臺部署環境和代碼運算服務器上運行,咱們惟一缺乏的就是一個任務的隊列調度處理模塊。咱們介紹一種基於gearman的分佈式運算框架。
Gearman是一個用來把工做委派給其餘機器、分佈式的調用更適合作某項工做的機器、併發的作某項工做在多個調用間作負載均衡、或用來在調用其它語言的函數的系統。
一個Gearman請求的處理過程涉及三個角色:Client -> Job -> Worker。
Client:請求的發起者,能夠是 C,PHP,Perl,MySQL UDF 等等。
Job:請求的調度者,用來負責協調把 Client 發出的請求轉發給合適的 Work。
Worker:請求的處理者,能夠是 C,PHP,Perl 等等。
由於 Client,Worker 並不限制用同樣的語言,因此有利於多語言多系統之間的集成。甚至咱們經過增長更多的 Worker,能夠很方便的實現應用程序的分佈式負載均衡架構。
另外,咱們的離線運算任務每每會存在着針對一類任務一些併發控制,任務去重,防追趕等等功能要求,咱們就能夠利用gearman作任務隊列,同時作二次開發,利用其餘技術手段,如mysql存儲介質下的任務數據存儲更新和分析,來實現這些併發控制和去重。能夠按照以下給出的一種架構來進行離線任務分佈式改造:
其中發送端調用統一的api來發送任務到gearman任務隊列,而且記錄相關任務信息到任務狀態記錄模塊,由部署在運算機上的worker來消費和執行任務。
任務發送端的處理邏輯以下圖所示:
按照這個流程,任務發送端能夠實現任務的去重功能。
Worker的任務消費流程以下:
這樣的結構不只可以實現任務的分佈式化執行,並且能夠執行一類任務的併發控制,同時經過任務執行前檢查機器資源情況,實現對機器資源的基礎保護,防止大量任務在集中個別機器上執行,使該服務器出現負荷太重,任務擁塞的狀況。
至此,咱們解決掉存儲的中心化和分佈式化,任務的分佈式化,新的任務的添加也只要歸入該框架下運行便可,隨着咱們的站點規模的增大,咱們能夠方便的加機器進行擴容,透明的進行存儲擴容和運算能力擴容,就不會再面臨結構上的不可擴展性。
下面以一個簡單的平臺應用例子來舉例,有一個平臺,其存在大量後臺cronjob按期任務,也存在各類須要對平臺的全量數據等進行批處理運算處理的功能,咱們在架構設計的時候,必須考慮到服務的水平可擴展性,也必需要有高可用性,具有強大的熱容災能力,同時,咱們也須要大量面對cronjob任務的防追趕,加鎖,批處理任務的併發執行度控制等問題,下面看看如何設計該平臺系統後端架構。
首先,該平臺的存儲咱們都使用非本地的存儲,包括數據庫服務器,相關cache存儲,還有分佈式文件存儲系統以及相關網絡訪問。
採用上面介紹的方案採用gearman分佈式框架進行部署,2臺gearman服務器,6臺運算服務器,以主備的模式來使用gearman-server,充當執行任務的隊列調度器,在6臺機器上各自部署消費worker程序,在另一臺機器上部署啓用linux系統的crontab,向gearman中發送cronjob任務給gearman,而後,針對任務的去重和併發控制,咱們設計以下的任務記錄模塊,簡單用mysql表來存儲相關的任務消息,用於實現防追趕去重和併發控制效果,其中一張關鍵的任務執行記錄表的格式以下:
針對不一樣類型的執行任務,咱們能夠設置不一樣類型的參數
將任務發送端程序和消費併發控制邏輯封裝到平臺公用模塊中,透明的進行調用和任務消費執行
針對cronjob類型的任務,平臺crontab主發送機上添加發送端任務
*/10 * * * * /home/work/php5/bin/php /home/work/ala-service/bin/cronjob/client_cronjob.php -t $type_id &> /dev/null
($type_Id爲在任務註冊表中添加的任務的編號id字段)
那麼註冊的任務觸發後就會隨機分配到6臺運算機上去執行。
而針對應用程序主動調用發送的任務執行方式,咱們只須要在發送端內嵌封裝好的發送端程序便可實現任務發送,下面圖舉一個簡單的PHP簡單封裝的發送端程序調用方式
發送端只要如此調用便可以發送任務去執行,後端運算機獲取任務後進行執行。
如此,運營前面所述架構思路,作2次擴展開發,就能夠方便的實現該後端平臺的需求,其能夠方便的水平擴展,機高的可用性,調用方便,實現真正的離線任務分佈式化。
將任務發送端程序和消費併發控制邏輯封裝到平臺公用模塊中,透明的進行調用和任務消費執行
針對cronjob類型的任務,平臺crontab主發送機上添加發送端任務
*/10 * * * * /home/work/php5/bin/php /home/work/ala-service/bin/cronjob/client_cronjob.php -t $type_id &> /dev/null
($type_Id爲在任務註冊表中添加的任務的編號id字段)
那麼註冊的任務觸發後就會隨機分配到6臺運算機上去執行。
而針對應用程序主動調用發送的任務執行方式,咱們只須要在發送端內嵌封裝好的發送端程序便可實現任務發送,下面圖舉一個簡單的PHP簡單封裝的發送端程序調用方式
發送端只要如此調用便可以發送任務去執行,後端運算機獲取任務後進行執行。
如此,運營前面所述架構思路,作2次擴展開發,就能夠方便的實現該後端平臺的需求,其能夠方便的水平擴展,機高的可用性,調用方便,實現真正的離線任務分佈式化。
by makaiwen