GaussDB(DWS)集群通信:詳解pooler連接池

来源:https://www.cnblogs.com/huaweiyun/p/18065439
-Advertisement-
Play Games

本文分享自華為雲社區《GaussDB(DWS) 集群通信系列一:pooler連接池》,作者:半島里有個小鐵盒。 1.前言 適用版本:【8.1.0(及以上)】 GaussDB(DWS) 為MPP型分散式資料庫,使用Share Nothing架構,數據分散存儲在各個DN節點,而CN不存儲數據,作為接收查 ...


本文分享自華為雲社區《GaussDB(DWS) 集群通信系列一:pooler連接池》,作者:半島里有個小鐵盒。

1.前言

適用版本:【8.1.0(及以上)】

GaussDB(DWS) 為MPP型分散式資料庫,使用Share Nothing架構,數據分散存儲在各個DN節點,而CN不存儲數據,作為接收查詢的入口,生成的計劃會儘量下推到DN並行執行以提升性能,此過程中會產生大量的建連操作,使得通信開銷變得很大。因此在大數據時代,集群規模越來越大,業務併發越來越高,資料庫集群各節點間的通信壓力也越來越大。GaussDB(DWS)集群通信技術,在大規模集群中可以承載高併發業務,能夠實現高性能分散式通信系統。

2.背景

GaussDB(DWS) 中客戶端執行查詢流程如上圖所示,其中具體的如下:

  1. 客戶端向CN的監聽埠發起連接;
  2. CN postmaster主線程accept連接,創建 postgres線程並將連接交給此線程處理;
  3. 客戶端下發query到CN;
  4. CN的postgres線程將查詢計划下發給其他 CN/DN,查詢結果沿原路徑返回到客戶端;
  5. 客戶端查詢結束,關閉連接;
  6. CN上對應的postgres線程銷毀退出;

CN與DN建連立流程,和客戶端與CN建連立流 程基本相同。因此為了減少CN與DN建立連接,以及DN進程中postgres線程創建、銷毀的開銷,CN端實現了Pooler連接池。

3.Pooler連接池

img

如上圖所示,CN的pooler連接池中會保存與其他CN/DN的連接,每一個連接在對端會對應一個postgres工作線程。

postgres工作線程是帶狀態屬性的,如database,所以可以認為pooler連接池中的連接也是帶屬性的。不同屬性間的連接是不能復用的,如上圖所示,按不同屬性切分為pool A/B/C等連接池。每個連接池中會存有連接往不同節點的空閑連接的數組,提供介面給外部使用或放入連接。

CN上的postgres工作線程在需要連接其他節點時,會創建一個本地agent,嘗試從pooler連接池取跟本線程相同屬性的空閑連接,pooler如果沒有空閑連接,就會新建一個連接。連接交給agent後,可以視為線程私有。線上程退出時,agent才會將連接還給pooler。

接下來,我們從數據結構上來看看Pooler連接池實現原理:

空閑連接池

DatabasePool

/* All pools for specified database */
typedef struct databasepool
{
    char    *database;
    char    *user_name;
    char    *pgoptions; /* Connection options */
    HTAB    *nodePools; /* Hashtable of PGXCNodePool, one entry for each node */
    MemoryContext mcxt;
    struct databasepool *next; /* Reference to next to organize linked list */
} DatabasePool;

DatabasePool *databasePools = NULL;

進程級別數據結構

DatabasePool用於存儲空閑連接,根據database,user_name,pgoptions三者來確定
如果通過三者查找到了,那麼就取其中對應的nodePools,找不到則新加

nodePools中對應的數據結構為PGXCNodePool,用於存儲本節點與其他每個cn/dn的連接,具體的保存如下

cn1[0,1,2,3,4,…]

dn1[0,1,2,3,4,…]

NodePool

typedef struct NodePool
{
    Oid nodeoid; /* Hash key (must be first!) */
    bool valid;
    ArrayLockFreeQueue pool;
} PGXCNodePool;

進程級別數據結構

連接到某一節點的空閑連接的集合,通過無鎖隊列(數組)實現
從這裡拿到對應的連接,直接復用

正在使用連接池

AgentPool

typedef struct
{
    ArrayLockFreeQueue pool;
    AgentSlot* slots;
}AgentPool;

進程級別的數據結構

存放一個進程中的所有的連接

其中slots為一個數組,表明一個槽位,與pool為一一對應的狀態
用於保存所有線程持有的連接,即poolAgent數據結構

AgentSlot

typedef struct
{
    int index;
    volatile AgentStatus status;
    PoolAgent* agent;
}AgentSlot;

進程級別數據結構

存放進程中的某一個連接

index與AgentPool->pool相關聯

status狀態為,標識該連接是否正在使用/空閑/持有

agent中為某個線程的信息(也就是每個session),都是在全局數組poolAgents中保存的

PoolAgent

typedef struct
{
    /* Agent members */
    ThreadId        pid;
    DatabasePool*   pool;
    int             index;

    /* param members */ 
    char*           user_name;
    char*           pgoptions;
    char*           paramsStr;
    char*           localParams;   /* params temporarily saved before commit */
    char*           tempNamespace; /* temp namespace name of session */
    List*           paramsList;    /* save session params, for build paramsStr */
    int             paramsReady;    /* param is set, need rebuild paramsStr */

    /* Connection members */
    int             dnNum;
    int             cnNum;
    PoolSlot**      dnConn;
    PoolSlot**      cnConn;
    NodeConnDef*    cnDef;
    NodeConnDef*    dnDef;

    /* handles members */
    NodeHandle** dnHandles;
    NodeHandle** cnHandles;
    int dnUsed;
    int cnUsed;
} PoolAgent;

對於每起一個線程session(即連接),都會有一個PoolAgent與之對應,即從DatabasePool->NodePool->pool取出來的連接

  • cnDef、dnDef:初始化時從pgxc_node中拿到,即cn定義、埠、ip
  • (session級別)dnConn、cnConn:從databasePools->nodePools-> pool拿真正對應的連接
  • (query級別)dnHandles、cnHandles:從dnConn、cnConn裡邊dop出來使用,確保兩者是一一對應的狀態,當query結束時,只需要close handles就行,cnConn不需要close

Pooler連接池具體的復用流程如下:

  1. session需要連接時,通過DB+USER為key找到正確的pooler連接池,優先從中取走現有連接,如果連接池中沒有連接的話,則新建連接;
  2. query結束後,CN的postgres線程並不會歸還連接,連接可以用於當前session的下一個查詢;
  3. session結束後,CN的postgres線程會將連接還到對應的pooler,連接對應的DN上的postgres線程並不會退出,處於ReadCommand中,等待復用後CN新的postgres線程發起任務;

4.Pooler連接池相關的視圖

pg_pooler_status視圖

pg_pooler_status視圖記錄了pooler連接池中的所有連接信息,每一行表示本CN發起的一個連接,對應對端進程的一個postgres線程

postgres=# select * from pg_pooler_status;
 database | user_name | tid |  node_oid  |  node_name   | in_use | node_port | fdsock |   remote_pid    | session_params
----------+-----------+-----+------------+--------------+--------+-----------+--------+-----------------+----------------
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |     94 | 140259241618584 | none
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |    101 | 140259241619432 | none
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |     91 | 140259241618160 | none
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |     95 | 140259241619008 | none
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |     59 | 140259241562192 | none
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |    106 | 140259241619856 | none
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |    108 | 140259241620280 | none
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |    117 | 140259241621128 | none
 postgres |   user1   |     | 2147483650 | datanode1    | f      |     37110 |    114 | 140259241620704 | none
  • in_use為‘t’表示這個連接正在某線程使用,為‘f’表示空閑連接等待復用
  • tid列為本CN的持有此連接的線程號
  • node_name列為對端進程號,remote_pid列為對端線線程號
  • 在query_id為0或CN/DN不一致時,通過pooler視圖查找CN與DN連接關係

一般pooler連接池中的連接會非常多,可以按不同欄位group by查看某個db pool池中的連接情況,或連往某個node的連接情況,如:

select database,user_name,node_name,in_use,count(*) from pg_pooler_status group by 1, 2, 3 ,4 order by 5 desc limit 50;

5.Pooler連接清理

清理Session持有的連接

  • cache_connection,是否使用pooler連接池緩存連接,預設開
  • session_timeout,客戶端連接空閑超時後報錯退出歸還連接
  • enable_force_reuse_connections,事務結束後強制歸還連接
  • conn_recycle_timeout(8.2.1),CN空閑session超時後歸還連接

Pooler空閑連接池中的連接

  • pg_clean_free_conn視圖/函數,清理1/4的空閑連接池連接,CM定期調用
  • CLEAN CONNECTION語法,清理對應DB或user的所有空閑連接 clean connection to all for database postgres to USER user1;

6.總結

本文詳細介紹了Libcomm通信庫及其原理,讓我們更好的理解GaussDB(DWS)集群通信中的具體邏輯,對於GaussDB通信運維也具備一定的參考意義。

 

點擊關註,第一時間瞭解華為雲新鮮技術~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目錄一.下載鏡像二.鏡像安裝三.繼續進行虛擬機設置四.虛擬機啟動設置一些供參考的視頻教程 一.下載鏡像 官網鏡像下載地址(需要開梯) 清華大學鏡像站地址 二.鏡像安裝 三.繼續進行虛擬機設置 四.虛擬機啟動設置 點擊虛擬機後滑鼠就不會出VMare,想要滑鼠返回個人的電腦,則按下Ctrl+Alt 一 ...
  • STM32F103xC,xD,xE引腳定義 由於在使用STM32系列晶元過程中發現互聯網沒有整理好的引腳定義,因此自己整理一份,方便以後查閱。 GPIOA Pin 重新上電時的功能 預設功能 重映射 PA0 PA0 WKUP/USART2_CTS/ADC123_IN0/TIM2_CH1_ETR/TI ...
  • STM32標準庫通用定時器PWM生成 1. 初始化 void TIM2_Init() // 定時器2初始化 { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); // 使能定時器2的時鐘 RCC_APB2PeriphClockCmd(RCC_AP ...
  • Ansible 是一種自動化運維工具,基於 Paramiko 開發的,並且基於模塊化工作,Ansible 是一種集成 IT 系統的配置管理、應用部署、執行特定任務的開源平臺,它是基於 Python 語言,由 Paramiko 和 PyYAML 兩個關鍵模塊構建。集合了眾多運維工具的優點,實現了批量系... ...
  • 一:修改伺服器埠 訪問tomcat主頁的時候,輸入的是localhost:8080,說明tomcat的埠是8080,那麼怎麼修改埠號呢? 我們要先認識配置文件 用瀏覽器打開tomcat下conf子目錄server.xml 這一句的意思是通過8005埠發送大寫的“SHUTDOWN”,會關閉服務 ...
  • 根據微軟發佈的Windows 11操作系統要求,這個版本的系統需要硬體支持受信任的平臺模塊 (TPM) 才能進行安裝和使用,不然就會提示你“這臺電腦無法運行Windows11。這臺電腦不符合安裝此版本的Windows所需的最低系統要求。有關詳細信息,請訪問https://aka.ms/Windows ...
  • proxy_set_header 是 Nginx 配置中的一個重要指令,特別是在使用 Nginx 作為反向代理時。該指令允許你修改由 Nginx 傳遞給代理後端的請求頭。這對於確保後端應用程式能夠接收到正確的客戶端信息(如 IP 地址、主機名等)以及控制緩存行為等場景非常有用。 以下是 proxy_ ...
  • 集群部署方案(2 Master + 3 Worker) Apache DolphinScheduler官網:https://dolphinscheduler.apache.org/zh-cn Apache DolphinScheduler使用文檔:https://dolphinscheduler.a ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...