以LTE SIG数据源为例,包括基础模型转换算子,Partition分组算子,关联定位算子,业务运算预汇总算子,Counter Reduce算子,通用汇总算子。
业务运算算子都是基于Spark RDD 可伸缩性数据集进行操作的,运算过程通过分布式分发到Executor中执行。基于单一职责原则,将各运算算子抽取为独立的功能运算算子,使模块划分更为清晰,可扩展。
为了使运算算子更为抽象,将Executor中执行的功能抽象出接口,泛型化输入类型,输出类型以及参数类型,并使功能具体可单元测试性。
基础模型转换算子将基于TBaseModel的RDD数据集转换为基于数据模型的RDD数据集,通过版本适配脚本完成模型的转换过程。具体设计可参考2.3节设计。
Partition分组算子基于数据均分原则,对RDD数据集进行分组,达到分布式计算的效率最大化。
关联定位算子承担在预汇总运算之前进行相同数据源或不同数据源之间的字段关联回填,当前支持的包括跨数据源的关联(比如MR关联定位结果,UMTS的CHR数据关联MR数据),和同数据内的关联(比如LTESIG内部的CHR事件关联MR事件)。
业务运算预汇总算子提供给业务特性数据通道,业务特性通过实现预汇总接口执行业务预汇总计算,即Counter计算。平台提供业务相关的数据模型数据集,相关配置等,业务Runner完成指标计算并返回预汇总结果,即F表汇总结果。
Counter Reduce算子获取业务运算汇总算子的预汇总结果,进行Reduce计算。
通用汇总算子按时间维度对预汇总结果进行合并汇总,时间维度包括15分钟,30分钟,60分钟,1天。通用汇总算子也提供给业务自定义汇总的能力。
接口设计
Driver 和 Executor之间的交互接口和参数模型的抽取,定义IExecutor[I, O] 接口描述Executor的输入类型I,输出类型O 和参数模型,继承IExecutor[I, O] 需描述操作的输入输出类型。
SparkTaskExecutorParam 描述Driver 和 Executor之间传递的参数模型。
Driver 和 Executor之间接口定义:
/**
* @version v2.5
* Spark Task Executor 接口
* I:输入泛型
* O: 输出泛型
* sparkTaskExecutorParam:SparkTaskExecutorParam Driver和Task进行参数传递
* @see SparkTaskExecutorParam
*/
trait IExecutor[I, O] {
def execute(input: I, sparkTaskExecutorParam: SparkTaskExecutorParam): O
}
使用实例:
Driver代码调用
val retRdd = callRdd.mapPartitions(rncstdPart => {
MvRncStdSigMapPartitionsExecutor.execute(rncstdPart, sparkTaskExecutorParam)
}, true)
Executor代码
object MvRncStdSigMapPartitionsExecutor
extends IExecutor[Iterator[(Long, IMvUStdSig)], Iterator[(NullWritable, CombineResult)]]
with DriverHelper {
override def execute(input: Iterator[(Long, IMvUStdSig)], sparkTaskExecutorParam: SparkTaskExecutorParam)
: Iterator[(NullWritable, CombineResult)] = {
//… Executor 代码开始
}
}
预汇总接口
/**
*
* 预汇总接口定义<br>
*@version 1
*@since V200R002C00
*
*/
trait IBaseCalcRunner extends scala.Serializable {
def CalcTaskName(): String
/**
* License是否有效
*
* @return
*/
def isLicenseValid(): Boolean
/**
* 当前处理数据源的制式
*
* @return
*/
def calcNetType(): com.huawei.pai.common.condition.DataType
/**
* 执行工参反查等维度变化操作
* @return
*/
def executeDimensionsExchange(): IDimensionsExchange
/**
* 数据输出配置 (表名, (保存时间维度, 保存策略))
*/
def targetTableSavePolicy: List[(String, (TimeDimension,SavePolicy))]
/**
* 原有driver中的privateBean, 在getConfigBean中获取
*/
def loadPrivateBean(conf: Configuration): PrivateConfigBean = { new PrivateConfigBean() }
/**
* 道路等大广播变量加载 ,在localData中获取
*/
def loadLocalData(conf: Configuration): HashMap[String, Any] = { HashMap[String, Any]() }
}
通用汇总接口定义
/**
*
*通用汇总接口定义<br>
*@version 1
*@since V200R002C00
*
*/
trait ISummaryRunner extends scala.Serializable {
/**
* 汇总执行周期
*/
def executePriod: TimeDimension
/**
* 输出表名配置
*/
def summaryTableSavePolicy: List[(String, SavePolicy)]
/**
* 原始表名
*/
def sourceTable: List[String]
/**
* 是否为默认汇总,默认汇总recordToSum不会执行
*/
def isDefaultSummary: Boolean = false
/**
* 单条数据转换为汇总数据
*/
def recordToSum(getConfigBean: Option[Broadcast[CommonConfigBean]], localData: HashMap[String, Any],record: (D2AggrKeys, D2AggrValues)): List[(D2AggrKeys, D2AggrValues)] = {List[(D2AggrKeys, D2AggrValues)]()}
/**
* 框架reduceByKey之后再记录处理配置
*/
def reprocessFunc(): List[(String, IReprocess)] = { List[(String, IReprocess)]() }
/**
* 自定义汇总操作
*/
def executeCustomSummary(sc: SparkContext, filePath:String, startTime:Date, endTime:Date, getConfigBean: Option[Broadcast[CommonConfigBean]]):Unit = {}
def loadSummaryPrivateBean(conf: Configuration): PrivateConfigBean = { new PrivateConfigBean() }
def executeDimensionsExchange() : IDimensionsExchange
def loadLocalData(conf: Configuration): HashMap[String, Any] = { HashMap[String, Any]() }
def tableFormatSpec:Map[String, Map[Int, ICounterFormat]] = Map[String, Map[Int, ICounterFormat]]()
}
扩展性设计
该模块出现的需要扩展的功能包括:
1. 数据源类型的增加,需要定义新数据源的数据模型,实现新的数据源数据模型对应的运算算子模板类函数,处理流程和业务运算算子可以直接复用。
2. 数据模型增加字段,由于事件模型存储的内容为序列化的二进制信息,为了能兼容之前版本的模型反序列化,需要增加一个新版本的数据模型结构,因此需要进行新的数据模型结构的适配,可能需要完成新字段的模型转换,如果有关联要求,还需要增加关联条件和关联回填功能,业务运算算子处理流程可以复用。
3. 基于泛型类型实现的Executor 实现类可根据输入输出类型进行扩展。
4. 扩展设计约束:对于Driver 和Executor之间的参数传递数据模型需要类型固定,保持接口稳定,同时IExecutor接口支持类型泛型扩展。
安全分析
该模块不涉及敏感数据处理,所依赖的配置文件也来自集群信任域,不涉及安全分析。
注意以下安全设计原则:
密码/密钥等敏感数据使用加密值进行传递,临时存放在内存中,在使用阶段进行解密临时存储在 byte 数组或 char 数组中,使用完后进行覆盖。
异常捕获进行打印运行日志时对敏感异常进行