用python作分佈式定時器

分佈式任務系統 (Python)

github地址 https://github.com/thomashuang/Lilac/blob/master/README.rstpython

這裏將介紹Liac的設計架構,首先分佈式任務系統的定義是在多臺服務器執行定時任務。mysql

實現技術

  1. 分佈式定時調度,能夠同時在不一樣服務執行。
  2. 使用Leader/Follower Pattern 多線程模式。
  3. 只是週期定時,crontab定時,定點任務。
  4. 重試失敗任務。
  5. 線程安全db api,支持讀寫分離模式
  6. 使用data-mapper模式
  7. web ui化管理工具(使用MVC,基於 mako gevent cherrypy)

定時任務的類型

一次性定時任務

在未來某個時間點須要執行一次git

週期性任務

對於週期性任務最爲簡單的就是間隔性執行任務,好比每五分鐘須要執行一次。github

如何作到分佈式任務

從分佈式的理解來看,須要一種機制保證正常給各個任務執行服務準確及時的分派任務,並卻要減小各個服務之間競爭。因而最簡單的任務執行者向任務管理服務所要當前能夠執行服務。回分派相關任務,當執行任務完須要彙報給任務調度管理服務,並籌劃任務下一步的狀態。但這裏設計原理並不是如此,對於任務管理器而言,只是做任務的的長久序列化,對於怎麼提取,任務的執行狀態(完成,失敗,重試等),都由任務執行者決定。web

分派流程

  1. 定時服務生成惟一task標識符,依據下次執行時間在db標記任務。
  2. 依據task標識符獲取可執行任務。
  3. 執行任務,保存刷新最新狀態。

使用MYSQL如何作到任務的分派

使用關聯數據數據,而非內存數據庫好比heaq作任務調度,可能有些開始讓人難以理解。如今有不少任務執行服務,在領取任務時,首先生成一個一個具備惟一性標識的(uuid)的對mysql的cron表作更新 UPDATE cron set task_id=$identify WHERE task_id IS NULL AND next_run<now() LIMIT $take_size; 這樣標識了當前服務的可執行的任務。而後使用SELECT × FROM cron WHERE task_id=$identify, 因而就能拉當前服務能夠執行任務。而後對於任務的是什麼,該怎麼執行。sql

任務線程池的設計與優化

對於scheduler任務的執行,由於一次認領多個任務,最初是想使用生產消費者模式,若是master線程與工人線程共享隊列,會形成任務競爭激烈。因而優化成每一個工人線程擁有本身的任務隊列,master線程輪詢分派任務,但這樣,減小了線程對資源的競爭,但在空閒時,若是沒有特殊處理可能形成cpu的佔用。最後使用的是一種leader follower的變種。master線程僅負責分派任務。 follower將在掛起與任務執行(processing)狀態轉換。另外這樣可能任務衆多,若是線程池沒有空閒線程怎麼辦,辦法是將這些任務放入一個閒置隊列,加入一個心跳(定時器)線程負責閒置任務的再次分配。對於python而言,真正的優化在於減小任務空閒時對cpu的搶佔。數據庫

數據層

最初設計時,考慮到對多數據庫的支持。首先使用記錄(activerecord)模式,這種模式把模型與數據落地放置與同一個類,隨着業務的複雜後,模式優點愈來愈小,形成數據落地層行爲與模型行爲的混淆。爲了維護性與後期的拓展性。最終採用了data-mapper模式,這樣在拓展多數據庫支持時,僅僅考慮數據落地層的接口重寫,一樣也爲後期的數據庫接口優化提供了空間。api

值得一提的是,在使用mysql做爲數據庫,由於使用mysqldb因此須要簡單的封裝一個鏈接池,並簡化接口的使用。db模塊有三個重要的接口setup 將幫助設置數據庫, query將用於select的查詢,execute是用來作增刪改的語句,由於這樣更方便數據庫的讀寫分離。安全

setup

setup將用來註冊數據庫,若是指定slave爲true,這個數據庫將會註冊到讀數據庫
key用來標示數據庫,默認註冊到default。
須要注意的是你必須先註冊一個master數據庫才能註冊從數據庫。服務器

query

用於select的查詢語句,指定many時將會使用mydqldb的fetchmany接口,key用來標示數據庫,默認爲default。

execute

對於insert語句將會返回lastwordid
而update與delete將會是rowcount。

web 管理平臺

web管理平臺使用的cherrypy與routes mako實現,考慮到cherrypy也許有些慢。因而給cherypy打上猴子補丁,而使用gevent的wsgiserver。 功能基本實現了簡單的用戶角色和任務管理功能。

相關文章
相關標籤/搜索