Metric 是 Datavines 中一个核心概念,一个 Metric 表示一个数据质量检查规则,比如空值检查和表行数检查都是一个规则。Metric 采用插件化设计,用户可以根据自己的需求来实现一个 Metric。下面我们来详细讲解一下如何自定义Metric
。
【资料图】
第一步我们先了解下几个接口和抽象类,它们是实现自定义 Metric 的关键。
SqlMetric 接口SqlMetric
接口中定义了规则的各种属性和操作的接口。
@SPIpublic interface SqlMetric { // 中文名 String getName(); // 英文名 String getZhName(); // 根据系统的语言进行名字返回 default String getNameByLanguage(boolean isEn) { return isEn ? getName() : getZhName(); } // 规则属于哪个维度,比如准确性、唯一性等等 MetricDimension getDimension(); // 规则的类型,包括单表检查、单表自定义检查 MetricType getType(); // 规则的级别,比如表级别、列级别 default MetricLevel getLevel() { return MetricLevel.NONE; } // 是否支持错误数据输出 boolean isInvalidateItemsCanOutput(); /** * 获取不符合规则的数据的SQL语句 * @return ExecuteSql */ ExecuteSql getInvalidateItems(String uniqueKey); /** * 计算实际值的SQL语句 * @return ExecuteSql */ ExecuteSql getActualValue(String uniqueKey); /** * 实际值的字段名 */ default String getActualName() { return "actual_value"; } // 实际值的类型,比如数字,百分比或者列表 default String getActualValueType() { return MetricActualValueType.COUNT.getDescription(); } // 对参数进行检查并输出检查结果 CheckResult validateConfig(Map config); //规则所需要的参数 Map getConfigMap(); //构造规则前需要做的检查 void prepare(Map config); default String getIssue() { return ""; } // 适合哪些字段类型 List suitableType(); // 是否支持多选,比如表行数检查支持多张表 default boolean supportMultiple() { return false; } // 对规则参数的重新构造,配合表行数多张表检查 default List
BaseSingleTable 抽象类BaseSingleTable
是实现了 SqlMetric 接口的抽象类,实现了表级别检查规则中所需要参数的添加、错误数据SQL语句构造和实际值计算SQL语句构造和对过滤条件的处理等。
protected StringBuilder invalidateItemsSql = new StringBuilder("select * from ${table}");
实际值计算SQL语句默认是计算不符合规则数据的行数String actualValueSql = "select count(1) as actual_value_"+ uniqueKey +" from ${invalidate_items_table}";
计算平均值、汇总值等统计类型的规则需要重新实现getActualValue()
中的ExecuteSql
。public abstract class BaseSingleTable implements SqlMetric { // 这里定义了获取不符合规则的数据的基础 SQL 语句,判断类的规则比如正则表达式和枚举值检查,只需要在基础SQL后面添加过滤条件即可。 protected StringBuilder invalidateItemsSql = new StringBuilder("select * from ${table}"); protected List filters = new ArrayList<>(); protected HashMap configMap = new HashMap<>(); protected Set 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 config) { return ConfigChecker.checkConfig(config, requiredOptions); } @Override public void prepare(Map 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
是列级别的抽象实现类,主要是添加列级别规则的通用参数。
public abstract class BaseSingleTableColumn extends BaseSingleTable { public BaseSingleTableColumn() { super(); configMap.put("column",new ConfigItem("column", "列名", "column")); requiredOptions.add("column"); } @Override public Map getConfigMap() { return configMap; } @Override public MetricLevel getLevel() { return MetricLevel.COLUMN; } @Override public boolean isInvalidateItemsCanOutput() { return false; }}
第二步了解完上面的三个基础类以后,自定义一个Metric
就变得格外简单了。
在 datavines-metric-plugins 下创建一个新规则的 module
在 pom.xml 中添加
io.datavines datavines-metric-base ${project.version}
以 枚举值检查 规则为例来讲解判断要实现的规则的级别,因为枚举值检查是列级别,所以继承 BaseSingleTableColumn 即可。在构造函数中的configMap
添加enum_list
参数用于返回给前端进行展示,在requiredOptions
添加enum_list
用于参数的检查。实现英文名、中文名、规则维度、规则类型这些基础的属性。因为枚举值检查规则是为了找出在枚举值列表中的数据,所以只需要在fileters
这个数组里面加入(${column} in ( ${enum_list} ))
,prepare()
方法会自动进行不符合规则的SQL语句构造。实现suitableType()
方法添加规则适用的字段类型。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 config) { if (config.containsKey("enum_list") && config.containsKey("column")) { filters.add(" (${column} in ( ${enum_list} )) "); } super.prepare(config); } @Override public List suitableType() { return Arrays.asList(DataVinesDataType.NUMERIC_TYPE, DataVinesDataType.STRING_TYPE, DataVinesDataType.DATE_TIME_TYPE); }}
第三步非常重要的一步
在 resources 目录下创建META-INF/plugins
目录。在 plugins 目录下创建文件并且命名为io.datavines.metric.api.SqlMetric
。在文件中添加column_in_enums=io.datavines.metric.plugin.ColumnInEnums
。第四步打包成jar
放到 datavines 目录下的libs
目录下即可。
收工!自定义 Metric 就这样轻松搞定了。
加入我们Datavines 的目标是成为更好的数据可观测性领域的开源项目,为更多的用户去解决元数据管理和数据质量管理中遇到的问题。在此我们真诚欢迎更多的贡献者参与到社区建设中来,和我们一起成长,携手共建更好的社区。
项目地址:https://github.com/datavane/datavines问题和建议:https://github.com/datavane/datavines/issues贡献代码:https://github.com/datavane/datavines/pulls关于DatavaneDatavane
是一个专注于大数据领域的开源组织(社区),由一群大数据领域优秀的开源项目作者共同创建,旨在帮助开源项目作者更好的建设项目、为大众提供高质量的开源软件,宗旨是:只为做一个好软件。目前已经聚集了一批优质的开源项目,涉及到数据集成、大数据组件管理、数据质量等。
在 Datavane
社区中,所有的项目都是开源开放的,代码质量和架构设计优质的潜力项目。社区保持开放中立、协作创造、坚持精品,鼓励所有的开发者、用户和贡献者积极参与我们的社区、共同合作,创新创造,建设一个更加强大的开源社区。
官 网: http://www.datavane.org/Github : https://github.com/datavane
关键词:
质检
推荐