我正在尝试构建一个从AWS Kinesis读取数据的简单应用程序。我已经设法使用单个分片读取数据,但我想从4个不同的分片中获取数据。
问题是,我有一个while循环,只要分片处于活动状态就会迭代,这会阻止我从不同的分片中读取数据。到目前为止,我无法找到替代算法,也无法实现基于KCL的解决方案。 非常感谢提前
public static void DoSomething() {
AmazonKinesisClient client = new AmazonKinesisClient();
//noinspection deprecation
client.setEndpoint(endpoint, serviceName, regionId);
/** get shards from the stream using describe stream method*/
DescribeStreamRequest describeStreamRequest = new DescribeStreamRequest();
describeStreamRequest.setStreamName(streamName);
List<Shard> shards = new ArrayList<>();
String exclusiveStartShardId = null;
do {
describeStreamRequest.setExclusiveStartShardId(exclusiveStartShardId);
DescribeStreamResult describeStreamResult = client.describeStream(describeStreamRequest);
shards.addAll(describeStreamResult.getStreamDescription().getShards());
if (describeStreamResult.getStreamDescription().getHasMoreShards() && shards.size() > 0) {
exclusiveStartShardId = shards.get(shards.size() - 1).getShardId();
} else {
exclusiveStartShardId = null;
}
}while (exclusiveStartShardId != null);
/** shards obtained */
String shardIterator;
GetShardIteratorRequest getShardIteratorRequest = new GetShardIteratorRequest();
getShardIteratorRequest.setStreamName(streamName);
getShardIteratorRequest.setShardId(shards.get(0).getShardId());
getShardIteratorRequest.setShardIteratorType("LATEST");
GetShardIteratorResult getShardIteratorResult = client.getShardIterator(getShardIteratorRequest);
shardIterator = getShardIteratorResult.getShardIterator();
GetRecordsRequest getRecordsRequest = new GetRecordsRequest();
while (!shardIterator.equals(null)) {
getRecordsRequest.setShardIterator(shardIterator);
getRecordsRequest.setLimit(250);
GetRecordsResult getRecordsResult = client.getRecords(getRecordsRequest);
List<Record> records = getRecordsResult.getRecords();
shardIterator = getRecordsResult.getNextShardIterator();
if(records.size()!=0) {
for(Record r : records) {
System.out.println(r.getPartitionKey());
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
答案 0 :(得分:1)
建议您不要从多个分片中读取单个进程/工作程序。首先,正如您所看到的那样,它会增加代码的复杂性,但更重要的是,您将难以扩展。
可扩展性的“秘密”是拥有小型独立工人或其他此类单位。您可以在AWS中的Hadoop,DynamoDB或Kinesis中看到此类设计。它允许您构建小型系统(微服务),可以根据需要轻松扩展和缩小。随着服务变得更加成功或其使用的其他波动,您可以轻松添加更多工作/数据单元。
正如您在这些AWS服务中所看到的,您有时可以在DynamoDB中自动获得此可伸缩性,有时您需要为您的kinesis流添加分片。但是对于您的应用程序,您需要以某种方式控制您的可伸缩性。
对于Kinesis,您可以使用AWS Lambda或Kinesis Client Library(KCL)进行扩展和缩小。他们俩都在监听您的流的状态(分片和事件的数量),并使用它来添加或删除工作人员并提供事件供他们处理。在这两种解决方案中,您应该构建一个针对单个分片的工作者。
如果需要对齐多个分片中的事件,可以使用某些状态服务(如Redis或DynamoDB)来实现。
答案 1 :(得分:0)
对于更简单、更简洁的解决方案,您只需担心提供自己的消息处理代码,我建议使用 KCL 库。
引用自 documentation
<块引用>KCL 充当记录处理逻辑之间的中介 和 Kinesis 数据流。 KCL 执行以下任务: