- 來源 | 願碼(ChainDesk.CN)內容編輯
- 願碼Slogan | 鏈接每一個程序員的故事
- 網站 | http://chaindesk.cn
- 願碼願景 | 打造全學科IT系統免費課程,助力小白用戶、初級工程師0成本免費系統學習、低成本進階,幫助BAT一線資深工程師成長並利用自身優點創造睡後收入。
- 官方公衆號 | 願碼 | 願碼服務號 | 區塊鏈部落
- 免費加入願碼全思惟工程師社羣 | 任一公衆號回覆「願碼」兩個字獲取入羣二維碼
本文閱讀時長:11min程序員
可伸縮性是指軟件系統隨着使用它的業務增加而增加的能力。 PostgreSQL提供了一些功能,能夠幫助您構建可擴展的解決方案,但嚴格來講, PostgreSQL自己是不可擴展的。它能夠有效地利用單臺機器的如下資源:算法
可是,當涉及將數據庫解決方案擴展到多臺計算機時,它可能很是有問題,由於標準PostgreSQL服務器只能在單個計算機上運行。在本文中,咱們將介紹PostgreSQL中不一樣的擴展方案及其實現。數據庫
系統可擴展性的要求意味着如今支持業務的系統也應該可以以與其增加相同的服務質量來支持相同的業務。後端
假設一個數據庫能夠存儲1 GB的數據,而且每秒有效地處理100個查詢。若是隨着業務的發展,處理的數據量會增加100倍?它可以每秒支持10,000個查詢並處理100 GB的數據嗎?也許不是如今,不是在同一個裝置中。可是,能夠擴展可擴展的解決方案,以便可以在須要時當即處理負載。緩存
在須要得到更好性能的場景中,設置更多服務器以處理額外負載並從主服務器將相同數據複製到它們是很常見的。在須要高可用性的狀況下,這也是將數據連續複製到備用服務器的典型解決方案,以便在主服務器崩潰時它能夠接管。服務器
複製可用於許多擴展方案。其主要目的是在系統出現故障時建立和維護備份數據庫。對於物理複製尤爲如此。可是,複製也可用於提升基於PostgreSQL的解決方案的性能。有時,第三方工具可用於實現複雜的擴展方案。架構
想象一下,有一個系統應該處理大量的讀取請求。例如,可能有一個應用程序實現支持網站上的自動完成功能的HTTP API端點。每次用戶在Web表單中輸入字符時,系統都會在數據庫中搜索名稱以用戶輸入的字符串開頭的對象。因爲用戶數量衆多,查詢數量可能很是大,而且還由於每一個用戶會話都處理了多個請求。爲了處理大量請求,數據庫應該可以使用多個CPU核心。若是同時請求的數量很是大,則處理它們所需的核心數量可能大於單個機器可能具備的核心數量。併發
這一樣適用於應該同時處理多個重度查詢的系統。您不須要大量查詢,可是當查詢自己很大時,使用盡量多的CPU將提供性能優點,尤爲是在使用並行查詢時。負載均衡
在這種狀況下,一個數據庫沒法處理負載,能夠設置多個數據庫,設置從一個主數據庫到全部數據庫的複製,使每一個數據庫做爲熱備用,而後讓應用程序查詢不一樣的數據庫不一樣的要求。應用程序自己能夠是智能的,每次均可以查詢不一樣的數據庫,但這須要應用程序的數據訪問組件的特殊實現,以下所示:微服務
另外一個選擇是使用一個名爲Pgpool-II的工具,它能夠做爲幾個PostgreSQL數據庫前面的負載均衡器。該工具公開了一個SQL接口,應用程序能夠鏈接到那裏,就好像它是一個真正的PostgreSQL服務器。而後Pgpool-II會將查詢重定向到當時執行最少查詢的數據庫; 換句話說,它將執行負載平衡:
另外一種選擇是將應用程序與數據庫一塊兒擴展,以便應用程序的一個實例將鏈接到數據庫的一個實例。在這種狀況下,應用程序的用戶應該鏈接到許多實例中的一個。這能夠經過HTTP負載平衡來實現:
當問題不是併發查詢的數量,而是數據庫的大小和單個查詢的速度時,能夠實現不一樣的方法。能夠將數據分紅多個服務器,這些服務器將並行查詢,而後將查詢結果合併到這些數據庫以外。這稱爲數據分片。
PostgreSQL提供了一種基於表分區實現分片的方法,其中分區位於不一樣的服務器上,而另外一個分區(主服務器)將它們用做外部表。在主服務器上定義的父表上執行查詢時,具體取決於WHERE子句和分區的定義,PostgreSQL能夠識別哪些分區包含所請求的數據,而且只查詢這些分區。根據查詢,有時能夠在遠程服務器上執行聯接,分組和聚合。PostgreSQL能夠並行查詢不一樣的分區,這將有效地利用多臺機器的資源。完成全部這些後,能夠在應用程序鏈接到單個數據庫時構建解決方案,該數據庫將根據要查詢的數據在不一樣的數據庫服務器上物理執行查詢。
也能夠在使用PostgreSQL的應用程序中構建分片算法。簡而言之,應用程序可能會知道哪些數據位於哪一個數據庫中,只在那裏寫入,而且只能從那裏讀取數據。這會給應用程序增長不少複雜性。
另外一種選擇是使用市場上可用的基於PostgreSQL的分片解決方案或開源解決方案。它們有各自的優勢和缺點,但常見的問題是它們基於PostgreSQL的早期版本,而且不使用最新的功能(有時會提供本身的功能)。
最受歡迎的分片解決方案之一是Postgres-XL,它使用運行PostgreSQL的多個服務器實現無共享架構。該系統有幾個組成部分:
· 多個數據節點:存儲數據
· 單個全局事務監視器(GTM):管理集羣,提供全局事務一致性
· 多個協調器節點:支持用戶鏈接,構建查詢執行計劃,並與GTM和數據節點交互
Postgres-XL實現與PostgreSQL相同的API,所以應用程序不須要以任何特殊方式處理服務器。它符合ACID,這意味着它支持事務和完整性約束。該COPY命令也受支持。
使用Postgres-XL的主要好處以下:
Postgres-XL是開源的,但能夠得到商業支持。
值得一提的另外一個解決方案是Greenplum。它被定位爲大規模並行處理數據庫的實現,專門爲數據倉庫而設計。它有如下組件:
· 主節點:管理用戶鏈接,構建查詢執行計劃,管理事務
· 數據節點:存儲數據並執行查詢
Greenplum還實現了PostgreSQL API,應用程序能夠鏈接到Greenplum數據庫而無需任何更改。它支持事務,但對完整性約束的支持是有限的。該COPY命令受支持。
Greenplum的主要好處以下:
缺點以下:
Greenplum有商業和開源版本。
與可伸縮性相關的另外一個用例是當數據庫鏈接的數量很大時。可是,當在具備大量微服務的環境中使用單個數據庫而且每一個數據庫都有本身的鏈接池時,即便它們不執行太多查詢,也可能在數據庫中打開數百甚至數千個鏈接。每一個鏈接都消耗服務器資源,只是處理大量鏈接的要求已經成爲問題,甚至不執行任何查詢。
若是應用程序僅在須要查詢數據庫並在以後關閉它們時才使用鏈接池和打開鏈接,則可能會出現另外一個問題。創建數據庫鏈接須要時間 - 而不是太多,可是當操做數量很大時,總開銷將是巨大的。
有一個名爲PgBouncer的工具能夠實現鏈接池功能。它能夠接受來自許多應用程序的鏈接,就像它是PostgreSQL服務器同樣,而後打開有限數量的數據庫鏈接。它將爲多個應用程序的鏈接重用相同的數據庫鏈接。創建從應用程序到PgBouncer的鏈接的過程比鏈接到真實數據庫要快得多,由於PgBouncer不須要初始化會話的數據庫後端進程。
PgBouncer能夠建立多個鏈接池,它們能夠在如下三種模式之一中工做:
· 會話模式:與PostgreSQL服務器的鏈接用於與PgBouncer的客戶端鏈接的生命週期。這種設置可用於加速應用程序端的鏈接過程。這是默認模式。
· 事務模式:與PostgreSQL的鏈接用於客戶端執行的單個事務。當僅同時執行少許翻譯時,這可用於減小PostgreSQL端的鏈接數。
· 語句模式:數據庫鏈接用於單個語句。而後將它返回到池中,併爲下一個語句使用不一樣的鏈接。此模式相似於交易模式,但更具侵略性。請注意,使用語句模式時,沒法進行多語句事務。
能夠設置不一樣的池以在不一樣模式下工做。
可讓PgBouncer鏈接到多個PostgreSQL服務器,從而起到反向代理的做用。
可使用PgBouncer的方式以下圖所示:
PgBouncer創建了與數據庫的多個鏈接。當應用程序鏈接到PgBouncer並啓動事務時,PgBouncer會爲該應用程序分配現有數據庫鏈接,將全部SQL命令轉發到數據庫,而後將結果傳回。交易完成後,PgBouncer將斷開鏈接,但不關閉它們。若是另外一個應用程序啓動事務,則可使用相同的數據庫鏈接。這樣的設置須要配置PgBouncer以在事務模式下工做。
PostgreSQL提供了幾種實現複製的方法,這種方法能夠維護來自另外一個服務器或服務器上的數據庫的數據副本。這能夠用做備份或備用解決方案,以便在主服務器崩潰時接管。經過使負載能夠分佈在多個數據庫服務器上,複製還可用於提升軟件系統的性能。