理解检查指向eventhub

时间:2016-02-17 17:56:06

标签: c# azureservicebus azure-eventhub

我想确保,如果我的eventhub客户端崩溃(当前是一个控制台应用程序),它只会获取尚未从eventhub获取的事件。实现这一目标的一种方法是利用抵消。但是,这(根据我的理解)要求客户端存储最新的偏移量(除了事件似乎不一定会触及SequenceNumber排序的ProcessEventsAsync方法的foreach循环)。

另一种方法是使用检查点。我认为它们是使用提供的存储帐户凭据通过服务器(eventhub)保留的。这是对的吗?

这是我目前使用的一些初步代码:

public class SimpleEventProcessor : IEventProcessor
{
    private Stopwatch _checkpointStopWatch;

    async Task IEventProcessor.CloseAsync(PartitionContext context, CloseReason reason)
    {
        Console.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason);
        if (reason == CloseReason.Shutdown)
        {
            await context.CheckpointAsync();
        }
    }

    Task IEventProcessor.OpenAsync(PartitionContext context)
    {
        Console.WriteLine("SimpleEventProcessor initialized.  Partition: '{0}', Offset: '{1}'", context.Lease.PartitionId, context.Lease.Offset);
        _checkpointStopWatch = new Stopwatch();
        _checkpointStopWatch.Start();
        return Task.FromResult<object>(null);
    }

    async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
    {
        foreach (var eventData in messages)
        {
            // do something                    
        }

        //Call checkpoint every 5 minutes, so that worker can resume processing from 5 minutes back if it restarts.
        if (_checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
        {
            await context.CheckpointAsync();
            _checkpointStopWatch.Restart();
        }
    }
}

我相信它每5分钟就会向服务器创建一个检查点。服务器如何知道哪个客户端已提交检查点(通过上下文)?此外,如果客户端重新启动,如何防止再次处理事件?此外,可能仍有一个长达5分钟的窗口,其中再次处理事件。也许我应该根据我的要求使用队列/主题?

PS:

这似乎已经足够了:

async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
{
    foreach (var eventData in messages)
    {
        // do something
    }
    await context.CheckpointAsync();
}

1 个答案:

答案 0 :(得分:21)

Lemme在回答之前提出了一些基本术语

EventHubs 是高吞吐量的持久事件提取管道。简单地说 - 它是一个可靠的事件流在云上。 事件数据上的

偏移(流中的一个事件)实际上是流上的光标。拥有此Cursor - 将启用类似的操作 - 重新开始从此游标(也称为偏移)读取 - 包含或排除。

EventProcessor library 是EventHubs团队构建的框架,在ServiceBus SDK的顶部,以制作&#34; eventhub接收器gu&#34; - 看起来更容易适用于Kafka的ZooKeeper&lt; - &gt;活动中心的EPH 。它将确保在特定分区上运行EventProcessor的进程死亡/崩溃时 - 在其他可用的EventProcessorHost实例中,它将从上一个检查点偏移 恢复。

CheckPoint :截至今天 - EventHubs仅支持客户端检查指向。当您从客户端代码调用Checkpoint时:

await context.CheckpointAsync();

- 它将转换为存储呼叫(直接来自客户端) - 这将在您提供的存储帐户中存储当前偏移量。 EventHubs服务不会与Storage进行对齐检查。

答案

EventProcessor框架旨在实现您正在寻找的目标。

检查点不会通过服务器(即EVENTHUBS服务)保留。它纯粹是客户端。您正在与Azure存储进行通信。这就是EventProcessor库带来新的附加依赖 - AzureStorageClient的原因。您可以连接到存储帐户&amp;检查点写入的容器 - 我们维护所有权信息 - EPH实例(名称)到他们拥有的EventHubs的分区以及他们当前读取/处理的检查点,直到。

根据基于计时器的检查点模式 - 您最初有 - 如果进程发生故障 - 您将在最后5分钟窗口中重新执行事件。 这是一个健康的模式:

  1. 基本假设是,故障是罕见的事件 - 所以你 很少会处理重复的事件
  2. 你最终会减少     调用存储服务(你很容易被压倒     经常检查)。我会更进一步     实际上,会异步触发检查点调用。 OnProcessEvents     如果检查点失败,请不要失败!
  3. 如果你想要绝对没有事件重复 - 你需要在下游管道中构建这个重复数据删除逻辑。

    • 每次EventProcessorImpl启动时 - 向下游查询最后一个序列号。它得到并保持丢弃事件,直到当前序列号

    here's more general reading on Event Hubs...