storm中DAU实时计算方案
所就职的公司是一家互联网视频公司,存在大量的实时计算需求,计算uv,pv等一些经典的实时指标统计。由于要统计当天的实时
UV,当天的uv由于要存储当天的所有的key,面临本地内存不够用的问题,异常重启后会丢失本地缓存,造成计算结果不准确的问题。;如果使用外部缓存比如redis,memcache等,在高并发时会出现效率问题。
在不断的实践中,不断改进方案,积累了如下经验:
1.使用bitMap可以节约内存。
使用redis的bitMap,并发时候会有问题。
a .只使用本地内存
由于reidis在数据量较大时,并发会达到瓶颈,干脆绕过redis,全部使用基于本地内存的bitMap方案。这样即省内存,又避免了redis的并发达不到性能要求的问题。
b.使用备份来解决DAU异常恢复问题。
实时任务异常时,由于历史缓存丢失,造成数据不准确问题。
定时或者定量将本地缓存的b的redis持久化的一个redis,hdfs,kafka中,这些数据只起到副本备份的作用。
当worker异常重启时,先从备份中恢复历史的历史的redis中的DAU的数据。然后再开始实时计算。
c.如何备份?备份哪些数据?
解决思路:
使用redis,hdfs等来存储备份数据,
bitMap的数据序列化,保存到文件,然后上传到hdfs上,或者redis上面。
dauBolt,接收到消息时,在execute方法中先后台恢复本地缓存,恢复成功后,再进行后续的业务处理。
使用kafka来备份当天的uuidSet :需要备份当天的所有的uuid
副本的备份每5分钟备份一次:使用kafka作为副本备份,可以 每1分钟或者每积累2W条UUID,就将这些UUID封装成一个msg,发送到kafka的一个topic主题队列uuidSetTopic里面,谁先到达执行条件就先执行那个? msg中要包含备份时候的时间戳发送时候的当前时间。
DauBolt:用来恢复当天到目前为止的uuidSet;dau相关的指标统计等;DauBolt会接收到uuidSetTopic的数据,还有userActionTopic的数据。
处理逻辑:
1.DauBolt的计算逻辑:
如果接收到的是uuidSetTopic的数据:
取出数据中的时间戳,
判断是否是当天的备份数据,如果不是,就不处理,丢弃掉。
判断是否本地缓存已经恢复,如果恢复,就不处理,同时通知dauSet_Spout不再读取uuidSetTopic的数据了。
如果没恢复, 就解析uuidSet,并逐个恢复到bitMap中。
判断恢复完成的逻辑:
取uuidSetTopic的数据中的时间戳dt。
dt 和当前时间的差小于1.5分钟,(uuidSetTopic 最迟是一分钟一条。1.5分钟可以保证这个时间段内只有一个因为凑不够2w条的强制发送的)并且msg的uuid个数小于2w,则说明恢复进入尾声了,基本上追上了当前时间。
连续两次差小于1.5分钟,uuid个数小于2w,也说明追上了最新的值;
dt 和当前时间的差 小于1.5 分钟(90s), 假设当前时间差是50s,msg的uuid个数等于2w,说明目前数据较多,不到一分钟就生产了2w条数据;接着往下取数据,将时间差的阀值缩小当前的差值50s;继续该逻辑,直到时间差大于设置的值,说明追上了最新的数据,本地缓存恢复成功。
如果当前时间和bolt的启动时间的间隔差超过15分钟(也就是允许有15分钟来恢复dau的计算的本地缓存),也认为恢复完成(不能无限期的等待它恢复啊,但是要在日志中打印出来这种情况)。
2.如果接收到的是userAction的数据:
取出数据中的uuid
当前的本地缓存是否已经恢复: 如果恢复,取出uuid,判断是否在本地的bitMap中,如果不在,更新DAU的值。
如果没有恢复,不进行uuid是否在bitMap的判断。
将uuid 发送到uuidSetSave_bolt.
恢复线程需要根据时间来判断是否恢复成功了。
当storm 任务启动前,先向dauBakTopic发送一条消息,UUID为空set,时间戳为当前时间。
storm中DAU实时计算方案的更多相关文章
- Storm大数据实时计算
大数据也是构建各类系统的时候一种全新的思维,以及架构理念,比如Storm,Hive,Spark,ZooKeeper,HBase,Elasticsearch,等等 storm,在做热数据这块,如果要做复 ...
- TOP100summit:【分享实录】Twitter 新一代实时计算平台Heron
本篇文章内容来自2016年TOP100summit Twitter technical lead for Heron Maosong Fu 的案例分享. 编辑:Cynthia Maosong Fu:T ...
- Hadoop平台提供离线数据和Storm平台提供实时数据流
1.准备工作 2.一个Storm集群的基本组件 3.Topologies 4.Stream 5.数据模型(Data Model) 6.一个简单的Topology 7.流分组策略(Stream grou ...
- 《storm实战-构建大数据实时计算读书笔记》
自己的思考: 1.接收任务到任务的分发和协调 nimbus.supervisor.zookeeper 2.高容错性 各个组件都是无状态的,状态 ...
- storm入门(二):关于storm中某一段时间内topN的计算入门
刚刚接触storm 对于滑动窗口的topN复杂模型有一些不理解,通过阅读其他的博客发现有两篇关于topN的非滑动窗口的介绍.然后转载过来. 下面是第一种: Storm的另一种常见模式是对流式数据进行所 ...
- Storm 实战:构建大数据实时计算
Storm 实战:构建大数据实时计算(阿里巴巴集团技术丛书,大数据丛书.大型互联网公司大数据实时处理干货分享!来自淘宝一线技术团队的丰富实践,快速掌握Storm技术精髓!) 阿里巴巴集团数据平台事业部 ...
- 实时计算storm流程架构总结
hadoop一般用在离线的分析计算中,而storm区别于hadoop,用在实时的流式计算中,被广泛用来进行实时日志处理.实时统计.实时风控等场景,当然也可以用在对数据进行实时初步的加工,存储到分布式数 ...
- Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV
Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV – lxw的大数据田地 http://lxw1234.com/archives/2015/09/516.htm Java使用极小 ...
- [转]基于Storm的实时数据处理方案
1 文档说明 该文档描述的是以storm为主体的实时处理架构,该架构包括了数据收集部分,实时处理部分,及数据落地部分. 关于不同部分的技术选型与业务需求及个人对相关技术的熟悉度有关,会一一进行分析. ...
随机推荐
- tftp 限制ip 限制ip段 或者多个ip段访问
1 限制单个ip访问 tftp 配置tftp信息 vi /etc/xinetd.d/tftp 在 service tftp配置信息中添加 only_form =ip 重启 service xinet ...
- C语言数据类型取值范围
一.获取数据类型在系统中的位数 在不同的系统中,数据类型的字节数(bytes)不同,位数(bits)也有所不同,那么对应的取值范围也就有了很大的不同,那我们怎么知道你当前的系统中C语言的某个数据类型的 ...
- TP框架主要文件夹注释
TP框架主要文件夹注释 common -> 函数库目录 conf -> 配置文件目录lang -> 语言包librang -> 核心资源库 behacior -> 行为目 ...
- cms 常用标签
{template "content","header"} 调用根目录下phpcms\template\content\header文件 {CHARSET} 字 ...
- ElasticSearch
ElaticSearch简介: ES是一个搜索引擎,基于当前最先进,最高效的全功能开源搜索引擎框架lucene ES还有许多功能: 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索 近实时 ...
- C++笔记(一)
一.动态数组 一般我们定义数组都是用下面的方式: int str[100]; 但对于一些需要手动输入数组大小的情况,这种定义方式就行不通了.因为上面这种方式要求事先知道数组大小,并且给数组中括号中必须 ...
- hashCode的作用
在一般的应用中你不需要了解hashCode的用法,但当你用到HashMap,HashSet等集合类时要注意下hashCode. 你想通过一个object的key来拿HashMap的value, ...
- oracle的IMU和ora-01555
IMU: 01555: 按照上图找啊找,已经提交事物的undo块找不到了,就产生01555错误,解决这样问题:1. 确保undo表空间数据的保留时间至少大于最长sql语句的时间 2. 增大undo表空 ...
- [Silverlight]监听指定控件(FrameworkElement)的依赖属性(DependencyProperty)的更改
前言 转载请注明出处:http://www.cnblogs.com/ainijiutian 最近在silverlight项目使用Telerik的控件,遇到一个问题.就是使用RadBusyIndicat ...
- Android 监听返回键、HOME键
拦截返回键,HOME键,继承BaseActivity即可 import android.app.Activity; import android.content.BroadcastReceiver; ...