goka——基于kafka的go语言流处理框架

Goka是一个Go语言实现的流处理框架,强调组合性、可扩展性和容错性。它通过emitters、processors和views组件与Kafka交互,支持微服务分解。处理器组通过回调函数处理消息,利用Kafka的分区和复制实现容错。Goka的Promise机制简化了异步写操作,而goroutine的控制确保了流程的正确执行。
摘要由CSDN通过智能技术生成

一、goka简单介绍(第一和第二部分基于官方博客,对部分内容进行精简翻译原文地址)

为了实现组合性、可扩展性和容错性,Goka鼓励开发者通过使用emitters(发射者)、processors(处理者)和views(视图,group表的持久高速缓存)三种组件来分解application到微服务中。下图描绘了使用的三种组件、kafka和扩展的API的架构图。
在这里插入图片描述
emitters.发射者,在kafka的视角相当于生产者,emitter将事件作为key-value message形式发送给kafka。API提供给开发者,可以自定义emitter的一些配置。

processors.处理者,是一组回调函数的集合。当新消息到达,processor会修改key-value table的内容。processor会消费input topics,当有新消息m到达某一个input topic,相应的回调函数便会被调用。接着回调函数会修改table中与消息m的key对应的value。

Processor groups.处理者组,在kafka的视角相当于消费者组,并且与它需要维护修改的group表(表示处理者组状态)进行绑定。处理者组的多个processor实例可以划分消费input topic和更新table的工作。这些实例属于同一个处理者组。

Group table and group topic.每一个处理者组都绑定到一个table,并且单独拥有写访问权。这个table被称作group table。group topic跟踪group table的更新,并且允许processor实例的恢复和再平衡。每一个processor实例会将负责的分区内容保存到本地存储,默认为leveldb。磁盘中的本地存储允许较小的内存占用并最大限度地缩短恢复时间。

view.视图,group table的持久高速缓存。订阅group topic的所有分区的更新,维持本地磁盘存储与group table的同步工作。另外,通过view,可以通过例如gRPC轻松地提供group table的最新内容。

processor可以通过调用ctx.Emit()发送一些消息到其他流的topic,并且可以通过调用ctx.Join()和ctx.Lookup()从其他processor groups的table中读值。

二、重要特性

1.组合性

当使用Goka的构建块来分解应用的时候,便可以很容易地复用其他应用的table和topic,从而扩展应用的边界。下面是两个应用程序用户状态和点击计数,共享topic和table的例子。
在这里插入图片描述
点击计数。只要用户单击特定按钮,emitter就会发送用户单击事件。点击计数processor会计算用户执行的点击次数。点击计数服务通过REST接口提供对点击计数表内容的读访问权限。复制该服务以实现更高的可用性和更短的响应时间。

用户状态。用户状态处理器跟踪平台中每个用户的最新状态消息 - 让我们假设我们的示例是社交网络系统的一部分。只要用户更改其状态,emitter就负责生产状态更新事件。用户状态服务提供用户的最新状态(来自用户状态)以及用户执行的点击次数(来自点击次数)。对于连接表,服务只是为每个表实例化一个视图。

需要注意的是,emitter不必与任何特定的Goka应用程序相关联。它们通常只是简单地嵌入到其他系统中,只是为了宣布要按需处理的相关事件。另外,只要使用相同的编码解码规则对消息进行编码和解码,Goka应用程序就可以与Kafka Streams,Samza或任何其他基于Kafka的流处理框架或库共享流和表。

2.可扩展性

emitters,发射者是相当简单的组件,可以通过实例化多个发射者来达到扩展的效果。发射者的限制因素是kafka可以承担的最大负载,最大负载取决于可用节点数量,分区总数,消息的大小和可用的网络带宽。

processors,可以通过实例化多个processor来达到扩展的效果。一个processor group的所有input topic都需要与group topic共同分区,使得input topic和group topic拥有相同数量的分区和相同的键范围。这样做使得Goka可以使用kafka的Rebalance机制一致地为processor实例分配工作,并且将所有topic(包括input topic和group topic)的分区组合在一起,然后将这些分区组一次分配给processor实例。例如,如果为processor A分配了input topic的分区1,那么也会为A分配其他input topic的分区1和group table的分区1。
每个processor实例仅保留其负责分区的本地副本,并且仅会消费这些分区而产生流量。而当某个processor实例出现故障时,其余实例会分享这个故障实例的工作和流量,使得流量和存储要求会发生改变。

views,本地视图包含他们订阅的完整table的副本。如果通过使用一个view实现服务,则可以通过生成服务的另一个副本来扩展服务。view的每个实例都使用group table的所有分区,而且每个view实例都将table的副本保存在本地存储中,从而增加磁盘的使用量。事实上,内存占用量不一定与磁盘占用空间一样大,因为只有用户经常检索的键值才会被LevelDB高速缓存在内存中。

3.容错性

emitters,发射者完成指定topic的消息发送后,该消息将会保证由订阅该topic的processor处理。如果发送了两条消息,processor也会按照相同的顺序处理。

processors,保证每条输入消息至少处理一次。作为kafka的消费者,processors会持续跟踪他们处理的每个topic的分区。只要输入消息被完全处理并且processor的输出持久化到了kafka后,processor便会将输入消息的偏移量提交到kafka。
如果processor在提交消息偏移量之前崩溃,则会在恢复之后再处理该消息,并进行相应的table的更新和输出消息。如果该processor实例未恢复,则group会进行Rebalance,为剩余processor实例分配失败实例的所属分区,kafka中的每个分区由不同的processor以相同的顺序消费,因此状态更新在恢复后会以相同的顺序重新消费,即使是另一个processor实例也会如此。

view,视图最终会看到它所订阅的tab

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在单节点 Kafka 上使用 Goka 创建主题(topic),您需要遵循以下步骤: 1. 首先,您需要安装和启动 Kafka。您可以从 Kafka 官方网站下载 Kafka 并按照说明进行安装和启动。 2. 然后,您需要安装 Goka。您可以通过运行以下命令来安装 Goka: ``` go get github.com/lovoo/goka ``` 3. 接下来,您需要编写一个 Goka 应用程序并在其中定义您的主题(topic)。下面是一个示例应用程序: ``` package main import ( "context" "fmt" "log" "github.com/lovoo/goka" ) const ( brokers = "localhost:9092" topic = "my-topic" group = "my-group" storagePath = "/tmp/goka-example" ) func main() { g := goka.DefineGroup(group, goka.Input(topic, new(goka.StringCodec), func(ctx context.Context, msg interface{}) { log.Printf("Received message: %s", msg.(string)) }), ) p, _, err := goka.NewProcessor(brokers, g, goka.WithStorageBuilder(goka.MemoryStorageBuilder())) if err != nil { log.Fatalf("Error creating processor: %v", err) } if err := p.Start(); err != nil { log.Fatalf("Error starting processor: %v", err) } defer p.Stop() emitter, err := goka.NewEmitter(brokers, topic, new(goka.StringCodec)) if err != nil { log.Fatalf("Error creating emitter: %v", err) } if err := emitter.EmitSync("hello world!"); err != nil { log.Fatalf("Error emitting message: %v", err) } fmt.Println("Press any key to exit...") fmt.Scanln() } ``` 这个应用程序定义了一个名为“my-topic”的主题,并将消息打印到控制台。它还使用了内存存储,但您可以使用任何支持的存储类型。最后,它使用了一个发射器(emitter),将“hello world!”消息发送到“my-topic”主题。 4. 最后,您可以使用以下命令运行应用程序: ``` go run main.go ``` 这将启动应用程序并将“hello world!”消息发送到“my-topic”主题。您可以在控制台中看到收到的消息。 请注意,这只是一个简单的示例,您可以根据您的需求修改它。此外,如果您使用的是真实的 Kafka 集群,您需要将“brokers”变量设置为您的 Kafka 集群的地址。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值