内部状态存储的卡夫卡流:“ TopicAuthorizationException:未获得访问主题的权限”

时间:2019-10-09 08:19:18

标签: apache-kafka apache-kafka-streams

Java:OpenJdk 11 卡夫卡:2.2.0 卡夫卡流库:2.3.0

我正在尝试在 docker 容器中部署我的Kafka流应用程序,并且在尝试创建带有TopicAuthorizationException的内部状态存储时失败。 它在本地效果很好。本地和服务器上的主要区别在于,该服务器连接到已部署的服务器Kafka,并使用常规的 Kerberos 身份验证进行身份验证。 我无法理解身份验证与本地商店之间的链接。

我的信息流看起来像这样:

StreamsBuilder builder = new StreamsBuilder();

        //We stream from the source topic
        KStream<String, EnrichedMessagePayload> sourceMessagesStream = builder.stream(sourceTopic, Consumed
                .with(Serdes.serdeFrom(String.class), INPUT_SERDE));

        //We group per room and window
        TimeWindowedKStream<String, EnrichedMessagePayload> windowed = sourceMessagesStream
                .groupByKey().windowedBy(TimeWindows.of(Duration.ofMillis(windowSize)).grace(Duration.ZERO));

        //We make them a list
        KStream<Windowed<String>, WindowedMessages> grouped = windowed
                .aggregate(WindowedMessages::new,
                        (key, value, aggregate) -> aggregate.add(value),
                        Materialized.with(Serdes.String(), Serdes.serdeFrom(windowSerializer, windowSerializer)))
                .suppress(Suppressed.untilWindowCloses(unbounded()))
                .toStream();

        //Filter
        KStream<Windowed<String>, FilterResult> filtered = grouped
                .mapValues((readOnlyKey, value) -> filterWindow(value.getMessages()));

        //Re map to its original form
        KStream<String, OutputPayload> reduced = filtered
                .flatMap((KeyValueMapper<Windowed<String>, WindowedMessages, Iterable<KeyValue<String, OutputPayload>>>) (key, value) -> value
                        .getMessages()
                        .stream().map(payload -> new KeyValue<>(key.key(), payload))
                        .collect(toList()));


        //Target topic
        reduced.to(sinkTopic, Produced
                .with(Serdes.serdeFrom(String.class), SERDE));

        return builder.build();

它接收消息流,将其作为窗口,在每个窗口中汇总所有消息,仅保留列表的最后一个版本,并带有“禁止显示”,然后将所有内容进行平面映射以将其转发到另一个主题。

每次我得到这种例外:

  

错误消息是:org.apache.kafka.common.errors.TopicAuthorizationException:未经授权访问主题:[主题授权失败。]   2019-10-09 06:44:03.255 +0000错误[filterer-d83f2f60-b2bd-40b2-a314-4b20f32918f7-StreamThread-1] [StreamThread.java:777]-流线程[filterer-d83f2f60-b2bd-40b2- a314-4b20f32918f7-StreamThread-1]在处理期间遇到以下意外的Kafka异常,这通常表明Streams内部错误:-[rapid_r-live-message-filterer-0-0-1-snapshot-10.1e842f1a-ea60-11e9-9c7d -024298932744]-[]-[]   org.apache.kafka.streams.errors.StreamsException:无法创建主题过滤器KTABLE-SUPPRESS-STATE-STORE-0000000005-changelog。       在org.apache.kafka.streams.processor.internals.InternalTopicManager.getNumPartitions(InternalTopicManager.java:212)       在org.apache.kafka.streams.processor.internals.InternalTopicManager.validateTopics(InternalTopicManager.java:226)       在org.apache.kafka.streams.processor.internals.InternalTopicManager.makeReady(InternalTopicManager.java:104)       在org.apache.kafka.streams.processor.internals.StreamsPartitionAssignor.prepareTopic(StreamsPartitionAssignor.java:971)       在org.apache.kafka.streams.processor.internals.StreamsPartitionAssignor.assign(StreamsPartitionAssignor.java:618)       在org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.performAssignment(ConsumerCoordinator.java:424)       在org.apache.kafka.clients.consumer.internals.AbstractCoordinator.onJoinLeader(AbstractCoordinator.java:622)       在org.apache.kafka.clients.consumer.internals.AbstractCoordinator.access $ 1100(AbstractCoordinator.java:107)       在org.apache.kafka.clients.consumer.internals.AbstractCoordinator $ JoinGroupResponseHandler.handle(AbstractCoordinator.java:544)处       在org.apache.kafka.clients.consumer.internals.AbstractCoordinator $ JoinGroupResponseHandler.handle(AbstractCoordinator.java:527)处       在org.apache.kafka.clients.consumer.internals.AbstractCoordinator $ CoordinatorResponseHandler.onSuccess(AbstractCoordinator.java:978)上       在org.apache.kafka.clients.consumer.internals.AbstractCoordinator $ CoordinatorResponseHandler.onSuccess(AbstractCoordinator.java:958)上       在org.apache.kafka.clients.consumer.internals.RequestFuture $ 1.onSuccess(RequestFuture.java:204)       在org.apache.kafka.clients.consumer.internals.RequestFuture.fireSuccess(RequestFuture.java:167)       在org.apache.kafka.clients.consumer.internals.RequestFuture.complete(RequestFuture.java:127)       在org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient $ RequestFutureCompletionHandler.fireCompletion(ConsumerNetworkClient.java:578)       在org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.firePendingCompletedRequests(ConsumerNetworkClient.java:388)       在org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:294)       在org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:233)       在org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:212)       在org.apache.kafka.clients.consumer.internals.AbstractCoordinator.joinGroupIfNeeded(AbstractCoordinator.java:415)       在org.apache.kafka.clients.consumer.internals.AbstractCoordinator.ensureActiveGroup(AbstractCoordinator.java:358)       在org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.poll(ConsumerCoordinator.java:353)       在org.apache.kafka.clients.consumer.KafkaConsumer.updateAssignmentMetadataIfNeeded(KafkaConsumer.java:1251)       在org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1216)       在org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1201)       在org.apache.kafka.streams.processor.internals.StreamThread.pollRequests(StreamThread.java:941)       在org.apache.kafka.streams.processor.internals.StreamThread.runOnce(StreamThread.java:846)       在org.apache.kafka.streams.processor.internals.StreamThread.runLoop(StreamThread.java:805)       在org.apache.kafka.streams.processor.internals.StreamThread.run(StreamThread.java:774)   由以下原因引起:org.apache.kafka.common.errors.TopicAuthorizationException:无权访问主题:[主题授权失败。]

1 个答案:

答案 0 :(得分:2)

这不是“身份验证”,而是“授权”。查看您的日志消息,其中显示“未授权访问主题”。据我所知,您无权创建内部主题“ filterer-KTABLE-SUPPRESS-STATE-STORE-0000000005-changelog”来支持本地禁止状态存储。默认情况下,Kafka代理中的主题支持Kafka Streams中包含的状态存储。在故障转移期间使用此内部主题来还原本地状态存储。这些内部主题是由Kafka Streams应用程序自动创建的,因此该应用程序需要具有适当的权限才能创建它们。

有关更多信息,请参见https://kafka.apache.org/23/documentation/streams/developer-guide/security.html#id1。在那里说:“运行应用程序的主体必须设置ACL,以便应用程序具有创建,读取和写入内部主题的权限。”