漫游Kafka设计篇之消息传输的事务定义
之前讨论了consumer和producer是怎么工作的,现在来讨论一下数据传输方面。数据传输的事务定义通常有以下三种级别:
- 最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输。
- 最少一次: 消息不会被漏发送,最少被传输一次,但也有可能被重复传输.
- 精确的一次(Exactly once): 不会漏传输也不会重复传输,每个消息都传输被一次而且仅仅被传输一次,这是大家所期望的。
大多数消息系统声称可以做到“精确的一次”,但是仔细阅读它们的的文档可以看到里面存在误导,比如没有说明当consumer或producer失败时怎么样,或者当有多个consumer并行时怎么样,或写入硬盘的数据丢失时又会怎么样。kafka的做法要更先进一些。当发布消息时,Kafka有一个“committed”的概念,一旦消息被提交了,只要消息被写入的分区的所在的副本broker是活动的,数据就不会丢失。关于副本的活动的概念,下节文档会讨论。现在假设broker是不会down的。
如果producer发布消息时发生了网络错误,但又不确定实在提交之前发生的还是提交之后发生的,这种情况虽然不常见,但是必须考虑进去,现在Kafka版本还没有解决这个问题,将来的版本正在努力尝试解决。
并不是所有的情况都需要“精确的一次”这样高的级别,Kafka允许producer灵活的指定级别。比如producer可以指定必须等待消息被提交的通知,或者完全的异步发送消息而不等待任何通知,或者仅仅等待leader声明它拿到了消息(followers没有必要)。
现在从consumer的方面考虑这个问题,所有的副本都有相同的日志文件和相同的offset,consumer维护自己消费的消息的offset,如果consumer不会崩溃当然可以在内存中保存这个值,当然谁也不能保证这点。如果consumer崩溃了,会有另外一个consumer接着消费消息,它需要从一个合适的offset继续处理。这种情况下可以有以下选择:
- consumer可以先读取消息,然后将offset写入日志文件中,然后再处理消息。这存在一种可能就是在存储offset后还没处理消息就crash了,新的consumer继续从这个offset处理,那么就会有些消息永远不会被处理,这就是上面说的“最多一次”。
- consumer可以先读取消息,处理消息,最后记录offset,当然如果在记录offset之前就crash了,新的consumer会重复的消费一些消息,这就是上面说的“最少一次”。
- “精确一次”可以通过将提交分为两个阶段来解决:保存了offset后提交一次,消息处理成功之后再提交一次。但是还有个更简单的做法:将消息的offset和消息被处理后的结果保存在一起。比如用Hadoop ETL处理消息时,将处理后的结果和offset同时保存在HDFS中,这样就能保证消息和offser同时被处理了。
漫游Kafka设计篇之消息传输的事务定义的更多相关文章
- 漫游Kafka设计篇之消息传输的事务定义(5)
之前讨论了consumer和producer是怎么工作的,现在来讨论一下数据传输方面.数据传输的事务定义通常有以下三种级别: 最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输. 最 ...
- 漫游Kafka设计篇之数据持久化
Kafka大量依赖文件系统去存储和缓存消息.对于硬盘有个传统的观念是硬盘总是很慢,这使很多人怀疑基于文件系统的架构能否提供优异的性能.实际上硬盘的快慢完全取决于使用它的方式.设计良好的硬盘架构可以和内 ...
- 漫游Kafka设计篇之Producer和Consumer
Kafka Producer 消息发送 producer直接将数据发送到broker的leader(主节点),不需要在多个节点进行分发.为了帮助producer做到这点,所有的Kafka节点都可以及时 ...
- 漫游Kafka设计篇之性能优化
Kafka在提高效率方面做了很大努力.Kafka的一个主要使用场景是处理网站活动日志,吞吐量是非常大的,每个页面都会产生好多次写操作.读方面,假设每个消息只被消费一次,读的量的也是很大的,Kafka也 ...
- 漫游Kafka设计篇之Producer和Consumer(4)
Kafka Producer 消息发送 producer直接将数据发送到broker的leader(主节点),不需要在多个节点进行分发.为了帮助producer做到这点,所有的Kafka节点都可以及时 ...
- 漫游Kafka设计篇之性能优化(7)
Kafka在提高效率方面做了很大努力.Kafka的一个主要使用场景是处理网站活动日志,吞吐量是非常大的,每个页面都会产生好多次写操作.读方面,假设每个消息只被消费一次,读的量的也是很大的,Kafka也 ...
- 漫游Kafka实现篇之消息和日志
消息格式 消息由一个固定长度的头部和可变长度的字节数组组成.头部包含了一个版本号和CRC32校验码. /** * 具有N个字节的消息的格式如下 * * 如果版本号是0 * * 1. 1个字节的 &qu ...
- 漫游Kafka设计篇之主从同步
Kafka允许topic的分区拥有若干副本,这个数量是可以配置的,你可以为每个topci配置副本的数量.Kafka会自动在每个个副本上备份数据,所以当一个节点down掉时数据依然是可用的. Kafka ...
- 漫游Kafka实战篇之客户端API
Kafka Producer APIs 旧版的Procuder API有两种:kafka.producer.SyncProducer和kafka.producer.async.AsyncProduce ...
随机推荐
- Unity3D之Assetbundle
原地址: Unity3D之Assetbundle 有几个地方需要注意下 1.如何解决资源重复加载的问题 2.初始化了就直接出现在场景中了 感觉怪怪的 3.标红的地方要注意下 prefab上挂载的脚 ...
- JAVA非空条件三元运算符
//非空情况处理: // Integer holidayPrice = order.get("holidayPrice")!=null?Integer.valueOf(String ...
- 斌哥的 Docker 进阶指南—监控方案的实现
过去的一年中,关于 Docker 的话题从未断过,而如今,从尝试 Docker 到最终决定使用 Docker 的转化率依然在逐步升高,关于 Docker 的讨论更是有增无减.另一方面,大家的注意力也渐 ...
- login shell 和 non-login shell 的区别
介绍之前先思考一个问题:有时我们通过su命令切换用户后,却发现并没有进入该用户的shell环境.这是为什么? login shell:取得bash时需要完整的登录流程.就是说通过输入账号和密码登录系统 ...
- Javascript 正则表达式_5
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- 用C#读取,写入ini文件
[DllImport("kernel32.dll")] private static extern bool WritePrivateProfileString(string se ...
- oracle创建表空间,创建用户(转)
//创建临时表空间 create temporary tablespace test_temp tempfile 'E:\oracle\product\10.2.0\oradata\testserve ...
- LINUX进程控制
1. 引言 一个程序是存储在文件中的机器指令序列.一般它是由编译器将源代码编译成二进制格式的代码.运行一个程序意味着将这个机器指令序列载入内存然后让处理器(cpu)逐条执行这些指令. 在Unix术语中 ...
- linux下关于gz和bz2压缩格式的常用操作技巧
.gz和.bz2都是linux下压缩文件的格式,有点类似windows下的.zip和.rar文件..bz2和.gz的区别在于,前者比后者压缩率更高,后者比前者花费更少的时间. 也就是说同一个文件,压缩 ...
- lintcode:买卖股票的最佳时机 IV
买卖股票的最佳时机 IV 假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格. 设计一个算法来找到最大的利润.你最多可以完成 k 笔交易. 注意事项 你不可以同时参与多笔交易(你必须在再次 ...