教程 | Datavines 自定義數(shù)據(jù)質量檢查規(guī)則(Metric)

Metric 是 Datavines 中一個核心概念冷尉,一個 Metric 表示一個數(shù)據(jù)質量檢查規(guī)則漱挎,比如空值檢查和表行數(shù)檢查都是一個規(guī)則。Metric 采用插件化設計雀哨,用戶可以根據(jù)自己的需求來實現(xiàn)一個 Metric 磕谅。下面我們來詳細講解一下如何自定義Metric

第一步

我們先了解下幾個接口和抽象類雾棺,它們是實現(xiàn)自定義 Metric 的關鍵膊夹。

SqlMetric 接口

SqlMetric接口中定義了規(guī)則的各種屬性和操作的接口。

@SPI
public interface SqlMetric {
    // 中文名
    String getName();
    // 英文名
    String getZhName();
    // 根據(jù)系統(tǒng)的語言進行名字返回
    default String getNameByLanguage(boolean isEn) {
        return isEn ? getName() : getZhName();
    }
    // 規(guī)則屬于哪個維度垢村,比如準確性割疾、唯一性等等
    MetricDimension getDimension();
    // 規(guī)則的類型,包括單表檢查嘉栓、單表自定義檢查
    MetricType getType();
    // 規(guī)則的級別宏榕,比如表級別、列級別
    default MetricLevel getLevel() {
        return MetricLevel.NONE;
    }
    // 是否支持錯誤數(shù)據(jù)輸出
    boolean isInvalidateItemsCanOutput();

    /**
     * 獲取不符合規(guī)則的數(shù)據(jù)的SQL語句
     * @return ExecuteSql
     */
    ExecuteSql getInvalidateItems(String uniqueKey);

    /**
     * 計算實際值的SQL語句
     * @return ExecuteSql
     */
    ExecuteSql getActualValue(String uniqueKey);

    /**
     * 實際值的字段名
     */
    default String getActualName() {
        return "actual_value";
    }
    // 實際值的類型侵佃,比如數(shù)字麻昼,百分比或者列表
    default String getActualValueType() {
        return MetricActualValueType.COUNT.getDescription();
    }
    // 對參數(shù)進行檢查并輸出檢查結果
    CheckResult validateConfig(Map<String,Object> config);
    //規(guī)則所需要的參數(shù)
    Map<String, ConfigItem> getConfigMap();
    //構造規(guī)則前需要做的檢查
    void prepare(Map<String,String> config);

    default String getIssue() {
        return "";
    }
    // 適合哪些字段類型
    List<DataVinesDataType> suitableType();
    // 是否支持多選,比如表行數(shù)檢查支持多張表
    default boolean supportMultiple() {
        return false;
    }
    // 對規(guī)則參數(shù)的重新構造馋辈,配合表行數(shù)多張表檢查
    default List<Map<String,Object>> getMetricParameter(Map<String,Object> metricParameter) {
        return Collections.singletonList(metricParameter);
    }
}

BaseSingleTable 抽象類

BaseSingleTable是實現(xiàn)了 SqlMetric 接口的抽象類抚芦,實現(xiàn)了表級別檢查規(guī)則中所需要參數(shù)的添加、錯誤數(shù)據(jù)SQL語句構造和實際值計算SQL語句構造和對過濾條件的處理等。

  • 這里定義了獲取不符合規(guī)則的數(shù)據(jù)的基礎SQL語句叉抡,判斷類型的規(guī)則比如正則表達式檢查和枚舉值檢查尔崔,只需要在基礎SQL語句后面添加過濾條件即可。
    protected StringBuilder invalidateItemsSql = new StringBuilder("select * from ${table}");
  • 實際值計算SQL語句默認是計算不符合規(guī)則數(shù)據(jù)的行數(shù)
String actualValueSql = "select count(1) as actual_value_"+ uniqueKey +" from ${invalidate_items_table}"; 
  • 計算平均值褥民、匯總值等統(tǒng)計類型的規(guī)則需要重新實現(xiàn)getActualValue()中的ExecuteSql季春。
public abstract class BaseSingleTable implements SqlMetric {
    // 這里定義了獲取不符合規(guī)則的數(shù)據(jù)的基礎 SQL 語句,判斷類的規(guī)則比如正則表達式和枚舉值檢查消返,只需要在基礎SQL后面添加過濾條件即可载弄。
    protected StringBuilder invalidateItemsSql = new StringBuilder("select * from ${table}");

    protected List<String> filters = new ArrayList<>();

    protected HashMap<String,ConfigItem> configMap = new HashMap<>();

    protected Set<String> requiredOptions = new HashSet<>();

    public BaseSingleTable() {
        configMap.put("table",new ConfigItem("table", "表名", "table"));
        configMap.put("filter",new ConfigItem("filter", "過濾條件", "filter"));

        requiredOptions.add("table");
    }

    @Override
    public ExecuteSql getInvalidateItems(String uniqueKey) {
        ExecuteSql executeSql = new ExecuteSql();
        executeSql.setResultTable("invalidate_items_" + uniqueKey);
        executeSql.setSql(invalidateItemsSql.toString());
        executeSql.setErrorOutput(isInvalidateItemsCanOutput());
        return executeSql;
    }

    @Override
    public ExecuteSql getActualValue(String uniqueKey) {
        ExecuteSql executeSql = new ExecuteSql();
        executeSql.setResultTable("invalidate_count_" + uniqueKey);
        String actualValueSql = "select count(1) as actual_value_"+ uniqueKey +" from ${invalidate_items_table}";
        executeSql.setSql(actualValueSql);
        executeSql.setErrorOutput(false);
        return executeSql;
    }

    @Override
    public CheckResult validateConfig(Map<String, Object> config) {
        return ConfigChecker.checkConfig(config, requiredOptions);
    }

    @Override
    public void prepare(Map<String, String> config) {
        if (config.containsKey("filter")) {
            filters.add(config.get("filter"));
        }

        addFiltersIntoInvalidateItemsSql();
    }

    private void addFiltersIntoInvalidateItemsSql() {
        if (filters.size() > 0) {
            invalidateItemsSql.append(" where ").append(String.join(" and ", filters));
        }
    }

    @Override
    public MetricLevel getLevel() {
        return MetricLevel.TABLE;
    }
}

BaseSingleTableColumn 抽象類

BaseSingleTableColumn是列級別的抽象實現(xiàn)類,主要是添加列級別規(guī)則的通用參數(shù)撵颊。

public abstract class BaseSingleTableColumn extends BaseSingleTable {

    public BaseSingleTableColumn() {
        super();
        configMap.put("column",new ConfigItem("column", "列名", "column"));
        requiredOptions.add("column");
    }

    @Override
    public Map<String, ConfigItem> getConfigMap() {
        return configMap;
    }

    @Override
    public MetricLevel getLevel() {
        return MetricLevel.COLUMN;
    }

    @Override
    public boolean isInvalidateItemsCanOutput() {
        return false;
    }
}

第二步

了解完上面的三個基礎類以后宇攻,自定義一個Metric就變得格外簡單了。

以 枚舉值檢查 規(guī)則為例來講解

  • 判斷要實現(xiàn)的規(guī)則的級別倡勇,因為枚舉值檢查是列級別逞刷,所以繼承 BaseSingleTableColumn 即可。
  • 在構造函數(shù)中的configMap添加enum_list參數(shù)用于返回給前端進行展示译隘,在requiredOptions添加enum_list用于參數(shù)的檢查亲桥。
  • 實現(xiàn)英文名、中文名固耘、規(guī)則維度题篷、規(guī)則類型這些基礎的屬性。
  • 因為枚舉值檢查規(guī)則是為了找出在枚舉值列表中的數(shù)據(jù)厅目,所以只需要在fileters這個數(shù)組里面加入(${column} in ( ${enum_list} ))番枚,prepare()方法會自動進行不符合規(guī)則的SQL語句構造。
  • 實現(xiàn)suitableType()方法添加規(guī)則適用的字段類型损敷。
public class ColumnInEnums extends BaseSingleTableColumn {

    public ColumnInEnums(){
        super();
        configMap.put("enum_list",new ConfigItem("enum_list", "枚舉值列表", "enum_list"));
        requiredOptions.add("enum_list");
    }

    @Override
    public String getName() {
        return "column_in_enums";
    }

    @Override
    public String getZhName() {
        return "枚舉值檢查";
    }

    @Override
    public MetricDimension getDimension() {
        return MetricDimension.EFFECTIVENESS;
    }

    @Override
    public MetricType getType() {
        return MetricType.SINGLE_TABLE;
    }

    @Override
    public boolean isInvalidateItemsCanOutput() {
        return true;
    }

    @Override
    public void prepare(Map<String, String> config) {
        if (config.containsKey("enum_list") && config.containsKey("column")) {
            filters.add(" (${column} in ( ${enum_list} )) ");
        }
        super.prepare(config);
    }

    @Override
    public List<DataVinesDataType> suitableType() {
        return Arrays.asList(DataVinesDataType.NUMERIC_TYPE, DataVinesDataType.STRING_TYPE, DataVinesDataType.DATE_TIME_TYPE);
    }
}

第三步

非常重要的一步

  • 在 resources 目錄下創(chuàng)建META-INF/plugins目錄葫笼。
  • 在 plugins 目錄下創(chuàng)建文件并且命名為io.datavines.metric.api.SqlMetric
  • 在文件中添加column_in_enums=io.datavines.metric.plugin.ColumnInEnums拗馒。

第四步

打包成jar放到 datavines 目錄下的libs目錄下即可路星。

收工!自定義 Metric 就這樣輕松搞定了诱桂。

加入我們

Datavines 的目標是成為更好的數(shù)據(jù)可觀測性領域的開源項目洋丐,為更多的用戶去解決元數(shù)據(jù)管理和數(shù)據(jù)質量管理中遇到的問題。在此我們真誠歡迎更多的貢獻者參與到社區(qū)建設中來挥等,和我們一起成長友绝,攜手共建更好的社區(qū)。

關于Datavane

Datavane是一個專注于大數(shù)據(jù)領域的開源組織(社區(qū))肝劲,由一群大數(shù)據(jù)領域優(yōu)秀的開源項目作者共同創(chuàng)建迁客,旨在幫助開源項目作者更好的建設項目郭宝、為大眾提供高質量的開源軟件,宗旨是:只為做一個好軟件掷漱。目前已經(jīng)聚集了一批優(yōu)質的開源項目粘室,涉及到數(shù)據(jù)集成、大數(shù)據(jù)組件管理卜范、數(shù)據(jù)質量等育特。

Datavane 社區(qū)中,所有的項目都是開源開放的先朦,代碼質量和架構設計優(yōu)質的潛力項目。社區(qū)保持開放中立犬缨、協(xié)作創(chuàng)造喳魏、堅持精品,鼓勵所有的開發(fā)者怀薛、用戶和貢獻者積極參與我們的社區(qū)刺彩、共同合作,創(chuàng)新創(chuàng)造枝恋,建設一個更加強大的開源社區(qū)创倔。

Github: https://github.com/datavane

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市焚碌,隨后出現(xiàn)的幾起案子畦攘,更是在濱河造成了極大的恐慌,老刑警劉巖十电,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件知押,死亡現(xiàn)場離奇詭異,居然都是意外死亡鹃骂,警方通過查閱死者的電腦和手機台盯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畏线,“玉大人静盅,你說我怎么就攤上這事∏夼梗” “怎么了蒿叠?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長杯矩。 經(jīng)常有香客問我栈虚,道長,這世上最難降的妖魔是什么史隆? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任魂务,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘粘姜。我一直安慰自己鬓照,他們只是感情好,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布孤紧。 她就那樣靜靜地躺著豺裆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪号显。 梳的紋絲不亂的頭發(fā)上臭猜,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機與錄音押蚤,去河邊找鬼蔑歌。 笑死,一個胖子當著我的面吹牛揽碘,可吹牛的內容都是我干的次屠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼雳刺,長吁一口氣:“原來是場噩夢啊……” “哼劫灶!你這毒婦竟也來了?” 一聲冷哼從身側響起掖桦,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤本昏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后枪汪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凛俱,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年料饥,在試婚紗的時候發(fā)現(xiàn)自己被綠了蒲犬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡岸啡,死狀恐怖原叮,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情巡蘸,我是刑警寧澤奋隶,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站悦荒,受9級特大地震影響唯欣,放射性物質發(fā)生泄漏。R本人自食惡果不足惜搬味,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一境氢、第九天 我趴在偏房一處隱蔽的房頂上張望蟀拷。 院中可真熱鬧,春花似錦萍聊、人聲如沸问芬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽此衅。三九已至,卻和暖如春亭螟,著一層夾襖步出監(jiān)牢的瞬間挡鞍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工预烙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留匕累,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓默伍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親衰琐。 傳聞我的和親對象是個殘疾皇子也糊,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容