AWS Kinesis Stream初探记录(一)

去年的项目涉及了不少和数据流相关的内容,当时的自己还只会使用AWS SQS来处理消息数据流,一年下来虽然完成了既定计划,但是也暴露了一些问题。由于我们会用多个线程同时读取两条数据流来更新DynamoDB中存储的一条数据,时不时就会出现由于optimistic locking造成的conditional checker failure。在流量很大的时候,这种failure的数量会剧增导致消息处理的效率降低。

年末在和另一个组的交流中发现,他们也遇到过类似的问题。出现问题的原因,就是在项目开始的时候做出了错误的估计:“这种数据更新造成locking的情况不怎么会出现”,而实际情况则是呵呵呵啊。最后他们的解决方法是使用了Kinesis Stream。Kinesis Stream通过一个用户提供的partition key,把同一个key的数据都放到一个shard当中,而每一个shard都会被一个(且仅有一个)处理器processor处理。processor和shard之间是一一对应的关系。这样一来,只要Id一样的数据都被放到同一个shard当中并且由一个processor处理,就不会出现线程之间的race condition,自然也就能缓解数据量增加时系统的压力了。

于是乎这个假期跟随着AWS的文档,把Kinesis Stream的基本概念过了一遍。有些概念我自己觉得文档说的不是那么清楚,在读的过程中会萌生各种问题和假设,不过好在看完所有的文档后我的假设都得到了验证。为了免得以后忘记,在此记录一下(这里省略了一些其他概念,只是记录让我自己产生疑惑的地方)。

  • Kinesis Stream里面的数据可以被多个不同的应用Application读取和处理。他们相互之间不会互相影响。比如一个应用把数据发到DynamoDB,另一个则可以把数据发到别的地方比如S3。具体如何做到互不影响是个值得研究的问题,不过我有一个大概的设想。

  • 文档中有一些概念一开始让我有些疑惑,比如Application应用这个概念。疑惑来源于文档中一些地方有Application和Application Instance的互换使用。文档中说的是:

An Amazon Kinesis Streams application is a consumer of a stream that commonly runs on a fleet of EC2 instances.

一个应用有自己独有的功能,比如把数据发到DynamoDB。那么我们可以把这个应用部署到一台或者几台机器上,也就是一个fleet上。每一台机器上都有一个这个应用的实例application instance。这些应用实例会读取同一个stream里面的数据,至于哪个实例处理哪部分的数据、如何load balance和处理failure,都由Kinesis Consumer Library--KCL替用户处理了。

在第一点中提到的不同应用的情况,可以认为是有另一个fleet上部署的是另一种应用且同时也在读取这个Kinesis Stream当中的数据。

  • 那么KCL应用的数据又是如何分配到各个实例上又能保证大家相互协调不撕逼呢?一个应用实例在第一次启动的时候会去DynamoDB里建当前这个应用的状态表。KCL通过这个表和各个instance通信交流,由此掌握有多少个shard、有多少个instance/worker和processor,这样在以后需要scale的时候能够灵活分配shard到不同的机器上去处理。比如,一个开始有4个shard,但是只有一台机器1,那么所有shard都由机器1处理。后来发现搞不定,需要加一台机器2。KCL检测到有新的instance上线,它会分配两个shard给新的instance去处理。

  • 看例子的时候我注意到每个应用实例都会初始化一个worker,其中一个变量是processor factory。这不禁让我想刚才的例子,4个shard两个instance也就是只有两个worker,那么要做到一一对应,需要四个processor,这样看来只能是worker有能力生成多个processor。后来看了下源代码,worker中用到了executorService,factory这个也是一个提示,如果只需要一个processor,没必要传一个factory进去。后来我读到的文档也验证了这一点:

As noted in Tracking Amazon Kinesis Streams Application State, the KCL
tracks the shards in the stream using an Amazon DynamoDB table. When
new shards are created as a result of resharding, the KCL discovers
the new shards and populates new rows in the table. The workers
automatically discover the new shards and create processors to handle
the data from them. The KCL also distributes the shards in the stream
across all the available workers and record processors...In all these
cases, the shards-to-worker-to-record-processor mapping is
continuously updated to load balance processing.

这里的DynamoDB状态表也应该就是不同的应用能够同时处理同一个Kinesis Stream中的数据的原因。各读各的,每个人读到哪里自己记录到不同的表里,你读到哪里跟我也没什么关系。

  • shard、worker和processor之间的关系:
    一个shard只被一个worker和一个processor处理。shard和processor之间的关系是一对一。一个worker可以拥有多个processor来处理多个shard。worker和shard、processor的关系是多对一。

以上只是读文档的一些总结,具体使用后的情况还要具体代码实现以后再看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值