Twitter Storm是如何保证数据不丢失的?

Twitter Storm一个很好的功能就是保证数据不丢失,下面就看一下它是如何保证的呢。

Tuple tree

A Storm topology has a set of special "acker" tasks that track the tree of tuples for every spout tuple. When an acker sees that a tree is complete, it sends a message to the spout task that created the spout tuple to ack the message. You can set the number of acker tasks for a topology in the topology configuration using Config.TOPOLOGY_ACKERS. Storm defaults TOPOLOGY_ACKERS to one task -- you will need to increase this number for topologies processing large amounts of messages.

(acker可以看成storm的守护进程,它们负责追踪spout tuple tree,当某个tuple tree完成/超时时,该acker负责调用spout的ack/fail方法)

The best way to understand Storm's reliability implementation is to look at the lifecycle of tuples and tuple trees. When a tuple is created in a topology, whether in a spout or a bolt, it is given a random 64 bit id. These ids are used by ackers to track the tuple tree for every spout tuple.

(不管tuple是spout创建的还是bolt创建的,都会随机分配一个64位的id)

Every tuple knows the ids of all the spout tuples for which it exists in their tuple trees. When you emit a new tuple in a bolt, the spout tuple ids from the tuple's anchors are copied into the new tuple. When a tuple is acked, it sends a message to the appropriate acker tasks with information about how the tuple tree changed. In particular it tells the acker "I am now completed within the tree for this spout tuple, and here are the new tuples in the tree that were anchored to me".

(每个tuple除了自己的id以外,还会保存其spout tuple ids)

when a tuple is acked in the topology, how does it know to which acker task to send that information?

Storm uses consistent hashing to map a spout tuple id to an acker task. Since every tuple carries with it the spout tuple ids of all the trees they exist within, they know which acker tasks to communicate with.

(tuple与acker的对应关系是通过consistent hashing map的)

Another detail of Storm is how the acker tasks track which spout tasks are responsible for each spout tuple they're tracking. When a spout task emits a new tuple, it simply sends a message to the appropriate acker telling it that its task id is responsible for that spout tuple. Then when an acker sees a tree has been completed, it knows to which task id to send the completion message.
(acker又是如何通知spout task的呢? 当spout task emit一个tuple的时候会将自己的task id和spout tuple告诉acker)

Acker tasks do not track the tree of tuples explicitly. For large tuple trees with tens of thousands of nodes (or more), tracking all the tuple trees could overwhelm the memory used by the ackers. Instead, the ackers take a different strategy that only requires a fixed amount of space per spout tuple (about 20 bytes). This tracking algorithm is the key to how Storm works and is one of its major breakthroughs.
(Acker并不傻,它使用的策略并不是在内存中维护每个spout tuple对应的tuple tree节点,而是针对每个spout tuple使用了一个固定大小的空间 - 20bytes 来存储一个pair信息)

An acker task stores a map from a spout tuple id to a pair of values. The first value is the task id that created the spout tuple which is used later on to send completion messages. The second value is a 64 bit number called the "ack val". The ack val is a representation of the state of the entire tuple tree, no matter how big or how small. It is simply the xor of all tuple ids that have been created and/or acked in the tree.
(上文提到的pair就是task id 和 64 bit number - "ack val")

When an acker task sees that an "ack val" has become 0, then it knows that the tuple tree is completed. Since tuple ids are random 64 bit numbers, the chances of an "ack val" accidentally becoming 0 is extremely small. If you work the math, at 10K acks per second, it will take 50,000,000 years until a mistake is made. And even then, it will only cause data loss if that tuple happens to fail in the topology.
(acker根据"ack val"是否为0来判断一个spout tuple对应的tuple tree是否完成,并且使用该方法丢失数据的概率非常低)

Now that you understand the reliability algorithm, let's go over all the failure cases and see how in each case Storm avoids data loss:

A tuple isn't acked because the task died: In this case the spout tuple ids at the root of the trees for the failed tuple will time out and be replayed.
Acker task dies: In this case all the spout tuples the acker was tracking will time out and be replayed.
Spout task dies: In this case the source that the spout talks to is responsible for replaying the messages. For example, queues like Kestrel and RabbitMQ will place all pending messages back on the queue when a client disconnects.
(既然已经介绍了保证数据可靠性的算法,那就看一下哪些情况下一个spout tuple对应的task没有收到ack: 1. bolt task dies, 2. acker task dies 3. spout task dies; 其中对于1(tuple tree 很高),如果bolt task上处理的是某个tuple tree的叶子节点,难道整个tuple tree还要重新走一遍,即使前面的环节已经成功了,如果能够在failed bolt的前一个bolt/spout继续就好了)

原文地址: https://github.com/nathanmarz/storm/wiki/Guaranteeing-message-processing
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值