通过Spark的UDAF看各类大数据组件
在IT界,每一项技术的兴起往往是因为这项技术 解决了某项痛点。
- C语言作为高级语言兴起,很大程度是因为降低了编程难度(对比汇编语言)。
- 数据库的兴起是因为解决了重要数据的存储问题。
- 以Hadoop为首的大数据组件的兴起,就是为了应对爆炸增长的数据量。
大数据处理的原理
Hadoop是最先兴起的大数据组件,它应对海量数据的方法核心就是:分布式,高可用。翻译成人话就是:团队合作。一台机器处理不了,我们就多台机器一起处理嘛。一项任务做不完,就开公司找人一起做!
Hadoop之类的大数据组件核心思想都是靠多台机器一起分工协作完成,但是机器的合作究竟要怎么实现呢?有没有什么具体的例子可以阐述呢?我最近在编写Spark的用户自定义聚合函数(UDAF)时,发现它就是一个极好的例子!
Spark UDAF(用户自定义聚合函数)
官网代码:
(可只查看末尾的 update,merge,evaluate 方法)
object MyAverage extends UserDefinedAggregateFunction {
// 输入数据
def inputSchema: StructType = StructType(StructField("inputColumn", LongType) :: Nil)
// 聚合时所用缓存器Buffer数据类型
def bufferSchema: StructType = {
StructType(StructField("sum", LongType) :: StructField("count", LongType) :: Nil)
}
// 回传数据
def dataType: DataType = DoubleType
// Whether this function always returns the same output on the identical input
def deterministic: Boolean = true
// 初始化Buffer
def initialize(buffer: MutableAggregationBuffer): Unit = {
buffer(0) = 0L
buffer(1) = 0L
}
// 数据输入时更新Buffer
def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
if (!input.isNullAt(0)) {
buffer(0) = buffer.getLong(0) + input.getLong(0)
buffer(1) = buffer.getLong(1) + 1
}
}
// 合并Buffer
def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
buffer1(0) = buffer1.getLong(0) + buffer2.getLong(0)
buffer1(1) = buffer1.getLong(1) + buffer2.getLong(1)
}
// 计算最终结果
def evaluate(buffer: Row): Double = buffer.getLong(0).toDouble / buffer.getLong(1)
}
计算逻辑类比人类团队协作
- update方法
buffer处理输入数据; ===> 每个单人处理部分工作 - merge方法
将多个buffer各自的计算结果合并; ===> 两人之间工作合作 - evaluate方法
将所有buffer合成的数据最后算出结果; ===> 多人合作完成项目
另一个例子:Hadoop的MapReduce就是一个很好的例子;
- Map端将大任务拆解为小任务;
- 小任务分解给各个partition(计算资源)计算;
- Reduce端将大家计算好的小任务合并,并算出最终结果;
一点感想
由此,我们可以很清楚的理解,Hadoop是靠多机器团队协作达到处理海量数据的目的;Hive的出现是为了降低MapReduce的上手难度,并提供分析大量数据的操作方法;Spark的快速计算同样是靠多机器团队协作,但对比MapReduce,Spark能利用内存计算,而不是只依靠较慢的磁盘读写,所以速度更快。这就像是请了更专业,更强的员工一样。
计算机技术在不断更新迭代,但它们的原理往往都来自生活。如果我们能够形象,深刻的理解一些技术的核心思想,那对我们快速学习新技术是十分有帮助的。
这是本人开发的一点小感想,如有哪里说得不对或不合适,欢迎您留言告诉我。反馈也是提升写作必不可少的部分。
如果觉得写得多少有点东西,麻烦您点一点下方的赞哦!!谢谢