我们一直在研究 Kafka 和 Kinesis 之间的权衡,就在最近……Kinesis 赢了!
Kinesis 定价基于两个维度:每个分片的小时价格(决定整体并发/吞吐量),以及每 100 万条消息的单价。正如我在之前的帖子中提到的,我们处理了*吨*的事件,如果我们简单地将这些事件以 1:1 的比例推送到 Kinesis 流中,我们很快就会把所有的钱都交给亚马逊并倒闭。
然而,随着最近发布的 Kinesis Producer Library (KPL),Amazon 公开了将多个消息/事件聚合到单个 PUT 单元中的本机功能。 PUT 单元的最大大小为 25Kb。如果消息大小为 150 字节,则可以将大约 150 条消息塞入单个 PUT 单元! (并节省一些严肃的面团!)
这是直接来自 Kinesis 定价计算器的 数学计算:
没有KPL,
100K m/s *(150 字节/m)= 100 个分片和 263,520M PUT 单元 = 4,787.28 美元/月
* 注意:每个分片只能处理 1K/s,这就是我们最终得到 100 个分片的原因。
现在使用 KPL,假设我们只能在每个 PUT 单元中容纳 100 条消息。
我们会将所需的吞吐量(消息/秒)降低到 1K/s。
每个 PUT 单元中有 100 条消息,每个单元的大小为 15Kb。 (100 * 150 字节)
这给了我们:
1K m/s * (15 Kb/m) = 15 个分片和 2,635.2M PUT 单位 = 201.60 美元/月
节省了:~20 倍!!
那么,让我们看看这在架构上意味着什么......
首先,您需要查看 KPL 推荐使用矩阵:
http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-kpl-integration.html
我对该图表的天真解释是:使用 Java!
具有讽刺意味的是,生产者实际上是一个本地构建的微服务/二进制文件。 KPL 是围绕使用进程间通信将工作委托给微服务的本机二进制文件的 java 包装器。
在 Java 中,集成 KPL 很简单。这是关键组件。
首先,配置生产者:
KinesisProducerConfiguration config = new KinesisProducerConfiguration();
config.setRegion(region);
config.setCredentialsProvider(new ProfileCredentialsProvider());
config.setMaxConnections(1);
config.setRequestTimeout(60000);
config.setRecordMaxBufferedTime(15000);
config.setNativeExecutable(
"/Users/brianoneill/git/amazon-kinesis-producer/bin/darwin-4.2.1/debug/kinesis_producer");
producer = new KinesisProducer(config);
请注意,KPL 实际上是异步发送消息,在内部缓冲/聚合这些消息(这使得围绕消息传递的保证具有挑战性——但我们将把这个问题推迟到另一天)。
另请注意,我构建了自己的本机二进制文件,并指定了它的位置。您不一定需要这样做,二进制文件实际上被捆绑到 JAR 文件中,并在运行时解压缩到一个临时位置。 (是的,疯了吗?)
接下来,您需要发送一些数据:
这很简单,一行代码:
KinesisProducerConfiguration config = new KinesisProducerConfiguration();
config.setRegion(region);
config.setCredentialsProvider(new ProfileCredentialsProvider());
config.setMaxConnections(1);
config.setRequestTimeout(60000);
config.setRecordMaxBufferedTime(15000);
config.setNativeExecutable(
"/Users/brianoneill/git/amazon-kinesis-producer/bin/darwin-4.2.1/debug/kinesis_producer");
producer = new KinesisProducer(config);
最后,您需要找出您的消息发生了什么:
对于这一个,我们将添加一个回调到未来:
KinesisProducerConfiguration config = new KinesisProducerConfiguration();
config.setRegion(region);
config.setCredentialsProvider(new ProfileCredentialsProvider());
config.setMaxConnections(1);
config.setRequestTimeout(60000);
config.setRecordMaxBufferedTime(15000);
config.setNativeExecutable(
"/Users/brianoneill/git/amazon-kinesis-producer/bin/darwin-4.2.1/debug/kinesis_producer");
producer = new KinesisProducer(config);
其中,回调是处理记录时将调用的方法。这是一个例子:
KinesisProducerConfiguration config = new KinesisProducerConfiguration();
config.setRegion(region);
config.setCredentialsProvider(new ProfileCredentialsProvider());
config.setMaxConnections(1);
config.setRequestTimeout(60000);
config.setRecordMaxBufferedTime(15000);
config.setNativeExecutable(
"/Users/brianoneill/git/amazon-kinesis-producer/bin/darwin-4.2.1/debug/kinesis_producer");
producer = new KinesisProducer(config);
简而言之,就是 KPL。
对我们来说,这是一个巨大的胜利,实际上使 Kinesis 成为一个可行的替代方案。
现在,我们只需要弄清楚如何将它融入其他一切。 =)
Kinesis Firehose 助您一臂之力! (敬请关注)