Scala 在Spark中使用大量数据帧/数据集/RDD

Scala 在Spark中使用大量数据帧/数据集/RDD,scala,apache-spark,Scala,Apache Spark,好的,我对使用Scala/Spark比较陌生,我想知道是否有一种设计模式可以在流媒体应用程序中使用大量数据帧(几个100k) 在我的示例中,我有一个SparkStreaming应用程序,其消息负载类似于: {"user_id":123, "data":"ABC"} {"user_id":456, "data":"DEF"} {"user_id":123, "data":"GHI"} 因此,当一条用户id:123的消息传入时,我需要使用特定于该用户的SparkSQL拉入一些外部数据,并在本地缓存

好的,我对使用Scala/Spark比较陌生,我想知道是否有一种设计模式可以在流媒体应用程序中使用大量数据帧(几个100k)

在我的示例中,我有一个SparkStreaming应用程序,其消息负载类似于:

{"user_id":123, "data":"ABC"}
{"user_id":456, "data":"DEF"}
{"user_id":123, "data":"GHI"}
因此,当一条用户id:123的消息传入时,我需要使用特定于该用户的SparkSQL拉入一些外部数据,并在本地缓存它,然后执行一些额外的计算,然后将新数据持久保存到数据库中。然后对流外传入的每条消息重复该过程

现在我的问题是,我想缓存为每个用户拉入的数据,然后在每次需要为该用户处理来自流的消息时重用用户数据的缓存副本(如果存在)。我有数百万可能的用户,在任何给定时刻都有大约100K的活动用户,我将通过几个(~50 ish)执行器处理这些数据

我知道缓存数据帧/RDD会从内存中取出LRU,但如果我将每个用户缓存的计算数据存储在映射中,以便在每个执行器上本地快速查找和检索,例如:

Map[id: INT, user_data: DataFrame]
我是否会创建这样一个场景:我保留对旧数据帧的引用,而这些旧数据帧永远不会得到GC'd,因为我有对它们的活动引用,并且最终会耗尽内存

我是否遗漏了一些基本的东西,有更好更有效的方法来实现这一点


谢谢,非常感谢您的帮助

如果用户元数据是静态的,我只需保留一个包含所有用户id和元数据的地图,并将其广播给工作人员即可。这是处理此类小地图时最有效的解决方案。更困难的情况是,这个“地图”需要及时更新。在这种情况下,我会定期将数据加载到rdd中,并将其作为管道的一部分与流数据连续连接

如果用户元数据是静态的,我只需保留一个包含所有用户id和元数据的地图,并将其广播给工作人员即可。这是处理此类小地图时最有效的解决方案。更困难的情况是,这个“地图”需要及时更新。在这种情况下,我会定期将数据加载到rdd中,并将其作为管道的一部分与流数据连续连接

~100K
DataFrames
——这听起来真是个坏主意。更准确地说,使用分布式数据结构来存储小块数据本身就是一个严重的设计错误。这些工具设计用于处理海量数据,而不是作为简单的数据访问对象。如果100K对象具有相同的结构,则应使用一个包含100K项的数据帧。如果它们没有相同的结构,那么您需要更改您的设计,使它们具有相同的结构。~100K
DataFrames
-这听起来是个非常糟糕的主意。更准确地说,使用分布式数据结构来存储小块数据本身就是一个严重的设计错误。这些工具设计用于处理海量数据,而不是作为简单的数据访问对象。如果100K对象具有相同的结构,则应使用一个包含100K项的数据帧。如果它们没有相同的结构,那么您需要更改设计,使它们具有相同的结构。