在回顾这个问题Spark groupByKey alternative时,我发现我有类似的需求,但是在更大的数据集上。好消息是我的每组数据都适合减速机一侧的内存。
我需要对每个组的数据进行一些处理,然后写出结果。可能有很多分组值。
输入(从该问题复制):
{"key1": "1", "key1": "2", "key1": "3", "key2": "55", "key2": "66"}
输出(从该问题复制):
{"key1": ["1","2","3"], "key2": ["55","66"]}
由于这是非常低效并且迫使数据大量移动,我在想是否可以使用spark框架仅将不同的键映射到不同的reducer,并让reducer端来源数据(来自数据库或其他)并且做它的计算。
在这种情况下,我将使用Spark来分散工作负载而不是其他任何东西。这是一种有用的方法吗?还有其他选择吗?
答案 0 :(得分:2)
这实际上取决于数据源;在很多方面,groupBy逻辑只是在构建索引时或在查询时执行与关系数据库相同的工作。
在spark和hadoop中记录完全混乱的原因是通常这些系统用于处理数据在预处理中不能很好地组织的情况,因为数据太大或者因为它以未分类的形式(例如来自许多不同服务器源的日志文件)到达,而这些形式的访问频率不足以证明连续预处理的合理性。
因此,一般情况下,如果源数据已经由您需要的分组有效组织,或者因为分组键是数据库源中的主键,或者它们已经在源文件中以这种方式分组,那么通过仅拉入reducers中的记录值,确实可以做得更好,因为您的存储格式已经有效地执行了shuffle操作。
但是,如果数据尚未被分组键编入索引,或者它分散在未分类的文件中,那么尝试通过reducers中的键提取数据总体上效率低下,因为每次尝试获取时都是如此单个密钥,底层存储层或读取器的所有数据都必须扫描可能包含这些密钥的完整数据集,从而有效地将数据访问次数乘以您拥有的密钥数。
即使数据有索引,如果记录值需要额外的磁盘来获取它,那么仅仅因为顺序磁盘访问可以获得数量级的顺序,支付额外数据shuffle的成本仍然是值得的。比随机访问更高的吞吐量。
主要的一点是,数据随机播放已经过优化,可以将您的数据组织成或多或少的一次通过,而按键过滤是多次通过,除非有效索引。因此,随机成本是源存储层中成本的折衷。