getting start with storm 翻译 第六章 part-3
来源:互联网 发布:什么微单最好 一款知 编辑:程序博客网 时间:2024/06/06 13:57
转载请注明出处:http://blog.csdn.net/lonelytrooper/article/details/9979019
ProductCategoriesCounterBolt
ProductCategoriesCounterBolt类负责记录所有的产品-分类关系。它接收由UsersHistoryBolt发射的产品-分类对并更新计数器。
每个产品-分类对的事件信息被存放在Redis服务器。出于性能的原因,使用一个本地的用于读的缓存和一个写缓存。事件信息被通过一个后台进程发送到Redis。
对于输入,该bolt也会发送一个包含了更新的计数器的元组来供topology中下一个bolt消费,NewsNotifierBolt,它用于广播消息到最终用户来用于实时更新。
public class ProductCategoriesCounterBoltextendsBaseRichBolt{
...
@Override
public voidexecute(Tuple input) {
String product =input.getString(0);
String categ =input.getString(1);
int total=count(product,categ);
collector.emit(newValues(product,categ,total));
}
...
private intcount(String product,String categ) {
int count=getProductCategoryCount(categ,product);
count ++;
storeProductCategoryCount(categ,product,count);
return count;
}
...
}
该bolt中的持久化被隐藏在getProductCategoryCount和storeProductCategoryCount方法中。我们进一步看下:
package storm.analytics;
...
public class ProductCategoriesCounterBoltextendsBaseRichBolt{
// ITEM:CATEGORY -> COUNT
HashMap<String,Integer>counter=newHashMap<String,Integer>();
// ITEM:CATEGORY -> COUNT
HashMap<String,Integer>pendingToSave=newHashMap<String,Integer>();
...
public intgetProductCategoryCount(Stringcateg,Stringproduct) {
Integer count =counter.get(buildLocalKey(categ,product));
if(count==null) {
String sCount =jedis.hget(buildRedisKey(product),categ);
if(sCount==null||"nil".equals(sCount)){
count =0;
} else{
count =Integer.valueOf(sCount);
}
}
return count;
}
...
private voidstoreProductCategoryCount(Stringcateg,Stringproduct,intcount) {
String key =buildLocalKey(categ,product);
counter.put(key,count);
synchronized(pendingToSave) {
pendingToSave.put(key,count);
}
}
...
}
getProductCategoryCount首先查询内存缓存计数器。如果查不到相应信息,它将从Redis服务器中获取它。
storeProductCategoryCount更新计数器缓存和pendingToSave缓冲区。该缓冲区被下边的后台进程持久化:
package storm.analytics;
public class ProductCategoriesCounterBoltextendsBaseRichBolt{
...
private voidstartDownloaderThread() {
TimerTask t =newTimerTask(){
@Override
public voidrun(){
HashMap<String,Integer>pendings;
synchronized(pendingToSave) {
pendings =pendingToSave;
pendingToSave =newHashMap<String,Integer>();
}
for (String key:pendings.keySet()) {
String[]keys=key.split(":");
String product =keys[0];
String categ =keys[1];
Integer count =pendings.get(key);
jedis.hset(buildRedisKey(product),categ,count.toString());
}
}
};
timer =newTimer("Item categories downloader");
timer.scheduleAtFixedRate(t,downloadTime,downloadTime);
}
...
}
下载线程锁定pendingToSave,当它发送旧的buffer到Redis的同时建立新的缓冲区来供其他线程使用。该代码块每隔downloadTime毫秒运行一次并且可以通过down-load topology配置参数来配置。download-time越长,执行Redis写的次数越少,因为连续的添加被一次写入。
再次牢记,正如在前边的bolt中一样,当分配资源到该bolt时,应用正确的域分组是非常重要的,在该例中根据产品分组。那是因为它按产品存储该信息的内存拷贝,并且如果一些缓存和buffer的拷贝存在,将出现不一致。
NewsNotifierBolt
NewsNotifierBolt负责通知web应用统计数据的变化,目的是为了使用户可以实时的看到变化。通知使用Apache HttpClient构建HTTP POST,发送到topology中配置的web服务器的URL地址。POST体被编码成JSON。
当测试的时候,该bolt被从topology中删除。
package storm.analytics;
...
public class NewsNotifierBoltextendsBaseRichBolt{
...
@Override
public voidexecute(Tuple input) {
String product =input.getString(0);
String categ =input.getString(1);
int visits=input.getInteger(2);
String content ="{ \"product\": \""+product+"\",\"categ\":\""+categ+"\",
\"visits\":"+visits+"}";
HttpPost post =newHttpPost(webserver);
try {
post.setEntity(newStringEntity(content));
HttpResponse response =client.execute(post);
org.apache.http.util.EntityUtils.consume(response.getEntity());
} catch(Exception e) {
e.printStackTrace();
reconnect();
}
}
...
}
- getting start with storm 翻译 第六章 part-3
- getting start with storm 翻译 第六章 part-1
- getting start with storm 翻译 第六章 part-2
- getting start with storm 翻译 第六章 part-4
- getting start with storm 翻译 第四章 part-3
- getting start with storm 翻译 第八章 part-3
- getting start with storm 翻译 第二章 part-1
- getting start with storm 翻译 第二章 part-2
- getting start with storm 翻译 第三章 part-1
- getting start with storm 翻译 第三章 part-2
- getting start with storm 翻译 第四章 part-1
- getting start with storm 翻译 第四章 part-2
- getting start with storm 翻译 第七章 part-1
- getting start with storm 翻译 第七章 part-2
- getting start with storm 翻译 第八章 part-1
- getting start with storm 翻译 第八章 part-2
- getting start with storm 翻译 第五章
- getting start with storm 翻译 第一章
- 华为心得
- phpcms中的$CATEGORY 数组
- SharedPreferences 的用法
- Cable master(hdu1551,二分查找)
- Gerrit 管理下git库分支导入
- getting start with storm 翻译 第六章 part-3
- ARC简介以及工程中ARC与非ARC的混合
- Design T-Shirt(hdu1031,简单排序)
- phpcms v9 如何获取当前栏目的名?
- netpoll浅析
- Android手机利用USB共享网络通过Ubuntu连接网络
- xss绕过过滤方法分享 及有关web攻击的方法
- HTTP协议简介
- GSL累计分布函数