我正在寻找一种方法来创建一种流应用程序,该应用程序可以承受每秒数百万个事件并实时输出这些事件的不同计数。由于此流不受任何时间窗口的限制,因此显然必须由一些存储支持。但是,我找不到保持良好抽象级别的最佳方法(这意味着我想要一个框架来为我处理存储和计数,否则我根本不需要框架(。我的首选存储是Cassandra和Redis(理想情况下(。
我考虑过的选项是Flink,Spark和Kafka Streams。我确实知道它们之间的区别,但我仍然无法选择最佳解决方案。有人可以建议吗?提前谢谢。
无论您选择哪种解决方案,如果您可以承受它不是 100% 准确的(但非常非常接近(,您就可以让您的操作员使用 HyperLogLog(有可用的 Java 实现(。这使您实际上不必保留有关每个单独项目的数据,从而大大减少了内存使用量。
假设 Flink,必要的状态非常小(<1MB(,因此可以轻松使用基于堆的FSStateBackend
和文件系统的检查点,从而减少序列化开销。
再次假设您使用 Flink,使用 [ContinuousEventTimeTrigger][2]
,您还可以查看当前正在跟踪的独特项目数量。
我建议重新考虑存储系统的选择。使用外部系统比使用本地状态慢得多。Flink 应用程序在本地维护 JVM 堆或 RocksDB(磁盘上(中的状态,并且可以定期将其检查点到持久存储(如 HDFS(。此状态可能会变得非常大(10 TB(,并且仍然可以有效地维护,因为检查点可以增量和异步完成。这比向外部系统发送每条记录的查询要好得多。
如果你仍然喜欢 Redis 或 Cassandra,你可以使用 Flink 的 AsyncIO 运算符发送异步请求,以提高应用程序的吞吐量。