实现精确一次消费
- kafka的偏移量管理:0.9版本之前是保存再zookeeper中的,0.9版本之后是保存在kafka的
__consumer_offsets
主题中
自动提交偏移量
enable.auto.commit=true
auto.commit.interval.ms= 5000
默认提交的时间间隔是5000ms
每间隔5s消费者会自动从poll方法获得的最大的偏移量提交到主题中,再均衡之后可能出现重复消费和丢失数据的可能,
重复消费:
数据丢失:提交偏移量的周期要小于,消费者处理的时长,会出现数据的丢失
立即提交偏移量
- 同步提交:使用失败尝试机制,如果提交不成功会一直阻塞进程
enable.auto.commit=false
使用commitSync()
提交由poll方法返回的最新的偏移量,如果成功提交马上返回结果,提交失败就会跑出异常
- 异步提交:没有事变尝试机制,所有没有同步的来的可靠
enable.auto.commit=false
使用commitASync()
提交由poll方法返回的最新的偏移量,频繁提交在broker响应之前,应用程序会一直阻塞,降低了吞吐量,单一但发生再均衡的情况,会增加重复的数量
一步提交还有回调的功能
实现手动提交偏移量+幂等性操作
很难确定自动提交偏移量的时机、同步提交和异步提交会出现吞吐量的问题
-
解决方案一:使用事务特性,使用关系型数据库将提交偏移量,和数据的消费写到同一个事务之中,保证事务的原子性操作;但是无法使用nosql的强大的存储功能
-
解决方案二:手动提交偏移量+幂等性操作
- 数据丢失问题,办法就是要等数据保存成功后再提交偏移量,手动提交偏移量保证数据不丢失
Cannal/maxwell进行实时采集业务数据库
抓取业务表的新增变化,用于制作实时统计;
原理:将自己伪装为slave,假装成从master中复制数据
流程:
- Mater改变记录,写进二进制日志;
- Slave从库想master发送dump协议,拷贝binlog日志到他的中继日志(relay)
- Slave将中继日志中的时间重做,将改变的数据同步到自己的数据库
将kafka中的数据读取处理进行分流写到kafka中。
将用户是否消费的状态保存到Hbase中;
首单分析
- 漏洞
如果一个用户是首次消费,在一个采集周期中,这个用户下单了 2 次,那么就会
把这同一个用户都会统计为首单消费 - 解决办法
- 应该将同一采集周期的同一用户的最早的订单标记为首单,其它都改为非首单
- 同一采集周期的同一用户-----按用户分组(groupByKey) ü 最早的订单-----排序,取最早(sortwith)
实现双流join和维度关联
订单事实表与订单明细事实表
- 准备订单明细数据
订单明细写入 Kafka(DWD 层)
订单写入 Kafka(DWD 层)
在 DWS 中创建 OrderWideApp 接收数据
-
双流合并的问题:
由于订单流和订单明细流,两个流的数据是独立保存,独立消费,很有可能同一业务的
数据,分布在不同的批次。因为join算子只join同一批次的数据。如果只用简单的join流 方式,会丢失掉不同批次的数据。
解决方案:
- 使用缓存的方式解决
对两个流做满外连接,会形成Some,none、(none、some)、(some,some)
将key保存到Redis中,实现
- 使用滑动窗口==+==去重的方式解决
SparkStreaming的滑动窗口函数