您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關PostgreSQL痛點的解決方案是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
內核必須為廣泛的工作負載而工作;它并不總是執行得象一些用戶社區所希望的那么好,這可以說不足為奇。PostgreSQL關系數據庫管理系統項目是一個有時感到有些冷落的社區。在響應 2014年 “Linux 存儲,文件系統,和內存管理”峰會組織者的邀請時,PostgreSQL 開發商 Robert Haas,Andres Freund 和 Josh Berkus 到場來討論了他們最痛苦的問題和可能的解決方案。
PostgreSQL是一個很老的系統,可以追溯到1996;它被很多用戶在多種操作系統上運行。因此,PostgreSQL開發商被他們可以添加的Linux指定代碼的數量所限制。它是基于合作進程的,沒使用線程。系統 V 共享內存用于進程間通信。重要的是,PostgreSQL維護它自己的內部緩沖區,但也使用 I/O 緩沖來讀寫磁盤數據。這種緩沖的組合導致了 PostgreSQL 用戶所經歷的一些問題。
同步緩慢
第一個被描述的問題是關于數據如何從緩沖區高速緩存保存到磁盤上。PostgreSQL 使用了一種形式的日志記錄,他們稱之為“預寫式日志”。變化之處首先寫入到日志中;一旦日志安全的保存在磁盤上,主要的數據庫塊就能被回寫。這個工作中很多都通過一個“檢查點”進程來完成;它寫入日志條目,之后將一批數據寫回到磁盤上的各種文件中。這種帶有日志能力的寫操作相對而言小而連續;他們的工作效果不錯,并且,據 Andres 所說,PostgreSQL 的開發者對系統這部分在 Linux 上的運行情況足夠滿意。[Robert Haas]
數據的寫入則是另一回事。檢查點進程調節這些寫操作,從而避免 I/O 系統壓倒其它一切。但是,當它開始考慮調用 fsync() 來確保數據被安全的寫入,并且所有這些被調節后的寫操作被立即推送到請求隊列時,就導致了 I/O 風暴。據他們說,問題不是因為 fsync() 太慢,而是它太快了。它導出如此多的數據到 I/O 系統,以至于其它任何事情,包括應用程序的讀請求等,都被阻塞住。這為用戶帶來了痛苦,同樣也為 PostgreSQL 的開發者帶來了痛苦。
Ted Ts'o 提問,將檢查點進程限定到 I/O 可用帶寬的特定百分比,是否能有幫助。但 Robert 回應說,I/O 優先級應該更好一些;檢查點進程,在其它進程不需要帶寬時,應該更夠 100% 的使用它。使用 I/O 友好的機制(它會在 CFQ 調度器中控制 I/O 優先級)被提出,但這也有問題:它對 fsync() 調用發起的 I/O 操作不起作用。即使來自檢查點進程的數據被寫入(并非總是如此),當 fsync() 開始真正進行 I/O 操作時,優先級沒有實施上。
Ric Wheeler 建議,PostgreSQL 開發者需要更好的控制他們寫入數據的速度;Chris Mason 補充說,當產生 I/O 請求時,O_DATASYNC 選項可以用來給以更好的控制。這里的問題是,這種方式的實現要求 PostgreSQL 知道存儲設備的速度。
讓我們把討論的話題放回到I/O優先。由于請求隊列的維護是通過I/O調度器實現的,大部分被PostgreSQL用戶所青睞的調度器都傾向于避免使用CFQ調度器(Completely Fair Queueing絕對公平調度器),或者說根本就沒有實現I/O優先機制。這還不是最糟的,甚至,那些提供了I/O優先的地方還限制了請求隊列的長度。一個大數據flush操作將會快速填滿隊列,這個時候I/O優先就會失去大部分的效應。如果沒有空間去容納這些請求隊列,一個高優先級的請求將會失活,無法達到預期的高優先。看來,I/O優先并不能解決問題。
正確的解決之道看起來仍然是那樣的模糊和不著邊際。Ted說如果PostgreSQL的開發者能提供那種通過運行著的數據庫來構建這種I/O模式的小程序,給出一種方法簡單地去復現這些問題,那么,內核開發者就能嘗試多種不同的方式去尋求解決之道。這樣的程序可能類似于PostgreSQL的初始化配置腳本,但是一個單獨的小程序是內核開發者社區更想要看到的。
雙緩沖技術
PostgreSQL需要去做屬于它自己的緩沖技術,因為其有很多情況下由于各種原因會使用I/O緩沖。這就會導致一個問題:數據庫的數據往往會在內存中被存儲兩次,一次是在PostgreSQL的緩沖區,另一次是在頁高速緩沖存儲器(page cache)。PostgreSQL在一定程度上極大地增加了內存的使用次數,對于一個完整的系統是有害的。
大量的內存浪費行為應該被有效地消除。考慮這樣一個例子,在PostgreSQL的cache上有一個臟數據(dirty buffer),它比內核所擁有的在頁高速緩沖存儲器上的數據要新。當PostgreSQL刷新這個臟數據時,頁高速緩沖存儲器被重寫的這一重要過程將不會發生,因此,數據也就不同步了。在這種情況下,PostgreSQL要是能告訴內核去移除在頁高速緩沖存儲器上相應的頁就能好了,可是,現實就是,現在沒有好的API能做這件事。據安德魯(Andres)說調用fadvise()函數的FADV_DONTNEED參數是可以的,實際上,這將引發指定的頁被讀出,幾乎沒人能很好地理解這種行為,但他們都贊成它不應該用這種方式去工作。他們也不可以在沒有映射到文件處理前就使用madvise()函數,這樣做的話,可能大量正在工作著的進程就會變得非常慢。
這種做法看起來不錯,但同時也可能在反方向上移動了一些頁,PostgreSQL可能想要從它自己的緩沖器中移除一個干凈的頁,但是卻在頁高速緩沖器里留下了一份拷貝。可能的情況,或許是一個實際上沒有引發I/O的特殊的寫操作,或許是一個將物理頁面轉換成頁高速緩沖器的系統調用。這些在表面上的討論是挺多的,但是卻沒有那一部分的討論是能給出確切的結論的。
復歸
對于PostgreSQL的用戶來說另外一個問題是經常遇到的,在最近的一些內核特性可能造成了的執行性能上的問題。舉個例子,透明大型分頁(transparent Huge page)特性對于PostgreSQL的工作負載來說沒有任何好處,而且它還明顯地變慢了。顯然,大量時間都被用在那些努力運行著的嚴密代碼上了,但是它們卻沒有真正產生空閑大型分頁(Huge page)。 于是,在許多的系統中,當透明大型分頁(transparent Huge page)功能被關掉,可怕的性能問題就簡單地消失了。
Mel Gorman回答:如果壓縮正在損害性能,這將是一個缺陷。話雖如此,他在相當長的一段時間內沒有發現任何透明大型分頁的缺陷。還有就是,他說,已經發布了一個限制進程數量的補丁,該補丁能在任何給定的時間內執行壓縮。不過,這個補丁的代碼并沒有被合并,因為沒有人的工作負載曾經遇到因太多進程運行壓縮而引發問題。他認為,也許是時候重新審視那個特定的補丁。
另一個痛點來源于區域回收功能,即使整個系統并不缺乏內存,該功能也將在內核中從一些區域回收頁。區域回收減慢了PostgreSQL的工作負載。通常***是在PostgreSQL服務器上簡單的禁用此功能。Andres指出他已經作為顧問多次處理和區域回收有關的性能問題。這對他來說是一個很好的賺錢方式。不過如果能修復這些問題,這將是一件好事。
Mel 說,區域回收模式是在假設系統中所有進程都納入到一個單一的NUMA節點下而寫的。這個假設已經不再有意義了;它很過時了,他說,這個選項的默認值改為“off”。看起來房間里沒人反對這個想法,所以可能會在不久的將來發生一點變化。
PostgreSQL的開發者指出,在一般情況下,內核升級往往是可怕的。Linux內核的性能特點在一個發布版到下一個版本之間往往有很大的不同;這使升級成了一個不確定的事情。有些關于尋找運行PostgreSQL基準的新內核的討論,但沒有得到明確結論。作為一個整體,雖然,這兩個項目的開發者高興怎么談話出來;如果沒有其他的事,這代表了兩個項目之間通信的一種新高度。
關于PostgreSQL痛點的解決方案是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。