排隊應用開發
王建興
qing.chwang@gmail.com
排隊在生活中無所不在
講者簡介
• 現職
– 聖藍科技技術長
• 興趣
– 網路應用系統開發
• 譯作
– Thinking in Java 4th Edition, 正體中文版
– Thinking in Java 2nd Edition, 正體中文版
– Essential C++, 正體中文版
• 專欄
– iTHome 電腦報程式人專欄
• 連絡方式
– qing at gmail.com
– qing_wang at twitter
綱要
• 何謂佇列
• 為什麼需要佇列
• 排隊理論
• 佇列的應用
• 案例探討
• 高效工作佇列beanstalk
• 結論
何謂佇列(Queue)?
• 佇列(Queue)是一種能依序存取其中元素
的抽象資料結構
– FIFO Queue
– Priority Queue
• 在佇列上的典型操作
– Enqueue(塞進佇列中)
– Dequeue(自佇列中取出)
– *Peek(窺看佇列中的第一個元素)
Java內建的Queue
• java.util.Queue
– 典型先進先出的FIFO Queue
– 尾進頭出
• java.util.PriorityQueue
– 非FIFO存取原則
– 依照物件的 “natural ordering” 或自定排序方式
決定優先序的佇列
– 自定排序透過Java的Comparator介面指定
Java中Queue的變形
• Blocking
– BlockingQueue
– PriorityBlockingQueue
• Double Ended Queue
– Deque
• Delay
– DelayQueue
– 儲存java.util.concurrent.Delayed
• Synchronous
– SynchronousQueue
In-Process Queue
• Queue 和 Queue 的客戶端程式位在同一個
行程中
• 客戶端程式毋需透過任何通訊協定或IPC的
方式來對Queue做操作
• 儲存於Queue中的資料,通常不需要做
serialization和deserialization
• 像Java collection API中的Queue族系都是屬
於In-Process 的 Queue
In-Process Queue的應用優缺
• 優
– 低額外負擔:不需要額外的傳輸、不需要跨行
程的資料處理負擔
– 單純:沒有獨立的伺服器需要管理
• 缺
– 較難擴展規模
– 受限在單一機器的資源(CPU, RAM, Network,
…)
Network-based Queue
• Queue 和 Queue 的客戶端程式不位在同一
個行程中
• 客戶端程式需透過特定的通訊協定或IPC的
方式來對Queue做操作
• 儲存於Queue中的資料,需要做serialization
和deserialization
Network-based Queue的應用優缺
• 優
– 有機會透過增加 Queue 的數量來擴展規模(增
加 CPU, RAM, Network, …)
– 多個 Queue 之間可相互備援,以容忍系統異常
及錯誤
• 缺
– 額外負擔較大
– 系統複雜度較高
為什麼需要佇列?
• 演算法中需要儲存資料的資料結構
• 資源的最佳化配置
• 跨行程的通訊
做為演算資料結構的Queue
• Queue是演算法中十分常用的資料結構
• Graph Traversal – BFS (Breadth First Search)
– FIFO Queue
• Prim’s Algorithm for Minimal Spanning Tree
– Priority Queue
用於資源最佳化的Queue
• Queue 是一種在提供服務的成本以及使用擁
塞的代價之間取捨達成平衡的機制
• 例:Job Queue
– 工作在Queue中排隊等待可用資源
• Queue提供緩衝的作用
• 因為資源的使用有高有低,透過Queue可緩
衝對資源的使用,使資源運用最佳化
• Queue提供排程的機制,可依重要性運用資
源
Producer-Consumer
*http://vichargrave.com/multithreaded-work-queue-in-c/producer-consumer-model/
• Producer 可以是 client request,而 Consumer
就成了可以處理 request 的 server 了
Producer-Consumer
• 用FIFO Queue來解決生產及消費速率不匹配
的問題
*http://blog.eyasranjous.info/2013/04/14/using-the-producer-consumer-java/
用於跨行程通訊的Queue
• 位在不同行程、甚至是不同機器上的程式
,可以透過Queue來交換訊息
用於跨行程通訊的Queue
• 即使主要目的是跨行程的通訊,但是這還
是個 Producer-Consumer 的模型
排隊理論(Queuing Theory)
• 排隊理論是用數學的方式研究等候線或佇
列的排隊
• 排隊理論透過建構模型的方式來預測佇列
的長度、排隊所需的等候時間、以及排隊
的公平性
排隊模型的參數
• 服務請求到達的規則
– 像是請求到達的機率分布方式
– 簡單的例子,像是平均多久一個請求到達
• 完成請求之服務時間的規則
– 像是完成請求之服務時間的機率分佈方式
– 簡單的例子,像是平均多久完成一個請求
• 總共有幾個伺服器
• 總共有幾個佇列
• 決定服務請求的方式
– 先到先服務、後到先服務、隨機服務、高優先權者先
服務…
排隊模型示意
*http://www.cmg.org/measureit/issues/mit58/m_58_15.html
資源配置及服務品質
• 前言:Queue 是一種在提供服務的成本以及
使用擁塞的代價之間取捨達成平衡的機制
• 想要提升服務品質,即降低擁塞的代價
– 增加 Server 的個數
• 想要降低提供服務的成本
– 減少 Server 的個數
• 相衝突的目標之下,只能取捨一個平衡點
佇列在系統上的應用
• 當資源有限時,利用佇列來更妥善的運用
資源,平衡資源配置量及服務品質
– Job Queue
• 透過佇列的機制,來簡化跨行程之系統組
成的溝通
– Message Queue
Job Queue
• 在軟體系統中,所謂的 Job Queue (工作佇
列)是一個由工作排程器(Job Scheduler)
所維護的資料結構,其中內含待執行的工
作
*http://zeroproductionincidents.wordpress.com/category/web-architecture/process-model/page/3/
Message Queue
• 所謂的Message Queue(訊息佇列)是一種
用於以下用途的軟體元件
– 跨行程通訊
– 同行程中跨執行緒的通訊
• Message Queue 中所儲存的就是用來通訊的
訊息內容
• Message Queue 的通訊本質是非同步,所以
訊息的發送者和接收者毋需在同時間連線
方能進行互動
Message Queue
*http://docs.wso2.org/wiki/display/MB201/Queues
Queue 的本質
• 非同步
– Producer/Consumer 或 Sender/Receiver 不需要
同步互動
• 緩衝
– 提供一個緩衝空間來暫存
• 標準化的溝通界面
Decupling System Components
• Message Queue/Job Queue 衍生出來的好處
• 透過Message Queue/Job Queue 溝通系統中
的不同組成
• 各組成可跨行程、跨主機
• 各組成可跨語言
• 容易擴展規模
案例探討
Event Log 的收集及分析系統
Event Log 的收集及分析
• 有一些系統,有大量的客戶端需要向系統
回報數量龐大的log資訊
• 例-:行車記錄系統
– 不斷的向系統回報車速GPS座標甚至是即時上
傳車上攝影機所拍下的照片
• 例二:廣告使用者行為追蹤系統
– 收集使用者在頁面上的行為,以便分析使用者
的偏好,進而做廣告投放呈現的參考
可能的系統架構
httpd EvetLogServlet Log Datastore LogAnalyzer
可能會有的效能問題
• 同時太多並行的請求時,會有大量的執行
緒被產生出來以執行 Servlet 的處理程式
• 對資料庫的寫入動作會是重要的瓶頸
– 每秒一萬筆的資料更新?
• 太多執行緒在等待資料庫可寫入
– 執行緒存在時間拉長,資源佔用時間拉長,佔
用更多的資料(CPU, Memory, Socket, …)
– 客戶端的請求等待回應的時間也變長
嘗試擴展規模?
httpd EvetLogServlet Log Datastore LogAnalyzer
…
…
Load
Balancer
導入Job Queue
…
…
EvetLogServlet DatastoreJob Queue Worker
多層的緩衝
…
Raw
DatastoreJob Queue Worker Worker
Report
Datastore
多層緩衝的實作
…
Cassandrabeanstalkd
Java
Worker
Java
Worker MySQL
同事的惡搞
• 同事:這比較像這兩年流行的架構
beanstalk
• Beanstalk 是個簡單、快速的工作佇列
• 許多需要執行耗時、緩慢工作的 Web 應用
程式都利用它來在背景執行這些工作
• 使用libevent,而在server-client之間師法
memcached的通訊協定,藉以得到很高的
性能
• 將任務儲存在主記憶體中
beanstalk的效能
*http://adam.heroku.com/past/2010/4/24/beanstalk_a_simple_and_fast_queueing_backend/
beanstalk 的特性
• 輕量化、高效
– 輕量化的通訊協定
– 將工作資訊儲存在記憶體中
• 工作具有優先序
– 支援 32 bits 的優先序表示
• 可將工作永續化
• 分散式容錯能力
• 逾時工作的控制
– 若consumer逾時無法完成工作,則工作會被從
RERSEVED狀態移回READY,供其他consumer繼續處理
beanstalk 中工作的狀態
beanstalk 的 Java Client
• beanstalk 有支援多種語言的客戶端
• Java 版客戶端TrendrrBeanstalk
– https://github.com/dustismo/TrendrrBeanstalk
選擇 Queue 實作的考量因素
• 傳輸的額外負擔
• 儲存的媒介
– 是否具備永續性
• 安全性
– 傳輸的安全性
– 儲存的安全性
• 容錯能力
• 擴展規模的能力
設計就是在做取捨
• 使用beanstalk就是求快
• 選擇犧牲
– 安全性
– 容錯能力
– 永續性
• 對於一個處理關鍵交易工作的工作佇列,
你或許不會考慮使用beanstalk
結論
• Queue 是系統設計時不可或缺的要素
• 透過 Queue 可以得到若干好處,尤其是改
善資源的利用效率
Thanks

排隊應用開發