# Kinesis Connector Guide This guide covers Kinesis connector configuration for Amazon Managed Service for Apache Flink applications. ## Maven Dependencies **CRITICAL:** Use the correct Kinesis connector dependency from the official Apache Flink project: ```xml org.apache.flink flink-connector-aws-kinesis-streams ${kinesis-streams.version} ``` Where `kinesis-streams.version` should match your Flink version (e.g., `5.1.0-1.20` for Flink 1.20, `6.0.0-2.0` for Flink 2.2). See `dependency-management.md` for the full version mapping. ## Kinesis Source Configuration When creating a Kinesis source, use the `KinesisStreamsSource` builder pattern. This API is the same for both Flink 1.20 and 2.2. ### Correct API Pattern ```java import org.apache.flink.configuration.Configuration; import org.apache.flink.connector.kinesis.source.config.KinesisSourceConfigOptions; Map applicationProperties = loadApplicationProperties(env); Properties inputConfig = applicationProperties.get("input.kinesis.config"); Map configMap = new HashMap<>(); inputConfig.forEach((k, v) -> configMap.put(k.toString(), v.toString())); Configuration sourceConfig = Configuration.fromMap(configMap); String inputStreamArn = inputConfig.getProperty("stream.arn"); KinesisStreamsSource source = KinesisStreamsSource.builder() .setStreamArn(inputStreamArn) .setDeserializationSchema(new EventDeserializationSchema()) .setSourceConfig(sourceConfig) .build(); DataStream events = env .fromSource(source, WatermarkStrategy.forBoundedOutOfOrderness(Duration.ofSeconds(5)) .withTimestampAssigner((event, timestamp) -> event.getTimestamp()) .withIdleness(Duration.ofSeconds(10)), // CRITICAL for low-throughput streams "kinesis-source", org.apache.flink.api.common.typeinfo.TypeInformation.of(Event.class)) .name("kinesis-source") .uid("kinesis-source-uid") .filter(event -> event != null) .name("filter-null-events") .uid("filter-null-events-uid"); ``` ### Key Configuration Methods - `.setStreamArn(String)` - Set the stream ARN (preferred over stream name) - `.setDeserializationSchema(DeserializationSchema)` - Set how to deserialize records - `.setSourceConfig(Configuration)` - Set Kinesis client configuration - `.build()` - Build the source ## Kinesis Sink Configuration For Kinesis sinks, use the `KinesisStreamsSink` builder: ```java Properties outputConfig = applicationProperties.get("output.kinesis.config"); String outputStreamArn = outputConfig.getProperty("stream.arn"); KinesisStreamsSink sink = KinesisStreamsSink.builder() .setStreamArn(outputStreamArn) .setSerializationSchema(new EventSerializationSchema()) .setPartitionKeyGenerator(event -> String.valueOf(event.hashCode())) .setKinesisClientProperties(outputConfig) .build(); events.sinkTo(sink) .name("kinesis-sink") .uid("kinesis-sink-uid"); ``` ### Key Sink Methods - `.setStreamArn(String)` - Set the destination stream ARN - `.setSerializationSchema(SerializationSchema)` - Set how to serialize records - `.setPartitionKeyGenerator(PartitionKeyGenerator)` - Set partition key logic - `.build()` - Build the sink ## Polling Configuration and Throttling The Kinesis `GetRecords` API has a hard limit of 5 calls per second per shard, shared across all consumers reading from that shard. The Flink Kinesis connector's default polling behavior can be aggressive and lead to `ReadProvisionedThroughputExceeded` or `LimitExceededException` errors, especially when multiple consumers share a stream or when polling intervals are too short. **Key polling configuration options** (see [KinesisSourceConfigOptions Javadoc](https://www.javadoc.io/static/org.apache.flink/flink-connector-aws-kinesis-streams/6.0.0-2.0/org/apache/flink/connector/kinesis/source/config/KinesisSourceConfigOptions.html)): | Config Option | Description | Default | Recommendation | |---|---|---|---| | `SHARD_GET_RECORDS_MAX` | Max records per `GetRecords` call | 10,000 (but Kinesis limit is 10,000 records / 10 MB per call; throttling occurs at 1,000 records for some stream configurations) | Lower to 1,000 or less if seeing throttling | | `READER_EMPTY_RECORDS_FETCH_INTERVAL` | Interval between polling calls when no records are returned | 200ms (5 calls/sec) | Increase to 500ms–1s if sharing shards with other consumers or if the default rate exceeds the per-shard limit | | `SHARD_DISCOVERY_INTERVAL` | Interval for discovering new shards via `ListShards` | 10s | Increase if `ListShards` rate limiting is observed | **Tuning polling to avoid throttling:** ```java Configuration sourceConfig = new Configuration(); // Reduce max records per GetRecords call to stay within Kinesis limits sourceConfig.set(KinesisSourceConfigOptions.SHARD_GET_RECORDS_MAX, 1000); // Increase polling interval to reduce GetRecords call rate // Default is 200ms (5 calls/sec) — increase if sharing shards with other consumers sourceConfig.set(KinesisSourceConfigOptions.READER_EMPTY_RECORDS_FETCH_INTERVAL, Duration.ofMillis(500)); KinesisStreamsSource source = KinesisStreamsSource.builder() .setStreamArn("arn:aws:kinesis:us-east-1:123456789012:stream/my-stream") .setDeserializationSchema(new SimpleStringSchema()) .setSourceConfig(sourceConfig) .build(); ``` **When polling tuning is sufficient (vs switching to EFO):** - Single consumer reading from the stream: tune polling — EFO is unnecessary cost since there is no shared-quota contention. - 2+ consumers and still seeing `ReadProvisionedThroughputExceeded` after raising `READER_EMPTY_RECORDS_FETCH_INTERVAL`: switch to EFO. Tuning polling intervals across multiple consumers is fragile; EFO eliminates the shared quota entirely. - Polling interval increase introduces unacceptable latency: switch to EFO (HTTP/2 push has no polling delay). - You expect to scale to more consumers later: prefer EFO upfront. See [kinesis-efo-guide.md](kinesis-efo-guide.md) for EFO configuration, consumer lifecycle, and the full when-to-use-EFO checklist. **Diagnosing polling throttling:** - Check CloudWatch metric `ReadProvisionedThroughputExceeded` on the Kinesis stream — sustained values > 0 indicate throttling. - Check Managed Service for Apache Flink CloudWatch logs for `LimitExceededException` errors. - Monitor `GetRecords.Latency` and `GetRecords.Success` metrics to correlate throttling with read performance. ## Migrating from Legacy Kinesis Consumer to KinesisStreamsSource **CRITICAL for Flink 2.x upgrades:** KDS connector versions below 5.0 have state that is incompatible with the Flink 2.2 connector (v6.0.0-2.0). You must migrate to connector v5.0+ on Flink 1.x before upgrading to Flink 2.x. See the [AWS blog post on the Kinesis source connector](https://aws.amazon.com/blogs/big-data/introducing-the-new-amazon-kinesis-source-connector-for-apache-flink/) for full details. The legacy `FlinkKinesisConsumer` uses the removed `SourceFunction` interface and will not work with Flink 2.x. The `KinesisStreamsSource` uses the FLIP-27 Source API. ### Migration Paths **DataStream API with operator UIDs defined:** 1. Update dependencies: replace `flink-connector-kinesis` with `flink-connector-aws-kinesis-streams` v5.0.0+ 2. Replace `FlinkKinesisConsumer` with `KinesisStreamsSource` builder pattern 3. Change the UID of the source operator to a new string (this selectively resets source state while preserving all other operator state) 4. Configure starting position with `AT_TIMESTAMP` set to just before deployment time 5. Deploy with `allowNonRestoredState = true` **Table API/SQL or DataStream without operator UIDs:** 1. Update dependencies and code as above 2. Deploy with `SKIP_RESTORE_FROM_SNAPSHOT` since Flink cannot map old operator state to new operators 3. After the application is running, switch back to `RESTORE_FROM_LATEST_SNAPSHOT` for future restarts ### Key Differences from Legacy Connector | Feature | Legacy `FlinkKinesisConsumer` | New `KinesisStreamsSource` | |---------|-------------------------------|---------------------------| | Interface | `SourceFunction` (removed in 2.x) | FLIP-27 Source API | | Stream identifier | Stream name | Stream ARN (cross-region/account support) | | Watermarks | Implicit defaults | Explicit `WatermarkStrategy` required | | Ordering on reshard | Not guaranteed | Guaranteed via parent-child shard lineage | | Shard assigner | Even shard distribution | Uniform partition-key distribution | | AWS SDK | v1 | v2 (non-blocking I/O) | | JAR size | ~60 MB | ~200 KB | | KCL/KPL dependency | Included | Removed (no built-in KPL de-aggregation) | ### State Compatibility Warning The saved state from `FlinkKinesisConsumer` is not compatible with `KinesisStreamsSource`. You cannot restore source position from a snapshot taken with the legacy connector. Plan for either selective state reset (with UIDs) or full state reset (without UIDs) as described above. ## Authentication In Managed Service for Apache Flink, authentication to Kinesis is handled automatically via the application's IAM execution role. No explicit credentials configuration is needed in the code.