KafkaStream KTable转储

时间:2019-01-27 05:52:27

标签: apache-kafka-streams

我的问题是关于在收到触发消息时转储值符合特定条件的KTable。

以下是此问题的一个示例:

KTable-CurrentAccountBalance

   John    +10,
   Joe     -1,
   Alice   -2,
   Jill    +5,

我的要求是获取所有传入事件中余额为负的记录:FETCH_NEGATIVE_BALANCE_ENTRIES 在不同的命令流上。

我的想法是: 如果使用命令流在CurrentAccountBalance KTable上执行 leftJoin ,我们可以转储CurrentAccountBalance的所有条目(可用于过滤器),但是不会发生。

leftJoin的ValueJoiner仅在右侧接收命令,在左侧接收null(而不是全部) CurrentAccountBalance条目)。我想念什么吗?

谢谢

2 个答案:

答案 0 :(得分:0)

由于KTable联接基于主键,因此KTable联接中的单个输入消息将在Kafka Stream中产生一个(或零个)输出消息。

您可以做的是创建一个自定义transformer,它接收命令并连接到KTable状态(如果指定KTable存储名称,则可以轻松地将该状态连接到转换器)。收到命令后,您可以获取一个state.all()迭代器,并搜索与您的条件匹配的所有条目,并通过context.forward()以及在转换器下游的接收器发出它们。

答案 1 :(得分:0)

这是我实现的转储符合特定条件的KTable条目的解决方案。在这里将其描述给以后寻求类似解决方案的其他人。

  1. 创建了一个自定义映射器(FlatMapper)以生成满足条件的消息。我已经将状态存储作为构造函数参数传递给此映射器。
  2. 创建了一个名为“ FLUSH_NEGATIVE_BALANCES”的事件,并在名为commandStream的新KStream上读取了该事件
  3. 收到此新的FLUSH命令后,我将调用在步骤1中创建的flatmapper来生成满足条件的消息(在我的情况下为负余额)
  4. 我将flatmapper的输出写入接收器流。

    / *这是Flatmapper的代码,上面的步骤是Step1 * /

    公共类NegativeBalanceMapper实现KeyValueMapper >> { 私有最终BusinessRuleValidator businessRuleValidator; 私人最终StoreHolder storeHolder;

    public NegativeBalanceMapper(StoreHolder storeHolder, BusinessRuleValidator businessRuleValidator)
    {
        this.storeHolder = storeHolder;
        this.businessRuleValidator = businessRuleValidator;
    }
    
    public Iterable<KeyValue<String, BalanceEntry>> apply(String key, CommandEntry value)
    {
        List<KeyValue<String, BalanceEntry>> result = new ArrayList<>();
        if (value == null)
        {
            return result;
        }
    
        final ReadOnlyKeyValueStore<String, BalanceEntry> ledgerStore = storeHolder.getLedgerStore();
        if (ledgerStore != null)
        {
            KeyValueIterator<String, BalanceEntry> range = ledgerStore.all();
            while (range.hasNext())
            {
                KeyValue<String, BalanceEntry> next = range.next();
                if (businessRuleValidator.isNegativeBalance(next.value))
                {
                    result.add(new KeyValue<>(next.key, next.value));
                }
            }    
        }
        return result;
    }
    

    }

    / 这里是接收到FLUSH命令时如何调用它的步骤-上面的step2 / 最终的KStream negativeBalances = filteredCommandStream.flatMap(negativeBalanceMapper);

    / 在这里,我将其推到上方的下沉步骤 /

    negativeBalances.to(KafkaConstants.TOPIC_NEGATIVE_BALANCES,Produced.with(Serdes.String(),serdeRegistry.getBalanceEntrySerde()));

感谢Matthias的指导。