2010-08-15 27 views
1

我正在讀IOCP,並從我瞭解到目前爲止,異步寫入只適用於寫入文件的上下文。通過「文件」,我不是指磁盤文件,而是Windows上的「文件」類型輸出設備。I/O完成端口可以幫助數據庫而不是文件寫入?

我計劃在實施,從客戶需要的郵件服務器以某種方式使用IOCP,然後異步寫入這些消息數據庫(MySQL或SQLite的)。但是,據我所知,IOCP中的異步寫入涉及將數據寫入設備驅動程序 - 而提及「設備驅動程序」似乎排除了在數據庫中使用IOCP和異步寫入的可能性,因爲存在從應用程序編寫者的角度來看,沒有涉及寫入數據庫的「設備驅動程序」。

那麼,IOCP真的可以幫助實現寫入數據庫的服務器嗎?我有一種嘮叨的感覺,我誤解了一些東西。

如果IOCP不能在這種情況下幫助,在那裏我應該考慮實施,做異步寫入數據庫的Windows服務器什麼的任何建議?

回答

0

它們可以幫助您在寫入文件的任何地方提供幫助,並且在發生任何事情時不想阻止它們。很難想象一個數據庫想要這樣做,除非編寫完整無關的文本日誌文件。

0

IOCP在實施數據庫時可以提供很大幫助。

IOCP結合FILE_FLAG_NO_BUFFERING和FILE_FLAG_WRITE_THROUGH和正確對齊塊可以讓數據庫引擎控制緩存行爲,避免不必要的重複緩存和塊拷貝,得到正確的順序寫入,這在任何同一時間寫可以在飛行控制等

當然的數據庫需要實現使用這些功能,使用SQLite和MySQL中,你得到別的東西。

,詳細瞭解如何做到這一點與實施數據庫幫助,「事務處理:概念與技術」 Gray和路透社是一個很好的參考。

2

通常情況下,數據庫會爲您提供一個用於寫入的API。這通常會隱藏它所做的所有複雜事情。有時候,這個API可能是通用的,並且可以與很多數據庫一起工作,比如OLE-DB和ODBC,有時API也可能是數據庫特定的。

這是不可能的,你使用的數據庫將暴露的API,它是低級別就夠用了IOCP儘管它可能在內部使用IOCP。

你可能想會問什麼是,我可以使用異步寫入寫信給我的數據庫,也就是說,你可以把火關DB寫入沒有阻斷在做了「發射了」線程。

雖然當您的服務器的其餘部分使用IOCP與其自己的日誌文件和套接字讀取/寫入進行通信時,IOCP「友好」數據庫API會很好,但您可以使用線程池來允許您可以發出數據庫API所需的阻止調用,而不會阻塞服務器執行的其他工作。我傾向於將其稱爲「業務邏輯線程池」,它與我用於所有非阻塞I/O的IOCP線程池分開。

我寫了一些關於構建使用這種設計寫入數據庫的服務器的文章,代碼和文章鏈接可以在here找到。

1

Io完成端口是一種多功能機制,可以通過多種方式實現可擴展性。

在「最佳」情況下,Io完成端口與正在與Io重疊使用的OS句柄相關聯。但實際上這並不是必需的:Io Completion Port機制足以提供可擴展性,即使所有使用的API都被阻止和/或不公開所需的句柄。

在一個非常簡單的模型中,可以使用CreateIoCompletionPort - 調用PostQueuedCompletionStatus來創建用戶定義的「作業」。創建一個工作線程池,所有工作線程都在GetQueuedCompletionStatus上循環 - 只需在處理排隊作業時在工作線程內調用阻塞Io例程。每當一個工作線程阻塞任何內核函數時,Io完成端口機制將看到併發計數很低,並釋放另一個工作線程。

顯然,使用這種方式,活動工作線程的數量可能會超過併發計數,但假設這些工作是對稱的,那麼當線程返回到其GetQueuedCompletionStatus調用時,它應該很快地自行解析。