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
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...
随机推荐
- 注册google账号 解决国内手机注册失败的问题
1. PC端下载夜神安卓模拟器.安装,启动. 2. 在模拟器里的市场应用里下载qq邮箱. 3. 启动邮箱,选择gmail,注册.后续一切顺利. 这是迄今为止,唯一注册顺利的方法.其他方法,手机验证一关 ...
- Python中类的定义与使用
目标: 1.类的定义 2.父类,子类定义,以及子类调用父类 3.类的组合使用 4.内置功能 1.类的定义 代码如下: #!/usr/bin/env python #coding:utf8 class ...
- discuz回贴通知插件实现-用户状态设置
1.获取用户提交数据 discuz通过$_GET来获取全部数据,包括($_GET,$_POST). else if($_GET['pluginop'] == 'set') { //获取用户提交数据 $ ...
- Django之常用命令以及问题汇总
基本命令 1.新建一个django项目 django-admin.py startproject project-name 2.新建一个app python manage.py startapp ap ...
- nzhtl1477-ただいま帰りました ( bfs )
nzhtl1477-ただいま帰りました 题目描述 珂学题意: 你是威廉!你要做黄油蛋糕给珂朵莉吃~! 68号岛有n个商店,有的商店直接有小路连接,小路的长度都为1 格里克告诉了你哪些地方可能有做黄油蛋 ...
- Codeforces 599B. Spongebob and Joke 模拟
B. Spongebob and Joke time limit per test 2 seconds memory limit per test 256 megabytes input standa ...
- 讲真的,千万别得罪会PS的人
传说中有一种软件炒鸡可怕 那就是PS,专业术语是photoshop! 它能让你貌美如花 也能让你瞬间丑得掉渣 更可怕的是网络上大神的出现 简直让我们难以想象的厉害! 下面大家一起来欣赏一下 那些大神帮 ...
- 11个 常见UI/UX设计师调查问卷分析
作为专业人员,设计出优秀的作品是UI/UX设计师必备的技能,同样重要的是良好的沟通能力.进一步来讲,提出正确的问题也是作为设计师的技能之一. 任何项目的首要任务都是收集需要的信息,以便正确有效地完成我 ...
- static 和 final
static是静态修饰关键字,可以修饰变量和程序块以及类方法:当你定义一个static的变量的时候jvm会将将其分配在内存堆上,所有程序对它的引用都会指向这一个地址而不会重新分配内存:修饰一个程序块的 ...
- 2018.09.10 bzoj1597: [Usaco2008 Mar]土地购买(斜率优化dp)
传送门 终究还是通宵了啊... 这是一道简单的斜率优化dp. 先对所有土地排序,显然如果有严格小于的两块土地不用考虑小的一块. 于是剩下的土地有一条边单增,另外一条单减. 我们假设a[i]是单减的,b ...