全部產品
Search
文件中心

Hologres:監控指標常見問題

更新時間:Jun 30, 2024

本文為您介紹Hologres監控指標相關的常見問題。

串連數過多時如何查看有哪些串連以及Kill串連?

串連數包括執行個體中總的SQL串連數,包括Active、Idle狀態的JDBC/PSQL等串連。執行個體的串連數通常與執行個體的規格有關,如果您發現串連數過多,甚至出現超出執行個體最大串連數的情況,或者遇到如下報錯:
  • 產生FATAL: sorry, too many clients already connection limit exceeded for superusers報錯。
  • 產生FATAL: remaining connection slots are reserved for non-replication superuser connections報錯。
說明執行個體串連數已達上限,通過HoloWeb或者SQL的方式查看當前的串連情況,詳情請參見串連數管理。可以使用Superuser帳號對不符合預期或者Idle的串連進行Kill操作。

查詢延遲過高時如何解決?

常見的延遲過高有以下幾種原因,可以先通過慢Query日誌尋找對應的慢SQL並根據如下的情況進行解決,詳情請參見慢Query日誌查看與分析
  • QPS較低,但查詢SQL較複雜,導致查詢延遲高。

    解決方案:對SQL進行最佳化,設定合理的索引,以提高查詢效能,詳情請參見最佳化查詢效能最佳化MaxCompute外部表格的查詢效能

  • 查詢的QPS較高,導致查詢延遲較高。

    解決方案:若是SQL已經最佳化完畢,但需要更高的QPS以及更低的延遲,可以擴容執行個體,用更多的資源擷取更好的效能,詳情請參見執行個體升配

  • 查詢時還有大量的寫入,寫入影響查詢,導致查詢延遲高。
    解決方案:寫入影響了查詢效能,可以進行如下操作。
    • 寫入在查詢低峰期進行,降低對查詢的影響。
    • 降低寫入的並發度,提高查詢效率,如果是外表寫入,可以用以下參數降低並發度。
      --設定MaxCompute執行的最大並發度,預設為128,建議數值設定小一些,避免一個Query影響其他Query,導致系統繁忙導致報錯。
      set hg_experimental_foreign_table_executor_max_dop = 32; --優先考慮設定
      
      --調整每次讀取MaxCompute表batch的大小,預設8192。
      set hg_experimental_query_batch_size = 1024;
      
      --直讀orc
      set hg_experimental_enable_access_odps_orc_via_holo = on;
      
      --設定MaxCompute表訪問切分spilit的數目,可以調節並發數目,預設64MB,當表很大時需要調大,避免過多的split影響效能。
      set hg_experimental_foreign_table_split_size = 512MB;

記憶體使用量率高的原因及解決方案?

Hologres執行個體的記憶體使用量率為記憶體綜合使用率。Hologres的記憶體資源採用預留模式,在沒有查詢的時候,也會有資料表的中繼資料、索引、資料緩衝等載入到記憶體中,以便加快檢索和計算,此時記憶體使用量率不為零是正常情況。理論上在無查詢的情況,記憶體使用量率達到30%~40%左右都屬於正常現象。

一些情況下,會使得記憶體使用量率持續升高,甚至接近80%。主要原因如下:
  • 表越來越多,資料總量越來越大,以至於資料規模遠大於當前計算規格。由於記憶體使用量率和中繼資料、索引量存在正相關關係,因此,表的數量越多,資料量越大,索引越多,都會導致記憶體使用量率升高。
  • 索引不合理,例如表的列特別多,TEXT列居多,設定了過多的Bitmap或Dictionary索引。此情況可以考慮去掉一些Bitmap或者Dictionar索引,詳情請參見ALTER TABLE

但是當記憶體使用量率穩定增長,長期接近80%時,通常意味著記憶體資源可能成為了系統的瓶頸,可能會影響執行個體的穩定性和或效能。穩定性影響體現在當中繼資料等過大,超額佔據了正常Query可用的記憶體空間時,在查詢過程中,可能會偶發SERVER_INTERNAL_ERRORERPC_ERROR_CONNECTION_CLOSEDTotal memory used by all existing queries exceeded memory limitation等報錯。效能影響體現在當中繼資料等過大,超額佔據了正常Query本來能夠使用的緩衝空間,從而快取命中會減少,Query延遲會增加。

因此當記憶體長期接近80%時,有如下幾個操作建議。
  • 刪除不再查詢的資料,以釋放中繼資料等占的記憶體。
  • 設定合理的索引,若是業務情境用不上的bitmap和dictionary,可以去掉,但不建議直接去掉,需要根據業務情況具體分析。
  • 升配執行個體的計算和儲存資源。對於升配的建議是:
    • 普通情境:可以容許讀磁碟資料的延遲,回應時間要求不嚴格,1CU(1Core+4GB記憶體)可以支援50~100GB的資料存放區。
    • 回應時間要求低的Serving情境:最好查詢熱點資料全在記憶體的緩衝中。記憶體中緩衝的比例預設佔總記憶體的30%,即1CU(1Core+4GB記憶體)其中1.3GB用於資料緩衝,同時資料緩衝還會被表的中繼資料所使用一些。舉個例子,低響應要求的情境,熱點資料如果是100GB,那麼最好要求100GB 在緩衝可用(實際上資料讀出來解壓後,佔用記憶體不止100GB),因此至少需要約320GB記憶體以上,從而推算計算資源至少需要96CU左右。

為什麼只有一個任務,Hologres執行個體CPU使用率就達到100%?

Hologres執行個體的CPU使用率為執行個體的CPU綜合使用率。Hologres因其可以充分發揮多核並行計算的能力,通常來說單個查詢可以迅速將CPU使用率提高到100%,這說明計算資源得到了充分利用。CPU使用率高不是問題,CPU使用率高了之後,查詢慢寫入慢才是問題,需要綜合分析。

寫入慢如何解決?

執行insertinsert on conflictupdate命令時,耗時比較長即寫入效能較差,通常原因是因為SQL沒有走Fixed Plan,沒有走Fixed Plan的SQL命令存在表鎖,並發執行時會等鎖,導致耗時較長,即時寫入RPS監控指標會顯示寫入類型為insert。可以查看Query的特徵改寫為走Fixed Plan的方式,讓監控指標的寫入類型變成SDK提升寫入效能,詳情請參加Fixed Plan加速SQL執行

CPU使用率長期達到100%如何解決?

當Hologres執行個體CPU使用率長期接近100%時(例如CPU使用率連續3小時滿載100%,或者連續12小時達到90%以上等),說明執行個體負載非常高,這通常意味著CPU資源成為了系統的瓶頸,需要分析具體的業務情境和查詢,以判斷原因。可以從以下幾方面進行排查。
  • 排查一:QPS或者RPS明顯上漲。

    對比CPU使用率上漲前和上漲後的QPS和RPS監控指標,如果有明顯的上漲趨勢,而導致CPU使用率上漲。

    解決方案如下。
    • 查詢資料(select)行為導致CPU使用率上漲,可以通過慢Query日誌,排查耗時較長的Query,對Query進行針對性最佳化。
    • 執行insertupdatedelete操作導致CPU使用率上漲,建議通過慢Query日誌排查Query是否未走Fixed Plan,如下SQL所示。未走Fixed Plan的insertupdatedelete命令會產生表鎖,Query並發會造成鎖等待,可以從業務上判斷是否可以改寫為走Fixed Plan的SQL,避免表鎖,降低CPU水位。
      --樣本查看過去一小時未走fixed plan的insert/update/delete
      select *
      from hologres.hg_query_log
      where query_start >= now() - interval '3 h'
          and command_tag in ('INSERT','UPDATE','DELETE')
          and 'HQE'=ANY(engine_type)
      order by query_start desc limit 500;
    • SQL都已經合理,但是CPU使用率還是比較高,說明執行個體資源已到瓶頸,可以適當的擴容或者使用多執行個體共用儲存部署從而讀寫分離,詳情請參見執行個體升配主從執行個體讀寫分離部署(共用儲存)
  • 排查二:未有明顯的QPS或者RPS上漲,存在已耗用時間較長的Query。
    通過監控指標發現沒有明顯的QPS或者RPS上漲,但是CPU使用率卻突然上漲並且持續一段時間,可以通過正在運行Query持續時間長度監控指標查看是否有已耗用時間較長的Query,若監控指標顯示有運行時間長度超過半個小時或者一小時的Query,說明是該Query導致的CPU使用率高。使用如下命令通過活躍Query查詢啟動並執行Query,並結束Query,從而降低CPU使用率。
    --查看已耗用時間較長的query
    SELECT current_timestamp - query_start as runtime, datname::text, usename, query, pid::text
        FROM pg_stat_activity
        WHERE state != 'idle'
        order by 1 desc;
    
    --取消query執行
    select pg_cancel_backend(<pid>);
  • 排查三:未有明顯的QPS或者RPS上漲,存在耗時較長的Query。
    通過監控指標發現沒有明顯的QPS或者RPS上漲,但是CPU使用率卻突然上漲並且持續一段時間,可以通過如下命令從慢Query日誌查看消耗CPU較高的Query,從而定位CPU消耗的操作,並根據Query最佳化SQL。
    -- 查詢最近3小時消耗比較高的Query
    select status as "狀態",
    duration as "耗時(ms)",
    query_start as "開始時間",
    (read_bytes/1048576)::text || ' MB' as "讀取量",
    (memory_bytes/1048576)::text || ' MB' as "記憶體",
    (shuffle_bytes/1048576)::text || ' MB' as "Shuffle",
    (cpu_time_ms/1000)::text || ' s' as "CPU時間",
    physical_reads as "讀盤量",
    query_id as "QueryID",
    query
    from hologres.hg_query_log
    where query_start > current_timestamp - interval'3 h'
    and command_tag in ('SELECT','INSERT','UPDATE','DELETE')
    and duration > 1000
    order by duration desc,
    read_bytes desc,
    shuffle_bytes desc,
    memory_bytes desc,
    cpu_time_ms desc,
    physical_reads desc
    limit 500;
  • 排查四:PQE的SQL導致CPU使用率達到100%。
    通過監控指標發現未有明顯的QPS或者RPS上漲,可以使用如下SQL命令從慢Query日誌查詢是否有新增的PQE SQL,導致CPU使用率上漲。如果存在PQE SQL,則需要最佳化SQL中走PQE引擎的運算元,詳情請參見最佳化查詢效能
    --查詢最近3小時走PQE的query
    select *
    from hologres.hg_query_log
    where query_start > current_timestamp - interval'3 h'
        and 'PQE'=ANY(engine_type)
    order by query_start desc limit 500;
  • 排查五:對錶修改過Bitmap或者Dictionary索引。
    對錶修改過Bitmap或者Dictionary索引,修改後會觸發後台非同步執行Compaction,佔用一定的CPU資源,同時執行個體的儲存量可能會出現先上升後回落的情況,可以使用如下SQL命令樣本從慢Query日誌查詢是否有修改過索引。
    --查詢最近3小時內執行過修改索引的記錄
    select *
    from hologres.hg_query_log
    where query_start >= now() - interval '3 h'
    and command_tag in ('CALL')
    order by query_start desc limit 500;

正在運行Query時間長度較長如何解決?

監控指標正在運行Query持續時間長度中有長時間啟動並執行Query,例如運行時間長度大於1小時。當出現有長時間啟動並執行Query時,可以先通過活躍Query頁面查看正在啟動並執行Query,詳情請參見Query管理。正在運行Query時間長度較長,通常有以下幾種情況,可以根據實際情況進行排查。
  • 情況一:執行個體有較長時間的寫入。

    解決方案:通過監控指標的即時寫入RPS指標查看是否有持續的寫入任務,從而導致出現Query已耗用時間較長的情況。

  • 情況二:事務空閑(idle in transaction)。
    • 用戶端開啟事務,進行DDL後未進行commit操作,使用如下SQL命令查詢活躍Query狀態,Query的狀態顯示為idle in trancation,且已耗用時間較長。
    • Query因為等鎖卡住等原因,導致長時間運行中。

    解決方案:通過以下樣本SQL查詢出已耗用時間較長的Query,如果是因為idle in trancation導致已耗用時間較長,可以用戶端關閉事務或者設定合理的空閑事務逾時時間,詳情請參見修改空閑Query逾時時間

  • 情況三:SQL運行複雜且有PQE的Query。
    解決方案:通過以下命令查詢當前正在運行且已耗用時間較長的Query,然後通過執行計畫(explain sql)查看當前有SQL走了PQE引擎(執行計畫中有External SQL(Postgres)),導致執行時間較長。
    --查看已耗用時間較長的query
    SELECT current_timestamp - query_start as runtime, datname::text, usename, query, pid::text
        FROM pg_stat_activity
        WHERE state != 'idle'
        order by 1 desc;
    
    --查看query的執行計畫
    explain sql
    • 使用Superuser帳號Kill已耗用時間較長的Query。
    • 最佳化SQL中走PQE引擎的運算元,詳情請參見最佳化查詢效能
  • 情況四:並發執行DDL導致搶鎖。

    並發執行DDL時會鎖表,導致互相搶鎖,從而出現等鎖,導致已耗用時間較長。

    解決方案:
    • 可以通過如下命令查看是否有DDL正在執行中,並Kill掉對應的DDL,釋放鎖。
      SELECT datname::text,usename,query,pid::text,state
         FROM pg_stat_activity
         WHERE state != 'idle' ;
    • 串列執行DDL。

失敗Query如何排查?

失敗Query代表每秒鐘失敗的Query。Query總數量是時間範圍乘以QPS個數,即時間範圍內的面積。不建議依賴QPS來判斷失敗的總數量。可以通過慢Query日誌排查Query總的失敗數量和失敗原因,並根據報錯針對性的解決,詳情請參見慢Query日誌查看與分析

Worker CPU負載不均如何解決?

在Hologres中資料分區(Shard)決定了資料的分布情況,一個Worker在計算時可能會訪問一個或者多個Shard的資料。同一個執行個體中,一個Shard同一時間只能被一個Worker訪問,不能同時被多個Worker訪問。如果執行個體中每個Worker訪問的Shard總數不同,那麼就有可能出現Worker資源負載不均的情況,主要原因如下:
  • 原因一:存在資料扭曲。

    如果資料存在嚴重的傾斜,那麼Worker的負載就會訪問固定的Shard,導致出現CPU負載不均的情況。

    解決方案:需要通過以下語句排查資料扭曲。如樣本結果,某個Shard的數值比其他Shard大太多,從而出現資料扭曲。可根據業務情況處理傾斜資料或者設定合適的Distribution Key,詳情請參見最佳化查詢效能
    select hg_shard_id,count(1) from <table_name> group by hg_shard_id;
    
    --樣本結果:shard 39的count值較大,存在傾斜
    hg_shard_id | count
    -------------+--------
              53 |  29130
              65 |  28628
              66 |  26970
              70 |  28767
              77 |  28753
              24 |  30310
              15 |  29550
              39 | 164983
  • 原因二:執行個體設定的Shard數和Worker個數不是整倍數關係。

    當Table Group中設定的Shard數和執行個體的總Worker數不是整倍數關係時,意味著不同的Worker上分配的Shard數不同,從而導致負載不均。

    解決方案:根據執行個體規格,設定合理的Shard數,詳情請參見Table Group與Shard Count操作指南。一般這種情況出現在較大規格(大於256Core)的執行個體上,小規格執行個體可以使用預設Shard數,無需更改。

  • 原因三:有Worker Failover後導致Shard分配不均。

    當有Worker因為OOM等原因而被終止(Kill)時,為了能快速恢複Worker的查詢,系統會將該Worker對應的Shard,快速遷移至其他Worker。當被Kill的Worker被拉起後,系統會再分配部分Shard給它,從而出現Worker間Shard分配不均的現象。

    解決方案:如果執行個體負載較低,可忽略該負載分配不均的問題。如果執行個體負載較高,可以重啟執行個體以重新均勻分配Shard資源。