GaussDB(DWS)應用實踐丨負載管理與做業排隊處理方法

摘要:本文用來總結一些GaussDB(DWS)在實際應用過程當中,可能出現的各類做業排隊的狀況,以及出現排隊時,咱們應該怎麼去判斷是否正常,調整一些參數,讓資源分配與負載管理更符合當前的業務;或者在做業阻塞的時候,怎麼去處理這些狀況,讓業務馬上恢復正常。

概述

數據庫系統的負載管理和資源管理,在整個系統中起着很重要的做用,好比不少用戶的業務壓力過大時,有時會致使鏈接數量被佔滿,有時會致使某種計算資源被佔滿,有時會致使存儲空間被佔滿,這些狀況都會致使整個集羣進入異常甚至不可用的狀態:正在執行的做業互相爭搶CPU,會致使你們都不能好好執行;大量做業執行時,佔用大量內存,很容易觸發到內存瓶頸,形成做業內存不可用問題,致使業務報錯等等。在不進行併發控制的狀況下,這些狀況都極可能會出現,影響到正常業務。數據庫

本文用來總結一些GaussDB(DWS)在實際應用過程當中,可能出現的各類做業排隊的狀況,以及出現排隊時,咱們應該怎麼去判斷是否正常,調整一些參數,讓資源分配與負載管理更符合當前的業務;或者在做業阻塞的時候,怎麼去處理這些狀況,讓業務馬上恢復正常。session

本文分爲如下幾個小節去介紹並解答以上問題:併發

  • 1、負載管理簡介:雙層排隊簡述
  • 2、經常使用視圖以及使用方法介紹
  • 3、負載管理常見問題以及處理
  • 4、部分負載管理配置方案介紹
  • 5、小結

1、負載管理簡介:雙層併發控制簡述

DWS的負載管理分爲兩層,第一層爲cn的全局併發控制,第二層爲資源池級別的併發控制。在經過第一層控制的時候,會繼續向前走到第二層資源池控制,根據資源池當前的負載資源狀況決定做業繼續執行或者排隊。ssh

DWS併發控制邏輯示意圖以下:高併發

從本圖的邏輯咱們能夠看到,實際做業執行中,可能會在兩種隊列中排隊:post

一種是全局隊列(global queue),這種隊列不區分簡單和複雜做業,也不區分是DDL或者是普通語句,優化

一種是資源池隊列(resource pool queue),用戶下發的通常語句會根據資源消耗估算以及複雜程度在這裏進行判斷是否排隊。spa

在兩層隊列的過濾下,DWS會篩選出當前能執行的語句,使其正常運行,運行時也會受到其所屬資源池資源的限制(只能使用資源池配置的CPU、內存、IO配額)。線程

2、經常使用視圖以及使用方法介紹

這裏介紹幾個經常使用視圖以及SQL語句,能夠迅速判斷目前的業務出現問題的緣由,受限根據如下視圖能夠看到目前的做業是否是在排隊,以後要迅速分析爲何在排隊,是由於負載管理各個參數配置問題,仍是由於正在執行的語句佔據了過多的資源致使的排隊。設計

  • pgxc_stat_activity(pg_stat_activity)

經常使用語句:

#查詢當前執行時間最長的語句的排隊狀態,query_id(數據庫中做業的惟一標識),以及詳細的語句信息。
select coorname,usename, current_timestamp-query_start as duration, enqueue,query_id,query from pgxc_stat_activity where state='active' and usename <> 'Ruby' order by duration desc;

根據該語句能夠迅速判斷出哪些語句執行時間很長,是什麼樣的語句執行很慢以及該語句的query_id,便於迅速進入下一步排查。

執行結果以下:

上圖解說:圖中爲在沒有做業的狀況下查詢,能夠看到有幾個WLM的語句已經執行了不少,不過這兩個是內部常駐線程,因此不影響業務,也不會佔用鏈接數等數據庫資源。

其他的行能夠看到有bi用戶,在執行一些做業,時間大概1-6分鐘左右。

  • pg_session_wlmstat (記錄每一個cn的語句執行狀況,資源使用狀況,排隊狀況等信息)

經常使用語句:

#查詢每一個用戶下的做業執行狀況,排隊狀況以及做業的複雜狀況和內存消耗狀況。
select usename,enqueue,datname,status,attribute,count(*),sum(statement_mem) from pg_session_wlmstat group by 3,1,2,4,5 order by 1,3,4,5 ;

執行結果以下:

上圖解說:

上圖中說明當前鏈接的cn中有用戶名爲usr1的用戶執行做業,而且在資源池上排隊(第一節介紹的resourcepool隊列),數據庫爲postgres,做業在排隊因此當前status爲pending狀態。

其餘字段包括做業的屬性和當前使用內存資源的總和狀況(根據該數值能夠看出是否由於內存資源不足而進入排隊狀態)。做業在排隊時候不涉及到資源消耗,所以可能沒有具體數值。

  • pgxc_thread_wait_status(查看數據庫中各個線程的執行狀況,當前在等待哪一步驟執行完成,在哪一個實例等待,均可以經過該視圖查詢);

經常使用語句:

#在根據pgxc_stat_activity查詢到具體執行時間長的語句以後,能夠根據本視圖查詢:
select * from pgxc_thread_wait_status where query_id = xxxxxxxx;

該語句能夠查看執行慢語句的阻塞點,語句卡住時,能夠經過該語句查看語句卡在了哪一個步驟。

舉例以下:

上圖能夠看到做業在wait io,此時能夠檢查下磁盤的讀寫速度是否,raid卡讀寫策略是否正常等等。

當出現排隊的時候,wait_status通常的狀態是waiting in ccn queue/waiting resourcepool queue等狀態。

  • 查詢併發數量的方法,就是查看pgxc_stat_activity中,狀態(state字段)是active的語句,enqueue字段爲null的語句,除此以外,idle in transaction之類狀態的語句,也會佔用一個併發數量,由於一個事務塊的業務還未提交,天然也算是正在執行的業務,對於這種狀況,後續能夠考慮進行一個處於此類狀態的超時時間的控制。

3、負載管理常見問題

通常當業務上發現任務阻塞時,能夠從後臺查詢部分語句排查目前的狀況,此時要先看下現象上是什麼狀況,通常併發控制有如下幾種現象,暫時先列出這麼多,後續繼續補充:

1. 業務反饋沒法鏈接到數據庫,好比DS鏈接一直轉圈,過一段時間以後會超時報錯。

  • 此時能夠開始排查當前的配置狀況,通常鏈接不到數據庫,實際上是一種表象,主要是由於做業已經進入了排隊的狀態,語句自己就有不少在排隊,沒法執行,此時用ds鏈接以後,ds自己就會下發語句查詢一些系統表之類的信息,因此也會進入排隊的狀態,在客戶層面的影響就是ds一直處於一個鏈接中的狀態,其實是ds的鏈接在數據庫中。
  • 查詢參數配置,看當前每一個cn能夠接受的最大併發數量是多少:
  1. show max_active_statements;

若是當前cn的活躍做業超過這個參數,會出現語句排隊的狀況,主要排隊狀況爲waiting in global queue,以下圖所示,下圖狀況中,max_active_statements=6。

  1. 查看業務鏈接是否主要只鏈接一個cn,能夠一樣經過查詢pgxc_stat_activity判斷coorname,查看是否大量的語句都是集中在某一個cn上執行,當語句下發集中在某個cn上時,這個cn的併發數量也只是max_active_statements設置的大小,舉個例子:若是業務鏈接3個cn,每一個cn的max_active_statements設置都是10,那麼最大能夠同時運行30個做業;若是這30個做業都下發到一個cn上,那麼就有20個排隊,同時只能執行10個,會大大影響執行效率,同時也會形成這種看似沒法鏈接到該cn的現象。
  • 解決方法:
  1. 業務負載不均:配置LVS,均衡業務,避免負載不均致使的排隊。
  2. max_active_statements參數設置太小:在資源負載容許的狀況下繼續調大,若是資源達到瓶頸,繼續放大可能會致使資源爭搶,效果不大。
  3. 鏈接被空閒事務佔用:如上圖中狀況,能夠看到有不少鏈接的狀態都是idle in transaction,這種狀態處於事務塊完成可是沒有提交,也會佔用一個併發,致使其他做業併發量減少,致使排隊。此類狀況須要排查業務應用的執行狀況,整改業務,避免處於這種空閒還佔用併發的狀況。嚴重阻塞業務的狀況,緊急處理能夠將該類語句直接terminate掉。
  4. 確實已經有不少做業在執行,資源使用也已經達到一個瓶頸,這時候就須要去擴容或者下降業務量,來避免這種狀況出現。

2. 做業長時間執行不出來,而且有不少做業在排隊,總體業務受到阻塞。

  • 此類狀況能夠繼續使用上述查詢pgxc_stat_activity的語句,查看語句的運行狀況,結果可能以下:

如圖:圖中最下方的兩個做業,執行時間已經達到了11小時,可是仍然沒有執行完,後面還有未執行的語句在排隊。總體對於客戶來講就是數據庫已經hang死了,什麼做業都執行不出來。

排查步驟

  • 排查當前集羣是否在使用動態自適應功能,查看以下參數:

show enable_dynamic_workload; //查看該參數目前是否爲打開狀態(2020年的版本都是默認打開)

  • 若是該參數打開,那麼就要查看這幾個正在運行做業目前的內存使用狀況,大機率正是由於這幾個做業一直使用着內存不釋放,纔會出現總體的排隊狀況。

經過鏈接cn 5001查詢視圖:

select * from pg_session_wlmstat where threadid = $query_id;

該視圖能夠看到某個語句使用了多大的內存,statement_mem字段能夠看到我這個語句是使用了1G,可是實際狀況中,1個語句使用幾十個語句的狀況不少。當一個或者幾個語句的內存達到整個集羣的整體可用內存上限,或者達到資源池上限的時候,就會使這些語句後面的語句開始排隊。資源不放,排隊不止。

  • 處理方法

應急處理:及時將卡住的語句terminate,釋放其佔用的資源,後續進行優化以後再執行,優化手段不少,包括計劃調優,analyze等操做,均可以免一個語句佔用太大內存,也能夠提高執行效率。

3. 全局資源可用內存不少,資源使用很小,併發數量也沒有達到上限,可是查詢顯示不少做業處於排隊狀態。

舉例:查詢pgxc_stat_activity時,語句的執行狀態以下:能夠看到,全部語句都在waiting in ccn queue,只有兩個語句在運行。此時集羣設置的max_active_statements是40,可是該用戶實際活躍數量只有2個。

舉例:查詢pgxc_stat_activity時,語句的執行狀態以下:能夠看到,全部語句都在waiting in ccn queue,只有兩個語句在運行。此時集羣設置的max_active_statements是40,可是該用戶實際活躍數量只有2個。

  • 首先,出現出現waiting in ccn queue的狀況,就必定是開啓了內存自適應功能(enable_dynamic_workload=on)。此時只有兩種狀況,第一種是全局資源不足,會排隊,第二種是用戶所屬的資源池內存不足,也會排隊。
  • 根據圖中的現象,咱們看到不少語句都在排隊,這時候要查詢一個排隊視圖:select * from pg_stat_get_workload_struct_info();

這個視圖能夠清晰看到做業是在哪裏排隊:

首先,上圖中有totalsize,這個就是整體可用的最大內存,freesize_limit:執行語句可用的最大內存,freesize:當前可用的最大內存。

因此能夠得出結論,此時不是在全局排隊,全局內存freesize足夠,那麼做業就是在資源池排隊,資源池排隊也會顯示waiting in ccn queue。

  • 此時查詢pg_session_wlmstat視圖,能夠看到正在運行的爲dw用戶,正在運行的語句佔用的內存爲兩條各1G。

能夠經過界面或者後臺查看一下,這個用戶對應的租戶上,是否是作了內存資源限制:

查看租戶界面內存配置以下:

能夠看到圖中給這個租戶或者說給這個用戶所在的資源池配置了10%的內存配額,一共是2277MB,即2G左右。

所以這種場景下,內存資源只能知足當前兩個語句的執行,其他屬於該用戶的語句都會進行排隊。

  • 處理辦法:
  • 方法1、此類問題,若在資源容許的狀況下,能夠適當調大租戶相關的內存資源,讓更多語句可以同時運行。
  • 方法2、優化相關語句的執行效率,縮短執行時間,讓語句能夠高效執行,避免大量堆積。

4.執行的做業基本都是一個用戶的,其他用戶的做業基本都在排隊中沒法執行。

舉例:以前某局點出現高併發DDL的狀況,該類高併發DDL在全局併發計數中會受到統計,佔用max_active_statements中的併發數量。

好比:max_active_statements=20,其中某用戶一直持續不停地下發DDL,此時在DWS設計ap場景並未涉及此類場景。會出現該20個併發設置廣泛被該用戶佔用的狀況,其餘用戶可能出現連不上的狀況。

這種場景下,即時再調大併發,也會再被該用戶的DDL語句佔用。

處理方案:

針對高併發DDL的不合理業務場景進行優化,好比把連續建立刪除臨時表的動做,改成對永久表的操做,此時就能夠極大幅度減小DDL併發數量,保證自身業務以及其他用戶業務的正常鏈接和運行。

4、部分場景配置方案

1. 限制單用戶併發

用戶的做業分爲如下幾種,DDL/DML/以及常規查詢,在DWS的視角中,常規查詢有分爲簡單查詢和複雜查詢。

對於DWS的兩層管控,受到第一層管控的有DDL、start transaction、DML、常規查詢等,基本是全部語句,只有內部線程的語句(好比WLM線程)以及超級用戶權限的用戶執行的做業。

受到第二層管控的語句,主要是能夠從優化器獲取到具體執行計劃以及執行代價的語句。

除了DDL/start transaction 之類的語句,以及部分白名單語句,此類語句都是視爲基本不消耗資源,而且不會形成阻塞的語句。

針對目前的管控機制來講,能夠將單個用戶關聯到一個單獨的資源池,這個資源池不設置內存配置,只設置併發配置,達到進行做業管控的效果。

具體步驟及解釋以下:

1.在全部節點建立好控制組

gs_ssh -c "gs_cgroup -c -S class_a"
gs_ssh -c "gs_cgroup -c -S class_a -G workload_a"

2.建立業務資源池(此時能夠同步設置max_dop參數,active_statements會限制複雜做業的併發數量,max_dop參數會限制簡單做業的併發數量)

create resource pool p1 with (control_group="class_a:workload_a");
alter resource pool p1 with (active_statements=10,mem_percent=0,max_dop=1);

3.關聯用戶與該資源池

ALTER USER testuser RESOURCE POOL 'p1';

5、小結

併發管理的用處,主要是爲了防止用戶跑太多的做業,致使集羣負載過大,資源發生爭搶,系統不能穩定運行,會由於資源出現各類問題,CPU/內存/IO,哪個都是讓人頭疼的問題,併發控制也能夠同步控制某一個用戶的併發做業,避免由於一個用戶的做業數量太大,致使其餘用戶在使用數據庫的時候出現問題。

負載管理最主要的現象就是會出現做業排隊的狀況,排隊是否合理,是否由於不合理的參數配置致使大量的業務阻塞;或者配置正常,可是沒有達到上限就出現排隊,本文的主要目的就是解決此類問題,或者及時定界到是什麼緣由致使了阻塞。

實際使用過程當中,許多時候出現排隊的狀況,均可能和正在執行的語句有關,正在執行的語句佔用着這個位置,又執行不完,其他語句天然會排隊。所以咱們碰到語句大量阻塞的狀況,要迅速定界到是由於什麼而形成阻塞,怎麼樣能恢復正常使用。找到問題的語句後,要及時去將它作一些適當的調優,避免再次執行到這個語句,還會出現同樣的狀況。

 

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

相關文章
相關標籤/搜索