LocalState

A simple, durable, atomic K/V database. *Very inefficient*, should only be used for occasional reads/writes. Every read/write hits disk.

基于map实现, 每次读写都需要从磁盘上将数据读出, 并反序列化成map, 这个过程称为snapshot. 所以说是比较简单和低效的, 只能用于读取配置或参数, 这种偶尔读取的场景.

    public synchronized Map<Object, Object> snapshot() throws IOException {
int attempts = 0;
while(true) {
String latestPath = _vs.mostRecentVersionPath();
if(latestPath==null) return new HashMap<Object, Object>();
try {
return (Map<Object, Object>) Utils.deserialize(FileUtils.readFileToByteArray(new File(latestPath)));
} catch(IOException e) {
attempts++;
if(attempts >= 10) {
throw e;
}
}
}

读写操作都是基于map的操作, get和put, 但是put需要做persist操作.

这里使用synchronized来做对象的线程间同步, 对于一个LocalState对象, 所有synchronized标有的函数只能被串行操作.

    public Object get(Object key) throws IOException {
return snapshot().get(key);
}
public synchronized void put(Object key, Object val, boolean cleanup) throws IOException {
Map<Object, Object> curr = snapshot();
curr.put(key, val);
persist(curr, cleanup);
}

当然不止这么简单, 为了达到atomic, 还使用了VersionedStore, 参考下一章

persist不会去update现有的文件, 而是不断的产生递增version的文件, 故每一批更新都会产生一个新的文件

把需要写入的数据序列化

创建新的versionfile的path

把数据写入versionfile

调用succeedVersion, 创建tokenfile以标志versionfile的写入完成

清除旧版本, 只保留4个版本

    private void persist(Map<Object, Object> val, boolean cleanup) throws IOException {
byte[] toWrite = Utils.serialize(val);
String newPath = _vs.createVersion();
FileUtils.writeByteArrayToFile(new File(newPath), toWrite);
_vs.succeedVersion(newPath);
if(cleanup) _vs.cleanup(4);
}

 

VersionedStore

    public VersionedStore(String path) throws IOException {
_root = path;
mkdirs(_root);
}

这个store, 其实就是_root目录下的一堆文件

文件分两种,

VersionFile, _root + version, 真正的数据存储文件

TokenFile, _root + version + “.version”, 标志位文件, 标志version文件是否完成写操作, 以避免读到正在更新的文件

getAllVersions就是读出所有_root目录下的所有完成写操作的文件, 读出version, 并做从大到小的排序

    public List<Long> getAllVersions() throws IOException {
List<Long> ret = new ArrayList<Long>();
for(String s: listDir(_root)) {
if(s.endsWith(FINISHED_VERSION_SUFFIX)) {
ret.add(validateAndGetVersion(s));
}
}
Collections.sort(ret);
Collections.reverse(ret);
return ret;
}

 

找到最新的版本文件

    public Long mostRecentVersion() throws IOException {
List<Long> all = getAllVersions();
if(all.size()==0) return null;
return all.get(0);

 

创建新版本号, 用当前时间作为version

    public String createVersion() throws IOException {
Long mostRecent = mostRecentVersion();
long version = Time.currentTimeMillis();
if(mostRecent!=null && version <= mostRecent) {
version = mostRecent + 1;
}
return createVersion(version);
} public String createVersion(long version) throws IOException {
String ret = versionPath(version);
if(getAllVersions().contains(version))
throw new RuntimeException("Version already exists or data already exists");
else
return ret;
}
 

创建tokenfile, 以标记versionfile写完成

    public void succeedVersion(String path) throws IOException {
long version = validateAndGetVersion(path);
// should rewrite this to do a file move
createNewFile(tokenPath(version));
}
 

清除旧的版本, 只保留versionsToKeep个, 清除操作就是删除versionfile和tokenfile

    public void cleanup(int versionsToKeep) throws IOException {
List<Long> versions = getAllVersions();
if(versionsToKeep >= 0) {
versions = versions.subList(0, Math.min(versions.size(), versionsToKeep));
}
HashSet<Long> keepers = new HashSet<Long>(versions); for(String p: listDir(_root)) {
Long v = parseVersion(p);
if(v!=null && !keepers.contains(v)) {
deleteVersion(v);
}
}
}

Storm-源码分析-LocalState (backtype.storm.utils)的更多相关文章

  1. Storm源码分析--Nimbus-data

    nimbus-datastorm-core/backtype/storm/nimbus.clj (defn nimbus-data [conf inimbus] (let [forced-schedu ...

  2. JStorm与Storm源码分析(四)--均衡调度器,EvenScheduler

    EvenScheduler同DefaultScheduler一样,同样实现了IScheduler接口, 由下面代码可以看出: (ns backtype.storm.scheduler.EvenSche ...

  3. JStorm与Storm源码分析(三)--Scheduler,调度器

    Scheduler作为Storm的调度器,负责为Topology分配可用资源. Storm提供了IScheduler接口,用户可以通过实现该接口来自定义Scheduler. 其定义如下: public ...

  4. JStorm与Storm源码分析(二)--任务分配,assignment

    mk-assignments主要功能就是产生Executor与节点+端口的对应关系,将Executor分配到某个节点的某个端口上,以及进行相应的调度处理.代码注释如下: ;;参数nimbus为nimb ...

  5. storm源码分析之任务分配--task assignment

    在"storm源码分析之topology提交过程"一文最后,submitTopologyWithOpts函数调用了mk-assignments函数.该函数的主要功能就是进行topo ...

  6. JStorm与Storm源码分析(一)--nimbus-data

    Nimbus里定义了一些共享数据结构,比如nimbus-data. nimbus-data结构里定义了很多公用的数据,请看下面代码: (defn nimbus-data [conf inimbus] ...

  7. Nimbus<三>Storm源码分析--Nimbus启动过程

    Nimbus server, 首先从启动命令开始, 同样是使用storm命令"storm nimbus”来启动看下源码, 此处和上面client不同, jvmtype="-serv ...

  8. storm源码分析之topology提交过程

    storm集群上运行的是一个个topology,一个topology是spouts和bolts组成的图.当我们开发完topology程序后将其打成jar包,然后在shell中执行storm jar x ...

  9. JStorm与Storm源码分析(五)--SpoutOutputCollector与代理模式

    本文主要是解析SpoutOutputCollector源码,顺便分析该类中所涉及的设计模式–代理模式. 首先介绍一下Spout输出收集器接口–ISpoutOutputCollector,该接口主要声明 ...

随机推荐

  1. 从零开始,跟我一起做jblog项目(二)Maven

    从零开始,跟我一起做jblog项目(一)引言 从零开始,跟我一起做jblog项目(二)Maven maven是一个项目管理工具,尤其适用于JAVA世界 在jblog的开发前期,还没有系统使用过mave ...

  2. 广义线性模型 - Andrew Ng机器学习公开课笔记1.6

    在分类问题中我们如果: 他们都是广义线性模型中的一个样例,在理解广义线性模型之前须要先理解指数分布族. 指数分布族(The Exponential Family) 假设一个分布能够用例如以下公式表达, ...

  3. bash的使用技巧

  4. 2015 Multi-University Training Contest 3 1006 Beautiful Set

    Beautiful Set Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5321 Mean: 给出一个集合,有两种计算集合的值的 ...

  5. UML概述

    UML (Unified Modeling Language)统一建模语言,是描述.构造和文档化系统制品的可视化语言,是一种图形表示法. UML用途:UML是一种工具,主要用在我们对软件用面向对象的方 ...

  6. (转)android从应用到驱动之—camera(1)---程序调用流程

    一.开篇 写博客还得写开篇介绍,可惜,这个不是我所擅长的.就按我自己的想法写吧. 话说camera模块,从上层到底层一共包含着这么几个部分: 1.apk------java语言 2.camera的ja ...

  7. HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(二)

    上一篇仅仅讲到前台操作,这篇专门涉及到Java后台处理.前台通过Ajax提交将Base64编码过的图片数据信息传到Java后台,然后Java这边进行接收处理.通过对图片数据信息进行Base64解码,之 ...

  8. ps -ef|grep htpd|wd -l

    在Linux下查看Apache的 负载情况,以前也说过,最简单有有效的方式就 是查看Apache Server Status(如何开启Apache Server Status点这里),在没有开启Apa ...

  9. 怎么用ChemDraw连接两个结构片段

    作为最新版的ChemOffice 15.1的核心组件,ChemDraw几乎能解决所有平面化学结构中的绘制问题.如果用户想连接两个分开的结构片段,ChemDraw提供两种连接两个化学结构片段的方法,分别 ...

  10. HttpClient使用学习

    import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apac ...