Spark可以使用两种方式来读取数据,一种是Socket(套接字)方式,另一种是使用Netty框架,Netty是由JBOSS提供的一个Java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。在Spark中使用Netty方式可以通过配置spark.shuffle.use.netty属性为true来启动。
ReduceTask读取数据时,会通过BlockManager根据BlockId把相关的数据返回给Reduc-eTask。如果使用的是Netty框架,BlockManager会创建ShuffleSender专门用于发送数据。如果ReduceTask所需要的数据恰好在本结点,那就直接去磁盘上读即可,不再通过网络获取,这一点比MapReduce做的要好,MapReduce取数据时,即使数据在本地还是要走一遍网络传输。
Spark的Shuffle过程中的数据都没有经过排序,这一点也要比MapReduce框架节省很多时间。ReduceTask读取过来的数据首先存放到HaskMap中,如果数据量比较小,占用内存空间不会太大,如果数据量较大,那就需要较多内存,当内存不够时,该怎么办?
Spark提供了两种方式,根据spark.shuffle.spill的设置,当内存不够时,直接就失败;如果设置了可以spill(输出)到磁盘,那就把内存中的数据移到磁盘中。在写磁盘前,先把内存中的HashMap排序,并且把内存中缓冲区的数据排序之后和写到磁盘上的文件数据组成一个最小堆,每次从最小堆中读取最小的数据。
Spark对Shuffle操作提供了多个属性,用于控制其中的细节。属性列表如表5-2所示。(www.xing528.com)
表5-2 Shuffle属性列表
至此,Spark中Shuffle的工作机制我们就分析完了,Shuffle作为Spark集群中很重要的一个环节,它的运行状况直接决定了Spark集群运行Spark程序时的性能状况。精通Shuffle的工作机制对于我们在生产环境下解决由于Shuffle状况而导致的问题有很大的帮助。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。