2012-04-28 31 views
7

我正在構建一個涉及重要圖像處理的應用程序。我們正在建立一個分佈式莊園,任意數量的渲染機器接收來自RabbitMQ交換機的圖像渲染請求。正在使用mySQL列來實現全局鎖定嗎?

由於在渲染過程中可能會有圖像請求,並且因爲我不想讓兩個渲染服務器重複工作,所以我在mySQL圖像表中創建了一個名爲is_rendering的列作爲布爾值。

當渲染服務器收到使其遵循一系列的步驟,看起來像這樣的請求:

  1. 選擇用於更新的圖像行
  2. 如果is_rendering ==真中止呈現請求
  3. 設置is_rendering == true並提交事務
  4. 渲染圖像並將縮略圖存儲在全局可訪問的商店中
  5. 設置is_rendering == false並返回

它絕對有效,但我擔心這些頻繁的數據庫更新似乎有點愚蠢。此外,我正在考慮渲染服務器在渲染過程中失敗的邊緣情況,並將is_rendering == true離開,從而阻止渲染該圖像。我正在考慮解決此問題的解決方案是將is_rendering列從tinyint(1)更改爲datetime字段,並將鎖定日期存儲爲「true」值,將null作爲「false」值存儲。週期性的服務運行狀況檢查可以在特定時間段內選擇所有具有is_rendering值的行,並在這種情況下釋放鎖。

這是一個理智的方法來解決這個問題,還是有其他更優雅的方法,我應該考慮?

+0

我已經成功實施了多次日期時間字段鎖定方法 – ilanco 2012-04-28 22:40:06

+0

除了引入這樣的列之外,我沒有看到任何其他鎖定方式。只有我會讓它成爲一個狀態,比如'0 = not_rendered,1 =渲染,2 =渲染'。但是也許我誤解了你的工作流程。當然,使用'InnoDB'事務將確保只有一個併發查詢可以將圖像設置爲呈現狀態。 – 2012-04-28 22:40:47

+0

這個方法本身是否合理我不知道,但作爲一個列的另一種選擇,單獨的1:1'is_rendering(int)'表似乎更易於管理。只需添加/刪除記錄,您就不必掃描健康檢查中的所有圖像記錄。但是,如果您同時需要圖像本身,則可能需要額外的工作。 – mkjeldsen 2012-04-28 22:43:08

回答

0

我已經提前完成並更改了實施以使用DATETIME列。

我真的很好奇這裏,如果這是一個糟糕的使用MySQL的一般。從我研究的內容來看,我可以使用Hadoop的ZooKeeper:http://zookeeper.apache.org/doc/r3.1.2/recipes.html或類似Google的內部Chubby系統。由於這只是服務的第一次迭代,我將堅持使用mySQL。

從我在這裏閱讀的內容以及我使用mySQL在線閱讀的方式來產生全局鎖定並不是一個可怕的想法,並且將其更改爲DATETIME列,但有一點不明確的是實施過期策略以處理機器在處理作業過程中關閉的奇怪邊緣情況的最佳方式。

保持一個事務級別的鎖將是另一種方法,但當單個服務器運行多個具有小連接池的線程時它沒有任何意義,它將不必要地綁定連接,儘管它具有構建在客戶端連接丟失時失效。

0

親愛的根據我的理解您的問題,如果您遵循以下規則,您的第一種方法也是正確的: 1)您的表類型是innoDB。 2)您在代碼中使用交易。因爲如果在更新期間發生任何分解,它會回滾。

最後,你的第二種方法也更好。如果您不滿足我提到的要點

+0

我正在使用InnoDB。我認爲堅持整個渲染交易是不明智的。渲染可能需要30多秒才能完成,我正在使用連接池。堅持交易意味着我必須綁定可以在其他地方使用的連接。 – Andrew 2012-04-28 22:49:55