Spark 颠覆 MapReduce 保持的排序记录
在过去几年,Apache Spark的採用以惊人的速度添加着,通常被作为MapReduce后继,能够支撑数千节点规模的集群部署。
在内存中数 据处理上,Apache Spark比MapReduce更加高效已经得到广泛认识;可是当数据量远超内存容量时,我们也听到了一些机构在Spark使用 上的困扰。
因此,我们与Spark社区一起。投入了大量的精力做Spark稳定性、扩展性、性能等方面的提升。既然Spark在GB或TB级别数据上执行 良好。那么它在PB级数据上也应当相同如此。
为了评估这些工作,近期我们与AWS一起完毕了一个Sort Benchmark(Daytona Gray类别)測试,一个考量系统排序 100TB数据(万亿条记录)速度的行业基准測试。
在此之前,这项基准測试的世界记录保持者是雅虎,使用2100节点的Hadoop MapReduce 集群在72分钟内完毕计算。
而依据測试结果得知。在使用了206个EC2节点的情况下,Spark将排序用时缩短到了23分钟。这意味着在使用十分之中的一个计 算资源的情况下。同样数据的排序上。Spark比MapReduce快3倍!
此外,在没有官方PB排序对照的情况下。我们首次将Spark推到了1PB数据(十万亿条记录)的排序。这个測试的结果是,在使用190个节点的情 况下,工作负载在短短不到4小时内完毕,相同远超雅虎之前使用3800台主机耗时16个小时的记录。同一时候,据我们所知,这也是公用云环境首次完毕的PB级 排序測试。
|
Hadoop World Record | Spark 100 TB | Spark 1 PB |
Data Size | 102.5 TB | 100 TB | 1000 TB |
Elapsed Time | 72 mins | 23 mins | 234 mins |
# Nodes | 2100 | 206 | 190 |
# Cores | 50400 | 6592 | 6080 |
# Reducers | 10,000 | 29,000 | 250,000 |
|
1.42 TB/min | 4.27 TB/min | 4.27 TB/min |
Rate/node | 0.67 GB/min | 20.7 GB/min | 22.5 GB/min |
Sort Benchmark Daytona Rules | Yes | Yes | No |
Environment | dedicated data center | EC2 (i2.8xlarge) | EC2 (i2.8xlarge) |
为什么会选择排序?
排序的核心是shuffle操作,数据的传输会横跨集群中全部主机。
Shuffle基本支持了全部的分布式数据处理负载。
举个样例,在一个 连接了两个不同数据源的SQL查询中。会使用shuffle将须要连接数据的元组移动到同一台主机;同一时候,类似ALS等协同过滤算法相同须要依赖 shuffle在网络中发送用户或产品的评级(ratings)和权重(weights)。
大部分数据管道開始时都会有大量的原始数据,可是在管道处理过程中,随着越来越多不相干数据被过滤。或者中间数据被更简洁的表示。数据量必 然会降低。
在100TB原始数据的查询上。网络上shuffle的数据可能仅仅有100TB的一小部分,这样的模式也体如今MapReduce的命名。
然而,排序却是很有挑战的。由于数据管道中的数据量并不会降低。假设对100TB的原始数据进行排序,网络中shuffle的数据必定也 是100TB。同一时候。在Daytona类型的基准測试中,为了容错,无论是输入数据还是输出数据都须要做备份。实际上。在100TB的数据排序上。我们可 能会产生500TB的磁盘I/O及200TB的网络I/O。
因此,基于上述原因。当我们寻找Spark的測量标准和提升办法时,排序这个最苛刻的工作负载成为了对照的不二之选。
产生如此结果的技术实现
在超大规模工作负载上。我们投入了大量的精力来提升Spark。从细节上看。与这个基准測试高度相关的工作主要有3个:
首先及最关键的,在Spark 1.1中我们引入了一个全新的shuffle实现,也就是基于排序的 shuffle(SPARK2045)。在此之前。Spark做的是基于哈希的shuffle实现,它须要在内存中同一时候保持P(reduce的切割数 量)个缓冲区。而在基于排序的shuffle下,不论什么时候系统仅仅使用一个缓冲区。这个操作将显著地降低内存开销,因此同一个场景下能够支撑数十万任务(我 们在PB排序中使用了2.5万个任务)。
其次,我们修订了Spark的网络模型。通过JNI(SPARK2468)使用基于Netty的Epoll本地port传输。
同一时候,新的模型还拥有了独立的内存池,绕过了JVM的内存分配器。从而降低垃圾回收造成的影响。
最后但相同重要的是。我们建立了一个外部shuffle服务(SPARK3796)。它与Spark本身的运行器全然解耦。这个新的服务基于上文所述的网络模型,同一时候,在Spark本身的运行器忙于GC处理时,它仍然能够保证shuffle文件处理的继续运行。
通过这三项改变,我们的Spark集群在map阶段单 节点能够支撑每秒3GB的IO吞吐,在reduce阶段单节点能够支撑1.1GB,从而榨干这些机器间10Gbps的网络带宽。
很多其它的技术细节
TimSort:在Spark 1.1版本号中。我们将默认排序算法从 quicksort转换到 TimSort,它是合并排 序和嵌入排序的一个衍生。在大部分现实世界数据集中,TimSort比quicksort更加高效,在部分排序数据中表现则更为优秀。
无论在map阶段还 是Reduce阶段,我们都使用了TimSort。
缓存位置的利用:在排序基准測试中,每条记录的大小都是100字节,而被排序的键是前10个字节。在排序项目的 性能分析阶 段,我们注意到缓存命中率不如人意。由于每次比較都须要进行一个随机的对象指针查询。为此。我们又一次设计了记录在内存的布局,用16字节长度(两个长整 形)的记录来表示每条记录。在这里,前10个字节代表了排序的键,后4个字节则代表了记录的位置(鉴于字节顺序和符号。这点并不easy发现)。这样一来,每 个比較仅仅须要做一次缓存查询,并且它们都是连续的。从而避免了随机的内存查询。
使用TimSort和新的布局方式来利用缓存命中,排序所占用的CPU时间足足降低了5倍。
大规模下的容错机制:在大规模下,很多问题都会暴露。在这个測试过程中。我们看到由于网络连通问题出现的节点丢失,Linux内核自旋,以及由于内存碎片整理造成的节点停滞。幸运的是,Spark的容错机制很好,而且顺利的进行故障恢复。
AWS的能量:如上文所述,我们使用了206个i2.8xlarge实例来跑这个I/O密集測试。通过SSD。 这些实例交付了很高的I/O吞吐量。
我们将这些实例放到一个VPC放置组中,从而通过单SR-IOV增强网络性能,以获得高性能(10Gbps)、低延 时和低抖动。
Spark仅仅能在内存中大放异彩?
这个误解一直环绕着Spark,特别是刚进入社区中的新人更是如此觉得。不错。Spark由于内存计算的高性能闻名。然而Spark的设计 初衷和理念却是一个通用的大数据处理平台——无论是使用内存还是磁盘。在数据无法全然放入内存时。基本上全部的Spark运算符都会做一些额外的处理。通 俗来说,Spark运算符是MapReduce的超集。
如本次測试所看到的,Spark能够胜任集群内存大小N倍的数据集处理。
总结
击败Hadoop MapReduce集群创造的大规模数据处理记录不仅是对我们工作的一个证明,也是对Spark承诺的一个验证——在不论什么数据体积,Spark在性能和扩展性上都更具优势。同一时候。我们也希望在用户使用过程中,Spark能够带来时间和开销上的双节省。
Spark 颠覆 MapReduce 保持的排序记录的更多相关文章
- Spark 与 MapReduce的区别
学习参考自 http://spark-internals.books.yourtion.com/markdown/4-shuffleDetails.html 1. Shuffle read 边 fe ...
- (转)MapReduce二次排序
一.概述 MapReduce框架对处理结果的输出会根据key值进行默认的排序,这个默认排序可以满足一部分需求,但是也是十分有限的.在我们实际的需求当中,往往有要对reduce输出结果进行二次排序的需求 ...
- mapreduce 实现数子排序
设计思路: 使用mapreduce的默认排序,按照key值进行排序的,如果key为封装int的IntWritable类型,那么MapReduce按照数字大小对key排序,如果key为封装为String ...
- 详细讲解MapReduce二次排序过程
我在15年处理大数据的时候还都是使用MapReduce, 随着时间的推移, 计算工具的发展, 内存越来越便宜, 计算方式也有了极大的改变. 到现在再做大数据开发的好多同学都是直接使用spark, hi ...
- spark和 mapreduce的比较
网上查阅一些资料,收集整理如下: 1. 通用性 spark更加通用,spark提供了transformation和action这两大类的多个功能api,另外还有流式处理sparkstreaming模块 ...
- Hadoop学习笔记—11.MapReduce中的排序和分组
一.写在之前的 1.1 回顾Map阶段四大步骤 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出,在Step1.4也就是第四步中,需要对不同分区中的数据进行排 ...
- Hadoop学习笔记: MapReduce二次排序
本文给出一个实现MapReduce二次排序的例子 package SortTest; import java.io.DataInput; import java.io.DataOutput; impo ...
- Alluxio增强Spark和MapReduce存储能力
Alluxio的前身为Tachyon.Alluxio是一个基于内存的分布式文件系统:Alluxio以内存为中心设计,他处在诸如Amazon S3. Apache HDFS 或 OpenStack Sw ...
- MongoDB(六):选择字段、限制记录数、排序记录
1. 选择字段 在MongoDB中,选择字段又叫投影,表示仅选择所需要字段的数据,而不是选择整个文档字段的数据.如果某个文档有5个字段,但只要显示3个字段,那么就只选择3个字段吧,这样做是非常有好处的 ...
随机推荐
- day02_12/12/2016_bean的实例化之构造器方式
- 利用python去除红章
近期接的一个需求需要去除图片的红章,用到了PIL库. from PIL import Image,ImageEnhanceimport os#f="5-12 - 0001.tif" ...
- 331 Verify Preorder Serialization of a Binary Tree 验证二叉树的前序序列化
序列化二叉树的一种方法是使用前序遍历.当我们遇到一个非空节点时,我们可以记录这个节点的值.如果它是一个空节点,我们可以使用一个标记值,例如 #. _9_ / \ 3 2 ...
- [转]java处理高并发高负载类网站的优化方法
本文转自:http://www.cnblogs.com/pengyongjun/p/3406210.html java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,ja ...
- Java Controller下兼容xls和xlsx且可识别合并单元格的excel导入功能
1.工具类,读取单元格数据的时候,如果当前单元格是合并单元格,会自动读取合并单元格的值 package com.shjh.core.util; import java.io.IOException; ...
- mysql索引初认识
mysql> use mysql; Database changed mysql> show index from user; +-------+------------+-------- ...
- android ormlite 清空表
delete from TableName; //清空数据 update sqlite_sequence SET seq = where name ='TableName';//自增长ID为0 Sam ...
- Android项目实战_手机安全卫士拦截骚扰
###1.骚扰拦截需求分析1.界面1.1 黑名单列表界面1.2 添加黑名单界面2.功能2.1 黑名单的添加.删除2.2 拦截电话2.3 拦截短信 ###2.黑名单数据库的创建1.分析需要的字段id 主 ...
- dubbo之并发控制
并发控制 配置样例 样例 1 限制 com.foo.BarService 的每个方法,服务器端并发执行(或占用线程池线程数)不能超过 10 个: <dubbo:service interface ...
- Android 动态设置 layout_centerInParent
RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutPa ...