Amazon Kinesis Data Streams
开发人员指南
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。请点击 Amazon AWS 入门,可查看中国地区的具体差异

重新分片后

在任何类型的重新分片过程之后,并在继续常规的记录处理之前,需要执行其他一些过程并考虑一些注意事项。以下各节介绍了这些过程。

等待流再次变为活动状态

在调用重新分片操作 splitShardmergeShards 之后,您需要等待流再次变为活动状态。要使用的代码与您在创建流之后等待流变为活动状态时使用的代码相同。下面重复列出了代码。

DescribeStreamRequest describeStreamRequest = new DescribeStreamRequest(); describeStreamRequest.setStreamName( myStreamName ); long startTime = System.currentTimeMillis(); long endTime = startTime + ( 10 * 60 * 1000 ); while ( System.currentTimeMillis() < endTime ) { try { Thread.sleep(20 * 1000); } catch ( Exception e ) {} try { DescribeStreamResult describeStreamResponse = client.describeStream( describeStreamRequest ); String streamStatus = describeStreamResponse.getStreamDescription().getStreamStatus(); if ( streamStatus.equals( "ACTIVE" ) ) { break; } // // sleep for one second // try { Thread.sleep( 1000 ); } catch ( Exception e ) {} } catch ( ResourceNotFoundException e ) {} } if ( System.currentTimeMillis() >= endTime ) { throw new RuntimeException( "Stream " + myStreamName + " never went active" ); }

分片之后的数据路由、数据保留和分片状态

Kinesis Data Streams 是一种实时数据流服务,也就是说,您的应用程序应假定数据不断地在流中的分片内流动。当您重新分片时,流至父分片的数据记录将基于数据记录分区键映射到的哈希键值重新路由至子分片。但是,重新分片前位于父分片中的任何数据记录将仍位于这些父分片中。换句话说,父分片在重新分片发生时不会消失;它们将与重新分片之前它们包含的数据一起保留。父分片中的数据记录可通过在 Kinesis Data Streams API 中使用 getShardIteratorgetRecords 操作或通过 Kinesis Client Library 进行访问。

注意

数据记录在当前保留期内添加到流中后即可访问。不论在该期间内对流中的分片进行了任何更改,都是如此。有关流的保留期的更多信息,请参阅更改数据保留期

在重新分片过程中,父分片将从 OPEN 状态过渡到 CLOSED 状态再过渡到 EXPIRED 状态。

  • OPEN:在重新分片操作之前,父分片处于 OPEN 状态,这意味着数据记录可添加到分片中并且可从分片进行检索。

  • CLOSED:在重新分片操作之后,父分片将过渡到 CLOSED 状态。这意味着无法再向此分片添加数据记录。原本应该已添加到此分片的数据记录现在将改为添加到子分片。但是,数据记录在有限时间内仍可从此分片进行检索。

  • EXPIRED:在流的保留期过期之后,父分片中的所有数据记录将会过期,不再可供访问。此时,父分片自身将过渡到 EXPIRED 状态。用于枚举流中的分片的 getStreamDescription().getShards 调用不包括返回的分片列表中的 EXPIRED 分片。有关流的保留期的更多信息,请参阅更改数据保留期

在进行重新分片并且流再次处于 ACTIVE 状态之后,您可立即开始读取子分片中的数据。但是,在重新分片后保留的父分片可能仍包含您尚未读取并且已在重新分片前添加到流中的数据。如果您在读取完父分片中的所有数据之前读取子分片中的数据,则可不按数据记录的序列号指定的顺序读取特定哈希键的数据。因此,假定数据顺序很重要,您在重新分片后应始终继续读取父分片中的数据直到读取完,并且只有在这之后才开始读取子分片中的数据。如果 getRecordsResult.getNextShardIterator 返回 null,则这指示您已读取完父分片中的所有数据。如果您使用 Kinesis Client Library 读取数据,则此库可确保您按顺序接收数据,即使发生重新分片也是如此。