全部產品
Search
文件中心

Hologres:Blink和Flink常見問題及診斷

更新時間:Sep 12, 2024

本文為您介紹使用Hologres過程中關於Blink和Flink的常見問題。

基本概念

  • Hologres效能

    • 寫入效能

      • 列存表: InsertOrIgnore > InsertOrReplace > InsertOrUpdate

      • 行存表: InsertOrReplcae = InsertOrUpdate > InsertOrIgnore

      參數

      說明

      InsertOrIgnore

      結果表有主鍵,即時寫入時如果主鍵重複,丟棄後到的資料。

      InsertOrReplace

      結果表有主鍵,即時寫入時如果主鍵重複,按照主鍵更新,如果寫入的一行資料不包含所有列,缺失的列的資料補Null。

      InsertOrUpdate

      結果表有主鍵,即時寫入時如果主鍵重複,按照主鍵更新,如果寫入的一行資料不包含所有列,缺失的列不更新。

    • 點查效能

      行存 = 行列混存 > 列存。

  • Blink、Flink(VVP)、開源Flink支援情況

    產品形態

    資料存放區類型

    描述

    源表

    結果表

    維表

    Binlog

    Hologres Catalog

    Flink全託管

    支援行儲存及列儲存。

    支援行儲存及列儲存。

    建議使用行儲存。

    支援

    支援

    Blink獨享

    支援行儲存及列儲存。

    支援行儲存及列儲存。

    建議使用行儲存。

    Hologres V0.8版本只支援行儲存,V0.9及以上版本支援行儲存及列儲存。建議使用行儲存。

    不支援

    已開始逐步下線,推薦使用阿里雲Flink全託管。

    開源Flink1.10

    支援行儲存及列儲存。

    支援行儲存及列儲存。

    不支援

    不支援

    開源Flink1.11及以上

    支援行儲存及列儲存。

    支援行儲存及列儲存。

    建議使用行儲存。

    不支援

    不支援

    從開源Flink1.11版本開始,Hologres代碼已開源。詳細內容請參見GitHub

  • Blink、Flink 映射Hologres的SQL樣本如下。

    create table holo_source(
    'hg_binlog_lsn' BIGINT HEADER,
    'hg_binlog_event_type' BIGINT HEADER,
    'hg_binlog_timestamp_us' BIGINT HEADER,
    A int,
    B int,
    C timestamp )
    with (
    type = 'hologres',
    'endpoint' = 'xxx.hologres.aliyuncs.com:80',   --Hologres執行個體的Endpoint。
    'userName' = '',                               --當前阿里雲帳號的AccessKey ID。
    'password' = '',                               --當前阿里雲帳號的AccessKey Secret。
    'dbName' = 'binlog',                           --Hologres執行個體的資料庫名稱。
    'tableName' ='test'                            --Hologres執行個體的表名稱。
    'binlog' = 'true',
    );

    Blink、VVP、Flink SQL,都是在Flink側聲明一張表,然後根據參數映射至Hologres的一張具體的物理表,所以不支援映射至外部表格。

即時寫入慢問題排查流程

  1. 確認寫入相關配置

    需要確認以下配置資訊。

    • 目標表的儲存格式,包括行存表、列存表和行列共存表。

    • Insert模式,包括InsertOrIgnore、InsertOrUpdate和InsertOrReplace。

    • 目標表的Table Group及Shard Count。

  2. 查看監控指標的即時寫入延遲

    如果平均寫入延遲偏高,在百毫秒甚至秒層級,通常便是後端達到了寫入瓶頸,這時候可能會存在如下問題。

    • 使用了列存表的InsertOrUpdate,即局部更新,且流量較高,這種情況下會導致執行個體的CPU負載和寫入延遲偏高。

      解決方案:建議更換表的類型,使用行存表,如果您的執行個體是V1.1及以上版本可以選擇行列混存表。

    • CloudMonitor查看執行個體的CPU負載,如果CPU水位接近100%,但沒有列存表的局部更新,那麼通常情況下是由於高QPS的查詢,或者本身寫入量較高導致的。

      解決方案:擴容Hologres執行個體。

    • 確認是否有不斷的Insert into select from命令,觸發了該表的BulkLoad寫入,當前BulkLoad寫入會阻塞即時寫入。

      解決方案:將BulkLoad寫入轉換成即時寫入,或者錯峰執行。

  3. 確認是否有資料扭曲

    使用如下SQL命令查看是否有資料扭曲。

    SELECT hg_shard_id, count(1) FROM t1 GROUP BY hg_shard_id ORDER BY hg_shard_id;

    解決方案:修改Distribution Key,使資料分布更加均衡。

  4. 確認後端是否有壓力

    如果以上步驟排查完沒有問題,寫入效能突然下降,一般情況是後端叢集壓力比較大,存在瓶頸。請聯絡技術支援人員確認情況,詳情請參見如何擷取更多的線上支援?

  5. 查看Blink/Flink側的反壓情況

    上述步驟排查完後,發現Hologres側沒有明顯的異常,通常情況下是用戶端慢了,也就是Blink/Flink側本身就慢了,這時候確認是否是Sink節點反壓了。如果作業只有一個節點,就無法看出是否反壓了,這時候可以將Sink節點單獨拆開再觀察。具體請聯絡Flink支援人員。

寫入資料有問題排查流程

這種情況通常是由於資料亂序引起的,比如相同主鍵的資料分布在不同的Flink Task上,寫入的時候無法保證順序。需要確認Flink SQL的邏輯,最後寫出到Hologres的時候,是否按照Hologres表的主鍵進行Shuffle了。

維表查詢問題排查流程

  • 維表Join和雙流Join

    對於讀Hologres的情境,需要首先確認使用者是否使用對了維表Join,是否錯將雙流Join當成維表Join來使用了。以下是Hologres作為維表的使用樣本,如果少了proctime AS PROCTIME() hologres_dim FOR SYSTEM_TIME AS兩處關鍵字,則會變成雙流Join。

    CREATE TEMPORARY TABLE datagen_source (
       a INT,
       b BIGINT,
       c STRING,
       proctime AS PROCTIME()
    ) with (
       'connector' = 'datagen'
    );
    
    CREATE TEMPORARY TABLE hologres_dim (
       a INT, 
       b VARCHAR, 
       c VARCHAR
    ) with (
       'connector' = 'hologres',
       ...
    );
    
    CREATE TEMPORARY TABLE blackhole_sink (
       a INT,
       b STRING
    ) with (
       'connector' = 'blackhole'
    );
    
    insert into blackhole_sink select T.a,H.b
    FROM datagen_source AS T JOIN hologres_dim FOR SYSTEM_TIME AS OF T.proctime AS H ON T.a = H.a;
  • 維表查詢

    1. 確認維表格儲存體格式

      確認維表的儲存格式是行存表、列存表還是行列共存。

    2. 維表查詢延遲高

      維表的使用,最常見的問題就是Flink/Blink側使用者反饋Join節點有反壓,導致整個作業的吞吐上不去。

      1. 確認Flink維表Join的模式

        當前Hologres Flink Connector的維表Join功能支援同步和非同步模式兩種,非同步模式效能要優於同步模式,具體需要看Flink SQL進行區分,以下是一個開啟非同步維表查詢功能的SQL樣本。

        CREATE TABLE hologres_dim(
         id INT,
         len INT,
         content VARCHAR
        ) with (
          'connector'='hologres',
          'dbname'='<yourDbname>',  --Hologres的資料庫名稱。
          'tablename'='<yourTablename>',  --Hologres用於接收資料的表名稱。
          'username'='<yourUsername>',  --當前阿里雲帳號的AccessKey ID。
          'password'='<yourPassword>',  --當前阿里雲帳號的AccessKey Secret。
          'endpoint'='<yourEndpoint>'  --當前Hologres執行個體VPC網路的Endpoint。
          'async' = 'true'--非同步模式
        );
      2. 確認後端查詢延遲

        查看監控指標的即時寫入延遲:

        • 確認是否是列存表在做維表,列存表的維表在高QPS情境下開銷很高。

        • 如果是行存表,且延遲高,通常情況下是執行個體整體負載較高導致的,需要進行擴容。

    3. 確認Join的Key是否是Hologres表的主鍵

      自VVR 4.x (Flink 1.13) 版本開始,Hologres Connector基於Holo Client實現了Hologres表的非主鍵查詢,這種情況通常效能會比較差、執行個體負載也比較高,尤其是建表沒有特別最佳化過的情況。這時候需要引導最佳化表結構,最常見的就是將Join的key設定成Distribution Key,這樣就能實現Shard Pruning。

    4. 查看Blink側的反壓情況

      如果上述步驟排查完成,發現Hologres側沒有明顯的異常,通常情況下是用戶端慢了,也就是Blink側本身就慢了,這時候可以確認是否是Sink節點反壓了。如果作業只有一個節點,就無法看出是否反壓了,這時候可以將Sink節點單獨拆開再觀察。同樣可以排查是否是Join節點導致的反壓。具體請聯絡Flink支援人員排查。

串連數使用說明

Hologres Connector預設採用JDBC相關模式。

  • 現已支援JDBC_FIXED模式,該模式不佔用串連數,並且在消費Binlog時也不受Walsender數量上限的限制,詳情請參見即時數倉Hologres

  • 從Flink引擎VVR-8.0.5-Flink-1.17版本開始,預設開啟了串連複用'connectionPoolName' = 'default',對大多數作業而言,這並沒有影響。如果單個作業表數量較多,可能在升級之後出現效能有所下降。這種情況下,建議為熱點表單獨配置connectionPoolName參數以最佳化效能。

  • JDBC模式會佔用一定數量的串連數,不同類型的表預設串連數使用方式如下表。

    表類型

    預設串連數(Flink作業的每個並發)

    Binlog源表

    0

    批量源表

    1

    維表

    3(可以通過connectionSize參數調整)

    結果表

    3(可以通過connectionSize參數調整)

    • 串連數計算方法

      • 預設情況

        預設情況下,作業使用的最大串連數可以通過如下公式計算:

        最大串連數 = ( 批量源表數 * 1 + 維表數 * connectionSize + 結果表數 * connectionSize )* 作業並發

        例如某作業有一張全增量源表、兩張維表和三張結果表,都使用預設的connectionSize參數值,作業並發設定為5,則最終使用的串連數為:(1 * 1 + 2 * 3 + 3 * 3) * 5 = 80

      • 串連複用

        Realtime Compute1.13-vvr-4.1.12及以上版本支援串連複用。一個作業的同一個並發內,相同connectionPoolName的維表和結果表會使用同一個串連池。預設情況樣本中,如果兩張維表和三張結果表都配置了相同的connectionPoolName,並適當調大connectionSize5,則最終使用的串連數為(1 * 1 + 5) * 5 = 30

        說明

        串連複用模式適用大多數情境,但部分情境比如維表數量較多、沒有啟用非同步也沒有開啟緩衝時,會非常頻繁的進行同步的點查,此時多表串連複用可能導致查詢變慢,這種情況可以只為結果表配置串連複用。

      • 其他使用串連的情境

        • 作業啟動過程中,需要建立串連用於表中繼資料的驗證等工作,可能會暫時使用3至6個串連,作業正常運行後會釋放。

        • Flink全託管支援Hologres Catalog、CTAS以及CDAS等功能,使用這些功能也會佔用串連數。預設情況下,一個使用Catalog的作業,會多佔用三個串連,用於建表等DDL操作。

    • 串連數使用診斷

      當作業的表數量較多、作業並發較高時,會佔用大量的串連數,甚至出現將Hologres總串連數佔滿的情況,通過以下方式對當前串連數的使用進行瞭解和診斷。

      • 使用如下命令在HoloWeb中通過pg_stat_activity表查看當前的活躍Query,詳情請參見查詢pg_stat_activity視圖資訊。其中application_name欄位中值為ververica-connector-hologres的Query代表來自Realtime ComputeFlink的讀寫串連。

        SELECT application_name, COUNT (1) AS COUNT
        FROM
          pg_stat_activity
        WHERE
          backend_type = 'client backend'
          AND application_name != 'hologres'
        GROUP BY application_name;
      • 有時作業並發設定的過高,在Hologres管理主控台執行個體列表對應執行個體的監控資訊頁表現如下:剛啟動時串連數很高,運行一段時間之後串連數下降。原因是很多串連處於空閑狀態而被關閉,此現象表明作業實際上不需要如此大的並發或串連數,應該合理規劃任務串連數、降低並發度或connectionSize參數值,或者使用串連複用模式。

      • 適當調整Hologres節點的並發度。預設情況下Flink作業的所有運算元並發相同,一些情境下那些包含複雜計算邏輯的運算元需要配置較高的並發,但這些並發對Hologres結果表來說可能是冗餘的,還可能佔用大量的串連數,此時可以參考作業資源配置,選擇專家模式,為寫入運算元單獨設定合適且較小的並發,從而降低總串連數的使用。

常見報錯

報錯:ERPC TIMEOUT或者ERPC CONNECTION CLOSED

  • 報錯現象:出現com.alibaba.blink.store.core.rpc.RpcException: request xx UpsertRecordBatchRequest failed on final try 4, maxAttempts=4, errorCode=3, msg=ERPC_ERROR_TIMEOUT報錯。

  • 可能原因:寫入時壓力過大寫入失敗或者叢集比較繁忙,可以觀察Hologres執行個體的CPU負載是否打滿。CONNECTION CLOSED可能是負載過大導致後端節點掛掉了,出現OOM(Out Of Memory)或者Coredump。

  • 解決方案:請先重試寫入,如果不能恢複請找Hologres技術支援人員排查原因。

報錯:BackPresure Exceed Reject Limit

  • 可能原因:通常是Hologres後端寫入壓力過大,導致Memtable來不及刷盤導致寫入失敗。

  • 解決方案:如偶發失敗可忽略該問題,或者Sink加上參數rpcRetries = '100' 來調大寫入重試次數。如果一直報該錯誤,請聯絡Hologres技術支援人員確認後端執行個體狀態。

報錯:The requested table name xxx mismatches the version of the table xxx from server/org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.Caused by: java.net.SocketTimeoutException: Read timed out

  • 可能原因:通常是使用者做了Alter Table導致Blink寫入所帶表的Schema版本號碼低於Server端版本號碼導致的,並且超過了用戶端的重試次數。

  • 解決方案:如偶發報錯可忽略該問題。如果一直報該錯誤,請聯絡Hologres技術支援人員。

報錯:Failed to query table meta for table

  • 可能原因:一種可能是使用者讀寫了一張Hologres的外部表格,Hologres Connector不支援讀寫外部表格。如果不是,可能是Hologres執行個體 Meta出現了問題。

  • 解決方案:請聯絡Hologres技術支援人員。

報錯:Cloud authentication failed for access id

  • 可能原因:該報錯通常是使用者配置的AccessKey資訊不對,或者使用者沒有添加帳號至Hologres執行個體。

  • 解決方案:

    • 請檢查當前賬戶的AccessKey ID和AccessKey Secret填寫是否正確,一般是AccessKey Secret錯誤或者有空格。

    • 檢查不出原因可以用當前AccessKey串連HoloWeb(使用帳號密碼方式登入),在測試聯通性時看報錯是什麼,還是一樣的報錯說明AccessKey有問題,如果報錯為FATAL:role“ALIYUN$xxxx“does not exist說明帳號沒有執行個體的許可權,需要管理員給該帳號授予許可權。

Hologres維表Join不到資料

  • 可能原因:Hologres維表使用了分區表,Hologres維表暫不支援分區表。

  • 解決方案:請將分區錶轉為普通表。

報錯:Modify record by primary key is not on this table

  • 可能原因:即時寫入的時候選擇了更新模式,但是Hologres的結果表沒有主鍵。

  • 解決方案:請設定主鍵。

報錯:shard columns count is no match

  • 可能原因:寫入Hologres的時候,沒有寫入完整的Distribution Key的列(預設是主鍵)。

  • 解決方案:請寫入完整的Distribution Key列。

報錯:Full row is required, but the column xxx is missing

  • 可能原因:Hologres老版本的報錯資訊,通常是使用者沒有寫某列資料,而那一列是不可為空的。

  • 解決方案:請為不可為空的列賦值。

VVP使用者讀寫Hologres導致JDBC串連數暴漲

  • 可能原因:VVP Hologres Connector讀寫Hologres(除了Binlog),採用JDBC模式,最大佔用讀寫Hologres表數量*並發度 * connectionSize(VVP表的參數,預設為3)個串連。

  • 解決方案:合理規劃任務串連數,降低並發度或者connectionSize。如無法調低並發度或connectionSize,可以為表設定參數useRpcMode = 'true' 切回至Rpc模式。

Blink/VVP使用者讀寫Hologres報錯顯示無法串連Hologres

  • 可能原因:Blink/VVP叢集預設訪問公網很慢或者無法訪問。

  • 解決方案:需要保證和Hologres執行個體在相同Region,且使用VPC的Endpoint。

報錯:Hologres rpc mode dimension table does not support one to many join

  • 可能原因:Blink和VVP的RPC模式維表必須是行存表,且Join的欄位必須是主鍵,報錯的原因往往是以上兩個條件不滿足

  • 解決方案:建議使用JDBC模式,且維表使用行存表或者行列共存表。

報錯:DatahubClientException

  • 報錯現象:出現Caused by: com.aliyun.datahub.client.exception.DatahubClientException: [httpStatus:503, requestId:null, errorCode:null, errorMessage:{"ErrorCode":"ServiceUnavailable","ErrorMessage":"Queue Full"}]報錯。

  • 可能原因:大量消費Binlog作業由於某種原因同時重啟導致線程池被佔滿。

  • 解決方案:分批進行消費Binlog作業。

報錯:Error occurs when reading data from datahub

  • 報錯現象:出現Error occurs when reading data from datahub, msg: [httpStatus:500, requestId:xxx, errorCode:InternalServerError, errorMessage:Get binlog timeout.]報錯。

  • 可能原因:Binlog每條資料太大,乘上攢批之後,每個RPC請求的大小超過最大限制。

  • 解決方案:在每行資料欄位較多且有很長的字串等欄位時,可以減小攢批配置。

報錯:Caused by: java.lang.IllegalArgumentException: Column: created_time type does not match: flink row type: TIMESTAMP(6) WITH LOCAL TIME ZONE, hologres type: timestamp

  • 可能原因:在Flink中欄位使用了TIMESTAMP(6)類型,當前不支援映射至Hologres。

  • 解決方案:修改欄位類型為TIMESTAMP

報錯:Caused by: org.postgresql.util.PSQLException: FATAL: Rejected by ip white list. db = xxx, usr=xxx, ip=xx.xx.xx.xx

  • 可能原因:在Hologres中設定了IP白名單,但是白名單中未包含Flink訪問Hologres的IP地址,所以Flink訪問Hologres時被阻止。

  • 解決方案:在Hologres的IP白名單中增加Flink的IP,詳情請參見IP白名單

報錯:Caused by: java.lang.RuntimeException: shaded.hologres.com.aliyun.datahub.client.exception.DatahubClientException: [httpStatus:400, requestId:xx, errorCode:TableVersionExpired, errorMessage:The specified table has been modified, please refresh cursor and try again

  • 可能原因:使用者對源表進行了DDL操作,Table Version發生變化,導致消費失敗。

  • 解決辦法:升級Flink版本到4.0.16及以上,會對此情況進行重試。

Binlog作業啟動時拋出Shard ID不存在的異常

  • 可能原因:所消費表的Shard數發生了變化,可能是使用者對錶進行了重新命名等操作,作業從checkpoint恢複時使用的舊錶的Shard資訊。

  • 解決辦法:重建表等操作之後,checkpoint中儲存的Binlog消費點位資訊已經沒有意義,請無狀態重新啟動作業。

報錯:ERROR,22021,"invalid byte sequence for encoding ""UTF8"": 0x00"

  • 可能原因:維表點查時,使用的主鍵(字串類型)中包含非UTF-8編碼的字元,導致SQL執行失敗。

  • 解決辦法:在上遊對髒資料進行處理。

報錯:hologres.org.postgresql.util.PSQLException: ERROR: syntax error

  • 可能原因:JDBC模式消費Binlog表時需要指定Slot,發生此報錯可能是建立的Slot名稱中有不支援的字元(只支援小寫字母、數字和底線)。

  • 解決辦法:重新建立Slot,或者使用VVR-6.0.7版本自動建立Slot功能。

報錯:create table hologres.hg_replication_progress failed

  • 可能原因:JDBC消費Binlog時可能需要hg_replication_progress表(當前資料庫中不存在此表)時,需要建立此表,但執行個體可以建立的Shard數已經達到上限,導致建立失敗報錯。

  • 解決辦法:清理無用的資料庫。

異常:作業運行時卡住,通過thread dump等可以看到卡在JDBC Driver載入處,通常是Class.forName等位置

  • 可能原因:JDK 8在載入JDBC驅動程式會進行一些靜態初始化操作,而多線程同時載入時可能會發生競爭條件。

  • 解決辦法:可以進行重試,或者使用6.0.7版本的Connector,對此類情況做了處理。

異常:使用JDBC模式消費Binlog時,拋出no table is defined in publication或者The table xxx has no slot named xxx異常

  • 可能原因:刪除表並重建同名表時,和表綁定的Publication沒有被刪除。

  • 解決辦法:當發生此異常時,可以在Hologres中執行select * from pg_publication where pubname not in (select pubname from pg_publication_tables);語句查詢未被一起清理的Publication,並執行drop publication xx;語句刪除殘留的publication,之後重新啟動作業即可。

報錯:作業上線時拋出“permission denied for database”的異常

  • 可能原因:Hologres V1.3和V2.0版本的JDBC模式消費Binlog,需要進行許可權配置。

  • 解決辦法:建議升級Hologres到V2.1版本,使用VVR-8.0.5版本及以上的connector,僅需要表的唯讀許可權就可以消費Binlog。如果不方便升級,請參考使用限制的賦權操作。

報錯:table writer init failed: Fail to fetch table meta from sm

  • 可能原因:對錶進行truncate或者rename操作之後進行寫入。

  • 解決辦法:偶發可以忽略,作業failover之後會自行恢複。Hologres V2.1.1到V2.1.14版本FE節點增加了replay緩衝時間,導致同一個DDL後再DML,DDL replay會變慢。類似異常出現機率可能提高,建議升級到V2.1最新版本。

異常:本地使用connector依賴開發Datastream作業過程中,出現類似java.lang.ClassNotFoundException: com.alibaba.ververica.connectors.hologres.binlog.source.reader.HologresBinlogRecordEmitter的異常

異常:JDBC模式消費Binlog,出現Binlog Convert Failed異常,或者部分shard的資料讀取停止在某個時刻。

  • 可能原因:Hologres執行個體的Gateway收到後端逾時的異常資訊時,將異常返回給用戶端的過程中會存在問題,導致讀取數據卡住或資料解析失敗報錯。

  • 解決辦法:一般只有在作業反壓時會出現,如果作業存在資料讀取卡住的問題,可以選擇重啟作業並從最近的checkpoint恢複。要徹底解決該問題,需要將Hologres版本升級到2.2.21及以上版本。