flink jobmanager和taskmanager的關係

耗子哥信徒發表於2024-07-25

需求背景

在flink中,我們使用druid datasource建立資料來源:

dataSource = DruidDataSourceFactory.createDataSource(prop);

現在我希望透過druid列印sql執行日誌。
參考https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_LogFilter
需要設定system properties。有兩種選擇:

  1. 提交任務jar包時,指定-D選項
  2. 在flink任務程式碼中,透過config.yaml檔案,指定不同環境下的日誌配置。

我選擇透過程式碼來控制,config.yaml檔案內容如下:

properties:
  #  列印druid sql日誌。參考https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_LogFilter
  druid:
    log:
      stmt:
        executableSql: true
    filters: log4j

接下來需要解析這個配置,然後set到system properties中。相關程式碼:

private static Configuration getYamlConfig(String fileName) throws Exception {
        ClassLoader cl = ConfigHelper.class.getClassLoader();

        try (InputStream is = cl.getResourceAsStream(fileName)) {
            Yaml yaml = new Yaml(new Constructor(Configuration.class));
            Configuration config = yaml.load(is);
            return config;
        }
    }
	
public class SystemPropertiesHelper {
    private static final Logger log = LoggerFactory.getLogger(SystemPropertiesHelper.class);

    public static void setSystemProperties(Map<String, Object> yamlMap, String parentKey) {
        for (Map.Entry<String, Object> entry : yamlMap.entrySet()) {
            String key = parentKey.isEmpty() ? entry.getKey() : parentKey + "." + entry.getKey();
            Object value = entry.getValue();

            if (value instanceof Map) {
                setSystemProperties((Map<String, Object>) value, key);
            } else {
                log.info("Set system property: {}={}", key, value.toString());
                System.setProperty(key, value.toString());
            }
        }
    }
}

接下來,我在main方法入口的地方,呼叫ystemPropertiesHelper.setSystemProperties(configuration.getProperties(), ""); 設定系統屬性。

本地執行(flink local env)是可以的,能列印出flink執行日誌。但是把jar釋出到測試的flink叢集之後就不行了,死活日誌打不出來。

後來透過日誌發現,在job manager的log中確實設定成功了系統屬性

2024-07-25 06:46:27,900 INFO  com.tide.util.SystemPropertiesHelper                         [] - Set system property: druid.log.stmt.executableSql=true
2024-07-25 06:46:27,901 INFO  com.tide.util.SystemPropertiesHelper                         [] - Set system property: druid.filters=log4j

但是,task manager的log中並沒有進行相關設定。顯然,任務jar包主要是由task manager執行的,druid datasource相關程式碼也是在運算元中呼叫的,肯定也是在task manager中執行的。

分析到這裡,關鍵點是理解在任務jar包執行過程中,job manager和task manager分別承擔的職責是什麼?
參考https://www.cnblogs.com/xing901022/p/14300093.html

1、job manager 會透過反射呼叫jar包的main方法,然後解析,生成StreamGraph。 因此,我們把setSystemProperties操作放到main方法中執行,自然是在job manager jvm程序中執行
2、job manager把運算元排程到特定的task manager進行執行。

因此,要解決問題,必須在運算元的邏輯程式碼中執行。修改程式碼:

Configuration configuration = ConfigHelper.getConfig();
            if (configuration.getProperties() != null) {
                // 設定系統屬性。控制druid sql log的行為
                SystemPropertiesHelper.setSystemProperties(configuration.getProperties(), "");
            }
            initDataSource();

就ok了。

擴充套件

使用druid 列印sql log,還需要在log4j新增配置:

 <logger name="druid.sql.Statement" additivity="false">
        <level value="DEBUG"></level>
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
    </logger>

相關文章