Message Delivery Semantics

  • At most once —— Messages may be lost but are never redelivered(消息可能丢失但不会重复投递)
  • At least once —— Messages are never lost but may be redelivered(消息不会丢失但可能重复投递)
  • Exactly once —— this is what people actually want, each message is delivered once and only once(消息只投递一次)

许多系统都声称提供"exactly once"投递,但是仔细阅读很重要,大部分这种宣称都是误导(他们没有考虑生产者和消费者可能失败的情况,以及多个消费者进程同时处理的情况,还有写到磁盘上的数据可能丢失的情况)。

Kafka的消息投递语义是直接的。发布消息的时候我们有一个概念叫消息被提交到日志。一旦被发布的消息被提交到日志,只要有一个这个消息所在分区的broker活着消息就不会丢失。从0.11.0.0版本以后,Kafka生产者支持幂等投递选项,以保证即使消息被重新发送,日志中也不会有重复的条目。为了实现这一点,broker给没用个生成者指定一个ID并且每条消息指定一个序列号。

并不是所有的情况都需要这样强的保证。

现在,让我们站在消费者的角度来看这个语义。消费者用日志控制它的位置。如果消费者没有崩溃它仅仅只是在内存中存储这个位置,但如果消费者失败了,我们想要另一个进程来接管这个分区,那么这个新的进程需要选择一个合适的位置开始处理。让我们来看一下消费者读取消息后处理消息和更新位置的几种选项。

  1. It can read the messages, then save its position in the log, and finally process the messages.(读取消息,然后在日志中保存位置,最后处理消息)。这种情况有一种可能就是消费者在保存位置之后就崩溃了。这情况下接管的进程会从保存的那个位置开始处理,即使在这个位置之前有一些消息没有被处理也不管了。这与"at-most-once"的语义是一致的,在这种情况下,消费者处理失败的那些消息就不会被处理了。
  2. It can read the messages, process the messages, and finally save its position.(读取消息,然后处理消息,最后保存位置)。这种情况下有一种可能是消费者在处理消息之后保存位置之前就崩溃了。这种情况下,新的进程接管以后会接收到一些之前已经被处理过的消息。这与"at-least-once"的语义是一致的。在许多情况下,消息有一个主键,以至于更新是幂等的(接收相同的消息两次,重写日志记录)。

The consumer's position is stored as a message in a topic, so we can write the offset to Kafka in the same transaction as the output topics receiving the processed data. If the transaction is aborted, the consumer's position will revert to its old value and the produced data on the output topics will not be visible to other consumers, depending on their "isolation level." In the default "read_uncommitted" isolation level, all messages are visible to consumers even if they were part of an aborted transaction, but in "read_committed," the consumer will only return messages from transactions which were committed (and any messages which were not part of a transaction).

当从主题消费并生产到另一个主题的时候,我们可以用事务生产者。消费者的位置作为消息被存储在topic中,以至于我们可以在接收处理数据的那个事务中将offset写到kafka。如果事务被中止,消费者的位置会恢复成旧值并且生产的数据对其它消费者不可见,这取决于隔离级别。默认的隔离级别是"read_uncommitted"表示消息对所有消费者可见,即使有些消息来自被中止的事务。

总结

1、消息投递语义

  最多一次:可能丢失消息但不会重复投递

  最少一次:不会丢失消息但可能重复投递

  精确一次:只会投递一次

2、kafka给每个生产者指定一个ID,每个发布的消息一个序列号,这样的话即使生产者重复发送消息,在提交日志中也不会有重复记录

3、站在消费者的角度,先保存位置后处理消息就是“最多一次”;先处理消息后保存位置就是“最少一次”;至于“精确一次”,可以使用事务生产者来实现,即在同一个事务中接收并处理消息,将位置(offset)保存到另一个topic中。只要事务成功了,皆大欢喜,若事务失败,则位置恢复。

参考 http://kafka.apache.org/documentation/#design

Kakfa消息投递语义的更多相关文章

  1. Exactly-Once 投递语义

    小结: 1.Exactly-Once 是指发送到消息系统的消息只能被消费端处理且仅处理一次,即使生产端重试消息发送导致某消息重复投递,该消息也在消费端也只被消费一次. 消息队列 RocketMQ &g ...

  2. 【转】Windows消息投递流程:WM_COMMAND消息流程

    原文网址:http://blog.csdn.net/hyhnoproblem/article/details/6182585 该示例通过研究基本的单文档程序的“文件”--“打开”命令,分析WM_COM ...

  3. Rabbitmq可靠消息投递,消息确认机制

    前言 我们知道,消息从发送到签收的整个过程是 Producer-->Broker/Exchange-->Broker/Queue-->Consumer,因此如果只是要保证消息的可靠投 ...

  4. Windows各种各种消息投递函数

    1.SendMessage:发送消息给指定的窗口过程:直到窗口过程处理了消息才返回. 2.PostMessage:将消息放入消息队列(与指定窗口创建的线程相关)中:无需等待消息处理,立即返回.   不 ...

  5. skynet1.0阅读笔记2_skynet的消息投递skynet.call

    为了了解 skynet.call 的调用过程,需要先看看 skynet的队列是如何把包分到不同工作线程的.看下图 查看 global_queue 的skynet_globalmq_push和skyne ...

  6. 【转】Windows消息投递流程:一般窗口消息投递(WM_LBUTTONCLICK)

    原文网址:http://blog.csdn.net/hyhnoproblem/article/details/6182646 本例通过在单文档程序的视图中添加WM_LBUTTONCLICK消息处理函数 ...

  7. rocketmq批量消息投递

    批量发送消息可提高传递小消息的性能.同时也需要满足以下特征 批量消息要求必要具有同一topic.相同消息配置 不支持延时消息 建议一个批量消息最好不要超过1MB大小 示例 小于1MB String t ...

  8. 【kafka学习之六】kakfa消息生产、消费示例

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 kafka_2.11-0.11.0.0 zookeepe ...

  9. ActiveMq C# 消息特性:延迟和定时消息投递

    ActiveMQ from version 5.4 has an optional persistent scheduler built into the ActiveMQ message broke ...

随机推荐

  1. C++STL中set的使用策略(详解)

    set的英文意思是“集合”, 集合都不陌生吧,集合的特点有唯一性,即:每一个元素只有一个,所以set可以用来“去重”操作,set还有默认的排序. 1.头文件——<set> 2.定义——se ...

  2. POJ 1321 棋盘问题(DFS板子题,简单搜索练习)

    棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44012   Accepted: 21375 Descriptio ...

  3. 解决 重启nginx: [alert] kill(189, 1) failed (3: No such process)

    解决 nginx: [alert] kill(189, 1) failed (3: No such process) [root@localhost/]# nginx -s reloadnginx: ...

  4. 关于vue的使用计算属性VS使用计算方法的问题

    在vue中需要做一些计算时使用计算属性和调用methods方法都可以达到相同的效果,那么这两种使用方式的区别在哪里: <div id="example"> <p& ...

  5. POJ 3041 Asteroids(模板——二分最大匹配(BFS增广))

    题目链接: http://poj.org/problem?id=3041 Description Bessie wants to navigate her spaceship through a da ...

  6. Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config解决

    出现这个问题往往伴随  HTTP-500错误 报错信息: HTTP Status - Handler processing failed; nested exception is java.lang. ...

  7. Oracle_SQL92_连接查询

    Oracle_SQL92_连接查询   笛卡儿积 --笛卡尔积 select * from emp;----14 select * from dept;----4 select * from emp, ...

  8. Linq 实例

    1.分页 ).Take(); 2.分组 1)一般分组 //根据顾客的国家分组,查询顾客数大于5的国家名和顾客数var 一般分组 = from c in ctx.Customers group c by ...

  9. win7彻底卸载iis

    https://jingyan.baidu.com/article/e5c39bf5829e8e39d660336c.html 昨天在电脑上搭建了PHP开发环境之后,重启apache服务器老是报错,检 ...

  10. 从数据库、代码和服务器对PHP网站Mysql做性能优化

    数据库优化是PHP面试几乎都会被问到的事情,也是我们工作中应该注意的事情,当然,如果是小网站无所谓优化不优化,网站访问量大了自然会暴漏数据库的瓶颈,这个瓶颈是各方面问题综合导致的,下面我们来做下数据库 ...