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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...