StructuredStream StateStore机制
ref: https://jaceklaskowski.gitbooks.io/spark-structured-streaming/
StruncturedStream的statefule实现基于StateStore,能够记忆历史的结果,从而形成unbounded流式计算。其内部实际上是将历史的统计结果存在StateStore(目前是基于HDFS存储数据)。每次计算时,会执行StateStoreRestore->Agg->StateStoreSave:
stateful机制以来与StateStoreRDD
logical plan逻辑:
StateStoreRestore/Save都是基于StateStoreRDD
StateStoreRDD基于StateStoreCoordinator获取state的location,作为preferred location.
数据来源包含StateStore的历史结果和新batch的RDD数据。
StateStoreRDD is an RDD for executing storeUpdateFunction with StateStore (and data from partitions of a new batch RDD).
最终StateStoreRDD将merge历史的state和新的batch data:
// StateStoreRDD#compute
override def compute(partition: Partition, ctxt: TaskContext): Iterator[U] = {
var store: StateStore = null
val storeId = StateStoreId(checkpointLocation, operatorId, partition.index)
store = StateStore.get(
storeId, keySchema, valueSchema, storeVersion, storeConf, confBroadcast.value.value) // 获取Store
val inputIter = dataRDD.iterator(partition, ctxt) // 新batch的数据
storeUpdateFunction(store, inputIter) // 结合计算,Restore和Save的逻辑不同
}
storeUpdateFunction of StateStoreRestore
Restore时的merge逻辑是将历史state和新batch的数据,按相同的key合并在一起,主要调用store#get(key)
{ case (store, iter) =>
val getKey = GenerateUnsafeProjection.generate(keyExpressions, child.output)
iter.flatMap { row =>
val key = getKey(row)
val savedState = store.get(key)
numOutputRows += 1
row +: savedState.toSeq
}
storeUpdateFunction of StateStoreSave (以outMode=complete为例),主要调用 store#put(key,value)
{ (store, iter) =>
val getKey = GenerateUnsafeProjection.generate(keyExpressions, child.output)
...
outputMode match {
// Update and output all rows in the StateStore.
case Some(Complete) =>
while (iter.hasNext) {
val row = iter.next().asInstanceOf[UnsafeRow]
val key = getKey(row)
store.put(key.copy(), row.copy())
numUpdatedStateRows += 1
}
store.commit()
numTotalStateRows += store.numKeys()
store.iterator().map { case (k, v) =>
numOutputRows += 1
v.asInstanceOf[InternalRow]
}
...
StateStore (HDFSBackedStateStore)
简单理解一下StateStore。直观上,在DStream
框架下如果要实现stateful,我们也会把历史的state用一个RDD存下来,每次新的数据计算完成后再跟历史RDD融合(通过checkpoint避免超长lineage)。这个思路是完全正确并且和StructuredStream的思路相似。
- key/value的schema
- preferred location优化
StateStoreRDD
是逻辑上的RDD,因为它的数据实际上来源于history+new batch。
- 它的partition是new batch的partition。
override protected def getPartitions: Array[Partition] = dataRDD.partitions
- preferredLocation选择
p1 -> 计算其对应的历史state store的storeId->从storeCoor获取该storeId的location。(注:可有可无)
StoreId 由( checkpointLocation, operationId, partition.index)唯一确定。
override def getPreferredLocations(partition: Partition): Seq[String] = {
val storeId = StateStoreId(checkpointLocation, operatorId, partition.index)
storeCoordinator.flatMap(_.getLocation(storeId)).toSeq
}
- compute过程
override def compute(partition: Partition, ctxt: TaskContext): Iterator[U] = {
var store: StateStore = null
val storeId = StateStoreId(checkpointLocation, operatorId, partition.index)
store = StateStore.get(
storeId, keySchema, valueSchema, storeVersion, storeConf, confBroadcast.value.value)
val inputIter = dataRDD.iterator(partition, ctxt)
storeUpdateFunction(store, inputIter)
}
※ 根据storeId,key/valueSchema, version等信息获取store (StateStore#get)
def get(
storeId: StateStoreId,
keySchema: StructType,
valueSchema: StructType,
version: Long,
storeConf: StateStoreConf,
hadoopConf: Configuration): StateStore = {
require(version >= 0)
val storeProvider = loadedProviders.synchronized {
startMaintenanceIfNeeded()
val provider = loadedProviders.getOrElseUpdate(
storeId,
new HDFSBackedStateStoreProvider(storeId, keySchema, valueSchema, storeConf, hadoopConf))
reportActiveStoreInstance(storeId)
provider
}
storeProvider.getStore(version)
}
→ storeProvider.getStore(version)
基于type MapType = java.util.concurrent.ConcurrentHashMap[UnsafeRow, UnsafeRow]
loadMap
从HDFS中将数据读入到Map中。
override def getStore(version: Long): StateStore = synchronized {
require(version >= 0, "Version cannot be less than 0")
val newMap = new MapType()
if (version > 0) {
newMap.putAll(loadMap(version))
}
val store = new HDFSBackedStateStore(version, newMap)
logInfo(s"Retrieved version $version of ${HDFSBackedStateStoreProvider.this} for update")
store
}
StructuredStream StateStore机制的更多相关文章
- 笔记:Binder通信机制
TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...
- JAVA回调机制(CallBack)详解
序言 最近学习java,接触到了回调机制(CallBack).初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义.当然了,我在理解了回 ...
- 谈谈DOMContentLoaded:Javascript中的domReady引入机制
一.扯淡部分 回想当年,在摆脱写页面时js全靠从各种DEMO中copy出来然后东拼西凑的幽暗岁月之后,毅然决然地打算放弃这种处处“拿来主义”的不正之风,然后开启通往高大上的“前端攻城狮”的飞升之旅.想 ...
- 路由的Resolve机制(需要了解promise)
angular的resovle机制,实际上是应用了promise,在进入特定的路由之前给我们一个做预处理的机会 1.在进入这个路由之前先懒加载对应的 .js $stateProvider .state ...
- Android权限管理之Permission权限机制及使用
前言: 最近突然喜欢上一句诗:"宠辱不惊,看庭前花开花落:去留无意,望天空云卷云舒." 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过 ...
- Java学习之反射机制及应用场景
前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...
- .NET Core采用的全新配置系统[10]: 配置的同步机制是如何实现的?
配置的同步涉及到两个方面:第一,对原始的配置文件实施监控并在其发生变化之后从新加载配置:第二,配置重新加载之后及时通知应用程序进而使后者能够使用最新的配置.要了解配置同步机制的实现原理,先得从认识一个 ...
- Go结构体实现类似成员函数机制
Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...
- 操作系统篇-分段机制与GDT|LDT
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...
随机推荐
- java中checked和unchecked 异常处理
有两种类型的异常:一种是checked异常一种是unchecked异常,在这篇文章中我们将利用实例来学习这两种异常,checked的异常和unchecked异常最大的区别就是checked去唱是在编译 ...
- richface的配置、用法介绍和注意事项
richface的配置.用法介绍和注意事项一.RichFaces (3.1.x) 技术需求 1.JDK 1.5 或更高版本: 2.支持的 JSF 实现: Sun JSF 1.1 RI - 1.2 My ...
- ios 打tag
修改spec文件的version: git commit -am"version 0.1.1" git push origin master -u git tag 0.1.1 gi ...
- 【校招面试 之 剑指offer】第18题 删除链表中的节点
题目一:在O(1)时间内删除链表节点. 给定单项链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点. 思路:(1)如果要删除的节点不是链表的尾节点,则将被删除节点的内容复制到该节点,然 ...
- 【校招面试 之 C/C++】第26题 C++ 智能指针(二)之 share_ptr
1.综述 shared_ptr 是一个标准的共享所有权的智能指针, 允许多个指针指向同一个对象. 定义在 memory 文件中(非memory.h), 命名空间为 std. shared_ptr 是为 ...
- C#中如何创建xml文件 增、删、改、查 xml节点信息
XML:Extensible Markup Language(可扩展标记语言)的缩写,是用来定义其它语言的一种元语言,其前身是SGML(Standard Generalized Markup Lang ...
- [leetcode]117. Populating Next Right Pointers in Each NodeII用next填充同层相邻节点
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...
- DB2锁机制
相比较Oracle来说,DB2的锁机制麻烦了很多,而且这个麻烦带来的不是性能的上升而是下降,不过如果细致了解的话,只能感慨不愧是数据库理论诞生的公司,在实现数据库理论上比Oracle全面得多. ...
- 模板练习(LUOGU)
1:并查集 P3183食物链 #define man 300050 ; int find(int x){ if(fa[x]==x) return fa[x]; return fa[x]=find(fa ...
- 洛谷 P2986 [USACO10MAR]伟大的奶牛聚集(树形动规)
题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...