"Kafka Streams is a powerful stream-processing library that offers stateful operations. Along with the stateful operations is a unique feature of Kafka Streams, Interactive Queries, or IQ. IQ allows you to leverage the application's state from the outside by directly querying the state stores.
IQ has always been a part of Kafka Streams, but the original version lacked some key features. Namely, the ability to query the state of a custom state store. With the addition of IQ v2, that has now changed. Additionally, IQ v2 brings other benefits like pushing queries down to the store level making querying more efficient.
In this talk, I will cover:
* Building an Interactive Query service including routing queries between app instances
* Creating custom queries using Interactive Query v2
* Testing your IQ Application
Attending this talk will teach you how to use IQ v2 to create queries more aligned with your unique business needs."
2. @bbejeck
Nice to meet you!
• Member of the DevX team
• Prior to DevX ~3 years as engineer on Kafka Streams team
• Apache Kafka® Committer and PMC member
• Author of “Kafka Streams in Action” - 2nd edition underway!
2
24. @bbejeck
Building The Query Service
Spring Boot
1. Provides the Spring container
2. Embeds a web-server
3. Quickly set up a stand-alone application
27
26. @bbejeck
Start Kafka Streams
@PostConstruct
public void init() {
kafkaStreams = new KafkaStreams(topology(), properties);
kafkaStreams.cleanUp(); //Optional – not a production setting
kafkaStreams.start();
}
29
39. @bbejeck
Why gRPC?
42
•High performance RPC framework
•Simple and quick service definition with a proto file
•Uses Protocol Buffers for serialization
•More performant than REST*
43. @bbejeck
gRPC – Define the service
46
@GRpcService
@Component
public class InternalQueryService extends
InternalQueryGrpc.InternalQueryImplBase {
}
44. @bbejeck
gRPC – Define the service
47
@GRpcService
@Component
public class InternalQueryService extends
InternalQueryGrpc.InternalQueryImplBase {
private final KafkaStreams kafkaStreams;
@Autowired
public InternalQueryService(KafkaStreams kafkaStreams) {
this.kafkaStreams = kafkaStreams;
}
}
45. @bbejeck
gRPC – Define the service
48
@Override
public void keyQueryService(
final KeyQueryRequestProto request,
final StreamObserver<QueryResponseProto> responseObserver) {
}
46. @bbejeck
gRPC – Define the service
49
@Override
public void keyQueryService(
final KeyQueryRequestProto request,
final StreamObserver<QueryResponseProto> responseObserver) {
....
queryResult = kafkaStreams.query(...)
Builder responseBuilder = QueryResponseProto.newBuilder();
aggregation = queryResult.getResult();
....
responseBuilder.addAggregations(aggregation);
responseObserver.onNext(repsonseBuilder.build());
responseObserver.onCompleted();
}
54. @bbejeck
Custom Queries- Steps
1. Extend the Query interface
2. Create wrapper delegate class for state stores * and supplier
3. Override the KeyValueStore.query method
* KIP proposal in the works for registering a custom handler
57
55. @bbejeck
Custom Queries- Extend Query interface
public interface CustomQuery<R> extends Query<R> {
enum Type {
MULTI_KEY,
FILTERED_RANGE
}
Type type();
}
58
56. @bbejeck
Custom Queries- Wrapper store class
public abstract class StoreDelegate implements KeyValueStore<Bytes, byte[]> {
private final KeyValueStore<Bytes, byte[]> delegate;
StoreDelegate(KeyValueStore<Bytes, byte[]> delegate) {
this.delegate = delegate;
}
@Override
public void put(Bytes key, byte[] value) {
delegate.put(key, value);
}
59
57. @bbejeck
Custom Queries- Store wrapper
public class CustomQueryStore extends StoreDelegate {
@Override
public <R> QueryResult<R> query(final Query<R> query,
final PositionBound positionBound,
final QueryConfig config) {
if (!(query instanceof CustomQuery)) {
return super.query(query, positionBound, config);
}
}
60
67. @bbejeck
Performance Considerations
70
1. Key space of 200
2. Produce 8K records per second
3. Run Kafka Streams for 10 minutes
4. Record process rate from Thread metrics
5. Run IQ for 10 minutes then record process rate again
70. @bbejeck
Summary
• Interactive Queries allow to you view the state of a running Kafka Streams
application
• By leveraging Spring Boot and creating an @RestController quickly get a
Kafka Streams application with IQ enabled
• gRPC provides a good mechanism for internal communication
• IQ V2 allows for querying a custom store.
73