iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >MapReduce如何实现Reduce端重分区Join操作优化
  • 101
分享到

MapReduce如何实现Reduce端重分区Join操作优化

2023-06-02 19:06:42 101人浏览 安东尼
摘要

mapReduce如何实现Reduce端重分区Join操作优化,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、重分区Join操作(Reduce端)本文介绍的第

mapReduce如何实现Reduce端重分区Join操作优化,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

一、重分区Join操作(Reduce端)

本文介绍的第一种方法是最基本的重分区Join操作,该方法允许执行内部和外部Join。开始之前,我们先搞清楚要解决的问题是将大型数据集Join在一起,我们选用的解决方案是Reduce端重分区Join。该方法是一种Reduce端Join实现,利用MapReduce的sortmerge将记录组合在一起,作为单个MapReduce作业实现,可支持N路连接,其中N是要连接的数据集数量。

Map端负责从数据集中读取数据,确定每个Join操作的value,并将该value的key输出,输出key包含在reducer中并将数据集组合在一起以生成最终结果。

单个reducer调用接收map函数Join操作发出的Key对应的所有值,并将数据分N个分区,其中N是要连接的数据集数量。reducer读取连接value的所有输入并将它们分区到内存中,然后跨所有分区执行笛卡尔积,并发出每个Join操作的结果。

MapReduce如何实现Reduce端重分区Join操作优化

图6.10 重分区Join操作的基本MapReduce实现

MapReduce代码要支持这种技术,需要满足以下条件:

  • 支持多个map类,每个map类处理不同的输入数据集,这是通过使用MultipleInputs类完成的。

  • 需要一种方法来标记mapper发出的记录,以便可以与其原点的数据集相关联,本文将使用htuple项目处理MapReduce中的数据。

重分区Join操作的代码如下:

MapReduce如何实现Reduce端重分区Join操作优化

MapReduce如何实现Reduce端重分区Join操作优化

MapReduce如何实现Reduce端重分区Join操作优化

可以使用以下命令运行作业并查看输出:

MapReduce如何实现Reduce端重分区Join操作优化

总结

hadoop捆绑了一个hadoop-datajoin模块,这是一个重分区Join操作框架,包括用于处理多个输入数据集和执行Join操作的管道。上述操作示例及hadoop-datajoin代码是重分区Join的最基本形式,两者都要求在执行笛卡尔积之前将连接key的所有数据加载到内存中,但如果连接key的基数大于可用内存,那么,这种方法就不太适用。下一个技术将着眼解决此问题。

二、优化重分区Join操作

旧版重分区Join操作实现会浪费大量空间,需要将给定key的所有value加载到内存中才能执行多路连接,将较小的数据集加载到内存中才能迭代更大的数据集,沿途执行Join更有效。

我们希望在MapReduce中执行重分区Join,且无需缓存reducer中的所有记录。优化后的重分区Join框架将仅缓存要连接的其中一个数据集,以减少reducer中缓存的数据量。此优化仅缓存来自两个数据集中较小者的记录,以减少缓存所有记录的内存开销,图6.11显示了改进的重分区Join实现。

MapReduce如何实现Reduce端重分区Join操作优化

图6.11 重分区Join操作优化MapReduce实现

该技术与旧版相比存在一定差异,此处使用辅助排序确保来自较小数据集的所有记录在较大数据集的记录之前到达reducer,以此来尽可能减少reducer中要缓存的数据量。此外,mapper会发出需要进行Join操作的用户名元组的key以及标识原始数据集的字段。

以下代码显示了一个新的枚举,显示了用户mapper如何填充元组字段:

MapReduce如何实现Reduce端重分区Join操作优化

MapReduce如何实现Reduce端重分区Join操作优化

需要更新MapReduce驱动程序代码以指示元组中的哪些字段应用于排序、分区和分组:

  • 分区程序应仅基于用户名进行分区,以便用户的所有记录都到达同一个reducer。

  • 排序应使用用户名和数据集指示符,以便首先排序较小的数据集(由于USERS常量小于USER_LOGS常量,导致用户记录在用户登录之前排序)。

  • 分组应对用户进行分组,以便将两个数据集都流式传输到同一个reducer调用:

MapReduce如何实现Reduce端重分区Join操作优化

最后,我们要修改reducer以缓存传入的用户记录,然后将其与用户日志Join:

MapReduce如何实现Reduce端重分区Join操作优化

可以使用以下命令来运行作业并查看输出:

MapReduce如何实现Reduce端重分区Join操作优化

Hive

在执行重分区Join操作时,Hive可支持类似优化。Hive可缓存Join键的所有数据集,然后流式传输大型数据集,使其不需要存储在内存中。假定在查询时,Hive最后指定的数据集最大。想象一下,你有两个名为users和user_logs的表,而user_logs要大得多。要连接这些表,我们需要确保user_logs表被引用为查询中的最后一个:

MapReduce如何实现Reduce端重分区Join操作优化

如果不想重新查询,可以使用STREAMTABLE提示告诉Hive哪个表更大:

MapReduce如何实现Reduce端重分区Join操作优化

总结

此操作实现通过仅缓冲较小数据集的value来改进早期技术,但它仍然存在数据在map和reducer之间的传输问题,这是一个昂贵的网络成本。此外,旧版可以支持N路连接,但是这种实现仅支持双向连接。

三、使用Bloom过滤器来减少混洗数据

如果希望根据某些谓词对数据子集执行Join操作,例如“仅限居住在加利福尼亚地区的用户”。到目前为止,我们还必须在reducer中执行过滤器才可以实现这一目的 ,因为只有一个数据集存放了有关状态的详细信息——用户日志没有该信息。接下来,我将介绍如何在map端使用Bloom过滤器,这会对作业执行时间产生很大影响。我要解决的问题是在重分区Join操作中过滤数据,但要将该过滤器推送到mapper。一个可行的解决方案是使用预处理作业创建Bloom过滤器,然后在重分区作业中加载Bloom过滤器以过滤mapper中的记录。

Bloom过滤器是一种非常有用的随机数据结构,它利用位数组简洁表明集合,并能判断一个元素是否属于该集合。然而,与Java中的HashSet相比,Bloom需要的内存要少得多,因此它们非常适合处理大型数据集。此解决方案有两个步骤,一是运行作业来生成Bloom过滤器,该过滤器将对用户数据进行操作,并由居住在加利福尼亚地区的用户填充;二是在重分区Join操作中使用此Bloom过滤器丢弃不需要的用户,该过程需要Bloom过滤器的原因是用户日志的mapper没有状态的详细信息。

MapReduce如何实现Reduce端重分区Join操作优化

图6.12 在重分区Join中使用Bloom过滤器的两步过程

第1步:创建Bloom过滤器

第一个作业是创建Bloom过滤器,其中包含加利福尼亚州的用户名。mapper生成中间Bloom过滤器,reducer将其组合成一个Bloom过滤器,作业输出是包含序列化Bloom过滤器的Avro文件:

MapReduce如何实现Reduce端重分区Join操作优化

第2步:重分区Join

重分区Join与上文提到的唯一区别是mapper加载第一步中生成的Bloom过滤器,并且在处理map记录时,执行针对Bloom过滤器的元素审查以确定是否应将记录发送给reducer。以下代码显示了两件事:一般化Bloom过滤器加载、抽象mapper以及支持两个Join数据集的子类:

MapReduce如何实现Reduce端重分区Join操作优化

MapReduce如何实现Reduce端重分区Join操作优化

以下命令运行两个作业并转储Join输出:

MapReduce如何实现Reduce端重分区Join操作优化

总结

该技术提出了一种在两个数据集上执行map端过滤的有效方法,以最小化mapper和reducer之间的网络I/O。作为shuffle的一部分,它还减少了mapper和reducer的磁盘溢出数据量。过滤器通常是加速和优化作业最简单有效的方法,重分区Join也同样适用于其他MapReduce作业。

四、reducer端Join操作可能发生数据倾斜

数据倾斜是实际操作中很容易碰到的问题,可能存在两种类型的数据倾斜:

  • 高Join-key基数,其中有一些连接key在一个或两个数据集中具有大量记录,我把这种称之为join-product偏差。

  • 糟糕的散列分区,少数reducer在总记录数中占很大比例,我将此称为散列分区倾斜。

五、加入具有高连接密钥基数的大型数据集

这种技术解决了join-product的倾斜问题,下一个技术检查了散列分区偏差。现在面临的问题是某些连接key是高基数的,这会导致某些reducer在尝试缓存这些key时耗尽内存。我们可以过滤掉这些key并将它们单独连接或将其溢出到reducer中并安排后续作业Join。

如果提前知道了哪些Key是高基数的,则可以将其分成单独的Join作业,如果不确定高基数Key是哪些,则可能需要在reducer中构建智能检测并将其写入副本文件,该文件由后续作业Join,如图6.14所示。

MapReduce如何实现Reduce端重分区Join操作优化

图6.13 提前知道高基数密钥时处理倾斜

MapReduce如何实现Reduce端重分区Join操作优化

图6.14 提前知道高基数密钥处理时的偏差

Hive

Hive支持类似于第二种方法的偏斜缓解策略,运行作业之前可指定以下配置启用:

MapReduce如何实现Reduce端重分区Join操作优化

可以选择设置一些其他配置来控制在高基数key上运行的map端连接:

MapReduce如何实现Reduce端重分区Join操作优化

最后,如果在sql中使用GROUP BY,可能还需要考虑启用以下配置来处理分组数据中的偏差:

MapReduce如何实现Reduce端重分区Join操作优化

总结

此技术假设给定的Join键,只有一个数据集具有高基数出现,因此可缓存较小数据集的map端连接。如果两个数据集都是高基数的,那么将面临一个昂贵的笛卡尔积运算,执行起来会很慢,因为它不适合MapReduce的工作方式(这意味着它本身不可拆分和可并行化)。在这种情况下,我们应该重新检查是否有任何技术(如过滤或投影)可帮助减少执行join所需的时间。

六、处理由散列分区生成的偏差

MapReduce的默认分区程序是一个散列分区程序,接受每个map输出key的散列,并对reducer数量建模,以确定key被发送到哪个reducer。散列分区程序可以很好地用作通用分区程序,但是有些数据集可能会导致散列分区程序因一些不成比例的密钥散列到同一个reducer而使其重载。与大多数reducer相比,这些reducer需要更长时间才能完成。此外,当检查straggler reducer计数器时,会注意到发送给落后者的组数远远高于已完成的其他组。

区分高基数key与散列分区引起的偏差可以使用MapReduce reducer来识别数据倾斜类型。由性能较差的哈希分区器引入的偏差将具有更多的组(唯一密钥)发送到这些reducer,而导致倾斜的高基数密钥可以通过所有reducer中大致相等数量的组来证明,倾斜越多,reducer的记录数量越多。

我们要解决的问题是reducer端连接需要很长时间才能完成,而落后的组需要比大多数reducer更长时间。使用范围分区程序或编写自定义分区程序,将偏移的key集中到一组reducer。此解决方案的目标是省去默认的散列分区程序,并将其替换为可以更好处理数据倾斜的内容,本文提供两个选项可供探索:

  • 使用与Hadoop捆绑在一起的sampler和TotalOrderPartitioner,将散列分区程序替换为范围分区程序。

  • 编写自定义分区程序,将具有数据倾斜的key路由到为倾斜key保留的Reducer。

范围分区法

范围分区根据预定义值分配map输出,其中每个map接收该范围内的所有reducer,这正是TotalOrderPartitioner的工作原理。实际上,TeraSort使用TotalOrderPartitioner在所有Reducer之间均匀分布,以最大限度减少数据倾斜。TotalOrderPartitioner附带采样器,可对输入数据进行采样并将其写入hdfs,然后在分区时由TotalOrderPartitioner使用。

自定义分区法

如果已经知道哪些Key显示数据倾斜,并且该组Key是静态的,则可以编写自定义分区程序以将这些高基数key推送到一组reducer。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网精选频道,感谢您对编程网的支持。

--结束END--

本文标题: MapReduce如何实现Reduce端重分区Join操作优化

本文链接: https://www.lsjlt.com/news/231037.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MapReduce如何实现Reduce端重分区Join操作优化
    MapReduce如何实现Reduce端重分区Join操作优化,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、重分区Join操作(Reduce端)本文介绍的第...
    99+
    2023-06-02
  • laravel如何实现JOIN去重操作
    本篇内容介绍了“laravel如何实现JOIN去重操作”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、背景介绍在Laravel的数据库查询...
    99+
    2023-07-06
  • jquery如何优化分页操作
    这篇文章主要介绍jquery如何优化分页操作,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!创建数据库语句CREATE TABLE `news` ( &n...
    99+
    2024-04-02
  • Pig中的JOIN操作是如何实现的
    在Pig中,JOIN操作是通过使用JOIN关键字来实现的。通过JOIN关键字,可以将两个或多个数据集按照指定的条件连接在一起。 具体...
    99+
    2024-03-07
    Pig
  • C#操作符重载如何实现
    这篇文章主要讲解了“C#操作符重载如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#操作符重载如何实现”吧!C#操作符重载是什么?是指允许用户使用用户定义的类型编写表达式的能力。例如...
    99+
    2023-06-18
  • C++如何实现操作符重载
    这篇文章主要介绍了C++如何实现操作符重载,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在C++中经常会遇到重载运算符的问题,其实运算符重载必须将运算符看做一个函数,分清他的...
    99+
    2023-06-04
  • 麒麟操作系统中的磁盘分区和格式化如何实现
    在麒麟操作系统中,磁盘分区和格式化可以通过以下步骤实现:1. 打开磁盘管理工具:在麒麟操作系统中,可以通过图形界面或命令行方式打开磁...
    99+
    2023-10-12
    麒麟操作系统
  • Python如何实现定积分与二重定积分的操作
    这篇文章给大家分享的是有关Python如何实现定积分与二重定积分的操作的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1.概述最近项目需要使用程序实现数学微积分,最初想用java实现,后来发现可用文档太少,实现比较...
    99+
    2023-06-15
  • MySQL如何实现分表优化
    这篇文章将为大家详细讲解有关MySQL如何实现分表优化,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。   这里的分表逻辑是根据t_group表的user_nam...
    99+
    2024-04-02
  • 如何实现windows10分屏操作
    这篇文章主要为大家展示了“如何实现windows10分屏操作”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何实现windows10分屏操作”这篇文章吧。一、二分屏方法一通过组合快捷键Win +...
    99+
    2023-06-26
  • 如何实现MySQL底层优化:表分区的应用和优势
    如何实现MySQL底层优化:表分区的应用和优势随着大数据时代的到来,数据库的性能需求也越来越高。MySQL作为常用的关系型数据库,为了满足大规模数据存储和高并发访问的需求,提供了表分区的功能。本文将介绍如何实现MySQL底层优化中的表分区,...
    99+
    2023-11-08
    MySQL 优化 分区
  • PHP异步编程实践:如何优化重定向操作的性能?
    随着互联网技术的不断发展,网站的访问量也越来越大,特别是在高并发的情况下,网站的性能问题就显得尤为突出。其中一个常见的性能问题就是重定向操作的性能问题,因为重定向操作需要浏览器重新发送请求,这会导致额外的网络延迟和服务器负担。本文将介绍如...
    99+
    2023-06-20
    异步编程 重定向 开发技术
  • 如何实现JavaScript if分支优化
    今天小编给大家分享一下如何实现JavaScript if分支优化的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。最近在网上冲浪...
    99+
    2023-07-05
  • linux如何实现Vim分屏操作
    这篇文章主要介绍linux如何实现Vim分屏操作,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Vim分屏功能是通过分割窗口来实现的,这是提高工作效率的一大利器。无论我们想同时显示两个文件,或者同时显示一个文件的两个不...
    99+
    2023-06-15
  • PHP如何实现重命名文件操作
    小编给大家分享一下PHP如何实现重命名文件操作,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!示例代码:<php//重命名文件示例if (renam...
    99+
    2023-06-03
  • Python如何实现MySQL客户端操作库
    这篇文章主要介绍了Python如何实现MySQL客户端操作库,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。PyMySQL 是一个纯 Python...
    99+
    2024-04-02
  • 【MySQL】MySQL中如何实现分页操作
    MySQL中的分页操作 一、 背景 什么是分页,就是查询时候数据量太大,一次性返回所有查询结果既耗费网络资源、又降低了查询效率,用户也不可能一下子看完成千上万条数据。所以分页的技术就应运而生。分页可以...
    99+
    2023-09-17
    mysql 数据库 sql
  • Java 如何在 Linux 中实现重定向操作?
    在 Linux 系统中,重定向操作是非常常见的,它可以让我们将程序的输出结果写入到文件中,或者从文件中读取输入数据。在 Java 中,我们同样可以通过代码实现重定向操作,本文将介绍如何在 Linux 中实现 Java 的重定向操作。 一、...
    99+
    2023-10-10
    重定向 linux 对象
  • Java和Linux:如何使用重定向操作优化数组性能?
    数组是Java编程中最常用的数据结构之一,但是在处理大量数据时,数组的性能可能会受到限制。在这种情况下,使用重定向操作可以大大提高程序的性能。本文将介绍如何在Java和Linux中使用重定向操作来优化数组性能。 什么是重定向操作? 在...
    99+
    2023-10-23
    linux 重定向 数组
  • git如何实现修改、删除、重命名操作
    这篇文章给大家分享的是有关git如何实现修改、删除、重命名操作的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Git中修改、删除、重命名操作时最基本的操作,也是最常用的操作。修改远程仓库地址git rem...
    99+
    2023-06-27
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作