Storm-源码分析-LocalState (backtype.storm.utils)
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)的更多相关文章
- Storm源码分析--Nimbus-data
nimbus-datastorm-core/backtype/storm/nimbus.clj (defn nimbus-data [conf inimbus] (let [forced-schedu ...
- JStorm与Storm源码分析(四)--均衡调度器,EvenScheduler
EvenScheduler同DefaultScheduler一样,同样实现了IScheduler接口, 由下面代码可以看出: (ns backtype.storm.scheduler.EvenSche ...
- JStorm与Storm源码分析(三)--Scheduler,调度器
Scheduler作为Storm的调度器,负责为Topology分配可用资源. Storm提供了IScheduler接口,用户可以通过实现该接口来自定义Scheduler. 其定义如下: public ...
- JStorm与Storm源码分析(二)--任务分配,assignment
mk-assignments主要功能就是产生Executor与节点+端口的对应关系,将Executor分配到某个节点的某个端口上,以及进行相应的调度处理.代码注释如下: ;;参数nimbus为nimb ...
- storm源码分析之任务分配--task assignment
在"storm源码分析之topology提交过程"一文最后,submitTopologyWithOpts函数调用了mk-assignments函数.该函数的主要功能就是进行topo ...
- JStorm与Storm源码分析(一)--nimbus-data
Nimbus里定义了一些共享数据结构,比如nimbus-data. nimbus-data结构里定义了很多公用的数据,请看下面代码: (defn nimbus-data [conf inimbus] ...
- Nimbus<三>Storm源码分析--Nimbus启动过程
Nimbus server, 首先从启动命令开始, 同样是使用storm命令"storm nimbus”来启动看下源码, 此处和上面client不同, jvmtype="-serv ...
- storm源码分析之topology提交过程
storm集群上运行的是一个个topology,一个topology是spouts和bolts组成的图.当我们开发完topology程序后将其打成jar包,然后在shell中执行storm jar x ...
- JStorm与Storm源码分析(五)--SpoutOutputCollector与代理模式
本文主要是解析SpoutOutputCollector源码,顺便分析该类中所涉及的设计模式–代理模式. 首先介绍一下Spout输出收集器接口–ISpoutOutputCollector,该接口主要声明 ...
随机推荐
- php7性能、兼容性和稳定性探讨
前几天看到php7发布了beta1版本,想了解一下php7到底折腾了些啥东西出来.这一了解发现不得了了,改变还挺多的.最最重要的方面就是性能提升了不少,这边有一个pdf文件是惠新宸(鸟哥,php核心开 ...
- 每日英语:The Perils Of Giving Advice
I know what you should do and here's my advice. How many times have you heard that (and groaned)? gr ...
- Java Mail(三):Session、Message详解
http://blog.csdn.net/ghsau/article/details/17909093 ************************************* 本文来自:高爽|Co ...
- 华中农业大学校赛 I Catching Dogs
Catching Dogs Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 1140 Solved: 298[Submit][Status][Web B ...
- Hadoop中MapReduce计算框架以及HDFS可以干点啥
我准备学习用hadoop来实现下面的过程: 词频统计 存储海量的视频数据 倒排索引 数据去重 数据排序 聚类分析 ============= 先写这么多
- Linux安装MediaWiki
1. 编译安装libxml2 # wget http://xmlsoft.org/sources/libxml2-2.6.32.tar.gz # tar zxvf libxml2-2.6.32. ...
- keepalived管理LVS文件详解
#全局设置,只设置一个 全局路由就可以,全局路由不能重复唯一标识. global_defs { router_id LVS_01 #全局路由ID,唯一不能重复 } #实例 vrrp_instance ...
- 处理器拦截器(HandlerInterceptor)详解
处理器拦截器(HandlerInterceptor)详解 编程界的小学生 关注 2017.04.06 15:19* 字数 881 阅读 657评论 0喜欢 4 简介SpringWebMVC的处理器拦截 ...
- selenium使用中遇到的问题
1.Exception in thread "main" org.openqa.selenium.WebDriverException: Cannot find firefox b ...
- pycharm Tab键设置成4个空格
file--->setting,选择Editor--->python,如下图所示: