2012-06-12 37 views
2

我正在一個debian-64上運行一個專門的DB守護進程,內存64G,磁盤空間很大。它使用磁盤哈希表(mmaped),並使用正常的write()調用將實際數據寫入文件。當進行大量更新時,mmap的很大一部分會變髒,並且頁面緩存會嘗試將其刷新到磁盤,從而產生大量隨機寫入,從而降低對數據文件進行常規(順序)寫入的性能。如何優先write()通過mmap更新(或延遲mmap頁面緩存刷新)

如果有可能延遲頁面緩存刷新mmaped區域性能會提高(我認爲),因爲髒頁面的幾個(或全部)更改將一次寫入而不是每次更新一次(最差事實上,它當然會彙總很多變化)。

所以我的問題:是否有可能延遲頁面緩存刷新內存映射區域?或者有可能優先考慮正規寫作?還是有人有任何其他想法? madvise和posix_fadvise似乎沒有任何區別...

回答

3

你可以玩在/proc/sys/vm可調。例如,增加dirty_writeback_centisecs中的值可以使pdflush的喚醒次數減少一些,增加dirty_expire_centiseconds,這樣數據就可以保持更長的時間,直到它必須寫出,並且增加dirty_background_ratio以允許更多的髒頁在RAM必須保留之前保留在RAM中做完了。
請參閱here瞭解所有值的具體內容。

注意,這會影響到你的機器上過程,但看到你是如何運行一個龐大的數據庫服務器,有機會,這是沒有問題的,因爲你不希望別的在同一臺機器上運行無論如何。

當然這會延遲寫入,但它仍不能完全解決與write競爭的髒頁回寫問題(儘管如果有很多更新,它可能會崩潰一些寫入)。
但是:可以使用sync_file_range系統調用,迫使開始寫出來的頁面在給定範圍上的「寫」文件描述符(SYNC_FILE_RANGE_WRITE)。因此,雖然髒頁面將在稍後的某個未知時間回寫(並且具有更大的寬限期),但您可以手動啓動對感興趣的頁面的回寫。
這不給任何保證,但它應該只是工作。

務必絕對肯定地閱讀文檔,更好地閱讀兩遍。如果使用錯誤,sync_file_range可能很容易損壞或丟失數據。尤其是,如果您追加到文件中,則必須確保元數據保持最新並刷新,否則在「崩潰」情況下,「已成功編寫」的數據將「丟失」。

+0

這聽起來很合理(儘管我認爲我也必須增加dirty_ratio),我會在接下來的幾周內嘗試一下,並讓你知道結果。謝謝! –

+0

它的工作原理和減少磁盤I/O預期:) –

+0

@HugoWalter:很高興聽到:) – Damon

0

我會嘗試mlock。如果你的mlock有關的存儲器範圍,它可能會防止發生刷新。完成後您可以munlock

+1

雖然mlock可能會工作,但它不是通過避免沖洗。這是因爲fysical內存將堅持地址範圍,所以頁面在被刷新後(並且很長時間沒有被引用)後不會被盜取。確切的問題當然是訪問哈希表將是非常稀疏和虛假的:有可能某個頁面很長時間不會被引用(並且會被LRU從核心中刪除)。Mlock可能會工作(如果內存不太緊) – wildplasser

+0

問題不在於它需要從磁盤重新加載散列表的相關部分(散列表並不是那麼稀疏和大,我嘗試了一個場景其中一切都適用於RAM,包括數據),問題是頁面實際寫入操作會導致重要的磁盤I/O(因爲它們經常變髒),這會減慢寫入數據文件的速度(當然這是不可避免的,但問題是它是否可以減輕) –

+0

問題是在(好的)散列表中,訪問模式總是分散的。在包含N個頁面的散列表上發佈N個更新,將會達到(2/3)\ * N個頁面。只有約。 N/3頁將不會被擊中。避免這種情況的唯一方法是不使用mmap(或匿名/私有映射),並且發明一些其他方式將更新應用於磁盤文件。 – wildplasser