Pgbouncer最佳實踐 之 池模式篇

瞭解更多Greenplum技術乾貨,歡迎訪問Greenplum中文社區網站

《Pgbouncer最佳實踐》系列已經連載到了第三篇,第一篇 概念篇 介紹了數據庫鏈接池在Pgbouncer中的三種方式。爲何使用鏈接池,使用與不使用之間的性能差別,以及鏈接池模式的工做流程、細節及一些注意事項等內容。第二篇 性能提高篇介紹了Pgbouncer帶來的性能提高的相關測試。數據庫

第三篇,本文將詳細介紹事務池、會話池和語句池。segmentfault

Pgbouncer具備三種可用的池模式:事務模式,會話模式和語句模式。在Greenplum中,gpboucner的池模式和pgbouncer相同。安全

事務鏈接池

數據庫客戶端不多在不間斷的狀況下執行連續的事務。而是一般在事務之間執行非數據庫工做。這意味着服務器鏈接在等待新工做到達時會花費大量時間空閒。服務器

事務池模式試圖減小服務器鏈接的空閒時間,以下所示:網絡

  • 池程序在開始事務時將服務器鏈接分配給客戶端。
  • 客戶端的事務完成後,池程序將釋放鏈接分配。

注意事項:併發

  • 若是客戶端運行多個事務,則每一個事務能夠在不一樣的服務器鏈接上執行。
  • 單個服務器鏈接能夠在其生命週期內運行由不一樣客戶端發出的事務。

圖 6 事務鏈接池負載均衡

與服務器所容許的鏈接相比,容許活動客戶端的數量要多得多。儘管取決於給定的工做負載,但常常會看到10倍或更多的活動客戶端鏈接與服務器鏈接比率。socket

這確實帶來了一個重要的警告:客戶端再也不指望對數據庫會話狀態所作的更改在同一客戶端進行的連續事務中繼續存在,由於這些事務可能在不一樣的服務器鏈接上運行。此外,若是客戶端進行會話狀態更改,它們可能而且極可能會影響其餘客戶端。post

如下是一些使用上面的事務池示例:性能

  • 若是客戶端1在T1中的第一個服務器鏈接上將會話設置爲只讀,而客戶端2的T3是寫事務,則T3將失敗,由於它在如今的只讀服務器鏈接上運行。
  • 若是客戶端1運行PREPARE a1 AS ...在T1上運行EXECUTE a1 ...,在T2上,則T2將失敗,由於預編譯語句對於運行T1的服務器鏈接是本地的。
  • 若是客戶端2在T3中建立了一個臨時表並嘗試在T4中使用它,則T4將失敗,由於該臨時表對於運行T3的服務器鏈接是本地的

有關使用事務池時不支持的會話狀態功能和操做的完整列表,請參見PgBouncer的列表。

會話鏈接池

分配給客戶端的服務器鏈接在客戶端鏈接的整個生命週期內持續。這看起來好像根本不使用鏈接池同樣,可是有一個重要的區別:當分配的客戶端斷開鏈接時,服務器鏈接不會被破壞。當客戶端斷開鏈接時,池管理器將:

  • 清除客戶端所作的任何會話狀態更改。
  • 將服務器鏈接返回到池中,以供其餘客戶端使用。

圖 7 會話鏈接池

語句鏈接池

在此,服務器鏈接分配僅在單個語句的持續時間內持續。這具備與事務池模式相同的會話狀態限制,同時還破壞了事務語義。

圖 8 語句鏈接池

這使得全部客戶端鏈接的行爲就像在「自動提交」模式下同樣。若是客戶端嘗試開始多語句事務,則合併程序將返回錯誤。

表 3 鏈接池模式對比

從上述對比狀況來看,在鏈接池的選擇上,須要依據業務環境特色來進行選擇,默認狀況下推薦使用事務鏈接池,它兼顧了執行事務的特性,尤爲多語句的支持,而且不會像會話鏈接池那樣,嚐嚐處於等待狀態。固然事務模式並不支持預編譯語句。而根據具體業務場景的特殊須要,有些時候須要客戶端與服務器端保持鏈接,或者支持預編譯語句,這樣只能選擇會話池模式。還有一些特例狀況,某些業務場景只是單語句執行,那麼語句池模式可能更適合。所以對比這三種模式,能夠發現從對客戶端操做的支持程度來說,會話池支持度最高,其次是事務池,最後是語句池模式。可是從支持的鏈接數來說,可能恰好是相反的順序。

表 4 SQL特性對照表

上表爲會話鏈接池和事務鏈接池的SQL特性對比狀況,能夠經過對比具體業務場景與SQL特性的符合度,來對鏈接池模式進行選型。

下面列舉了一些示例場景:

  • 有些只運行快速查詢,所以在沒有事務的狀況下能夠共享一個會話來處理上百個併發查詢。
  • 一些角色成員對於會話級併發是安全的,而且老是使用事務。所以,他們能夠安全地共享數百個併發事務的多個會話。
  • 有些角色過於複雜,沒法與其餘人共享會話。所以,您對它們使用會話池模式能夠避免當全部「插槽」都已佔用時鏈接錯誤。
  • 不要使用它代替HAProxy或其餘負載均衡器。儘管pgbouncer具備一些可配置的功能來解決負載均衡器要解決的問題,例如dns_max_ttl,而且能夠爲其設置DNS配置,可是大多數產品環境都使用HAProxy或其餘用於HA的負載均衡器。這是由於HAProxy確實擅長以循環方式在服務器之間實現負載平衡,而不是pgbouncer。儘管pgbouncer對於postgres鏈接池更好,但最好使用一個小型守護程序來完美地執行一項任務,而不是使用較大的守護程序來完成兩項任務,那樣效果更糟。

在對於鏈接數的建議值來說,上文也給出了一個大體的結果,就是通常狀況下設置爲CPU核數的3-4倍左右,固然這個不是絕對值,應該是在與業務場景相似的硬件環境中充分進行測試後,纔可以得出具體的數值。

還有一點須要注意的是鏈接Pgbouncer的鏈接方式,網絡鏈接和unix socket鏈接方式,較網絡鏈接,unix socket方式可能更加節省網絡通訊的開銷,所以若是pgbouncer和數據庫在一臺機器部署,能夠優選該方式;若是處於不一樣服務器上,則選擇網絡鏈接。

做者簡介

原文做者:王志斌,曾得到中國PostgreSQL數據庫管理工程師(PGCE),是PostgreSQL官方認證講師,盤古云課堂特邀金牌講師。

本文僅表明做者我的觀點,與官方無關。

image

相關文章
相關標籤/搜索