spark源码阅读之network(2)
在上节的解读中发现spark的源码中大量使用netty的buffer部分的api,该节将看到netty核心的一些api,比如channel:
privatestaticclassClientPool{TransportClient[] clients;Object[] locks;publicClientPool(int size){clients =newTransportClient[size];locks =newObject[size];for(int i =0; i < size; i++){locks[i]=newObject();}}
publicTransportClient createClient(String remoteHost,int remotePort)throwsIOException{// Get connection from the connection pool first.// If it is not found or not active, create a new one.finalInetSocketAddress address =newInetSocketAddress(remoteHost, remotePort);// Create the ClientPool if we don't have it yet.ClientPool clientPool = connectionPool.get(address);if(clientPool ==null){connectionPool.putIfAbsent(address,newClientPool(numConnectionsPerPeer));clientPool = connectionPool.get(address);}int clientIndex = rand.nextInt(numConnectionsPerPeer);TransportClient cachedClient = clientPool.clients[clientIndex];if(cachedClient !=null&& cachedClient.isActive()){logger.trace("Returning cached connection to {}: {}", address, cachedClient);return cachedClient;}// If we reach here, we don't have an existing connection open. Let's create a new one.// Multiple threads might race here to create new connections. Keep only one of them active.synchronized(clientPool.locks[clientIndex]){cachedClient = clientPool.clients[clientIndex];if(cachedClient !=null){if(cachedClient.isActive()){logger.trace("Returning cached connection to {}: {}", address, cachedClient);return cachedClient;}else{logger.info("Found inactive connection to {}, creating a new one.", address);}}clientPool.clients[clientIndex]= createClient(address);return clientPool.clients[clientIndex];}}
*/publicTransportClient createUnmanagedClient(String remoteHost,int remotePort)throwsIOException{finalInetSocketAddress address =newInetSocketAddress(remoteHost, remotePort);return createClient(address);}/** Create a completely new {@link TransportClient} to the remote address. */privateTransportClient createClient(InetSocketAddress address)throwsIOException{logger.debug("Creating new connection to "+ address);Bootstrap bootstrap =newBootstrap();bootstrap.group(workerGroup).channel(socketChannelClass)// Disable Nagle's Algorithm since we don't want packets to wait.option(ChannelOption.TCP_NODELAY,true).option(ChannelOption.SO_KEEPALIVE,true).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, conf.connectionTimeoutMs()).option(ChannelOption.ALLOCATOR, pooledAllocator);finalAtomicReference<TransportClient> clientRef =newAtomicReference<TransportClient>();finalAtomicReference<Channel> channelRef =newAtomicReference<Channel>();bootstrap.handler(newChannelInitializer<SocketChannel>(){@Overridepublicvoid initChannel(SocketChannel ch){TransportChannelHandler clientHandler = context.initializePipeline(ch);clientRef.set(clientHandler.getClient());channelRef.set(ch);}});// Connect to the remote serverlong preConnect =System.nanoTime();ChannelFuture cf = bootstrap.connect(address);if(!cf.awaitUninterruptibly(conf.connectionTimeoutMs())){thrownewIOException(String.format("Connecting to %s timed out (%s ms)", address, conf.connectionTimeoutMs()));}elseif(cf.cause()!=null){thrownewIOException(String.format("Failed to connect to %s", address), cf.cause());}TransportClient client = clientRef.get();Channel channel = channelRef.get();assert client !=null:"Channel future completed successfully with null client";// Execute any client bootstraps synchronously before marking the Client as successful.long preBootstrap =System.nanoTime();logger.debug("Connection to {} successful, running bootstraps...", address);try{for(TransportClientBootstrap clientBootstrap : clientBootstraps){clientBootstrap.doBootstrap(client, channel);}}catch(Exception e){// catch non-RuntimeExceptions too as bootstrap may be written in Scalalong bootstrapTimeMs =(System.nanoTime()- preBootstrap)/1000000;logger.error("Exception while bootstrapping client after "+ bootstrapTimeMs +" ms", e);client.close();throwThrowables.propagate(e);}long postBootstrap =System.nanoTime();logger.debug("Successfully created connection to {} after {} ms ({} ms spent in bootstraps)",address,(postBootstrap - preConnect)/1000000,(postBootstrap - preBootstrap)/1000000);return client;}
privatefinalChannel channel;privatefinalTransportResponseHandler handler;@NullableprivateString clientId;
publicvoid fetchChunk(long streamId,finalint chunkIndex,finalChunkReceivedCallback callback){finalString serverAddr =NettyUtils.getRemoteAddress(channel);finallong startTime =System.currentTimeMillis();logger.debug("Sending fetch chunk request {} to {}", chunkIndex, serverAddr);finalStreamChunkId streamChunkId =newStreamChunkId(streamId, chunkIndex);handler.addFetchRequest(streamChunkId, callback);channel.writeAndFlush(newChunkFetchRequest(streamChunkId)).addListener(newChannelFutureListener(){@Overridepublicvoid operationComplete(ChannelFuture future)throwsException{if(future.isSuccess()){long timeTaken =System.currentTimeMillis()- startTime;logger.trace("Sending request {} to {} took {} ms", streamChunkId, serverAddr,timeTaken);}else{String errorMsg =String.format("Failed to send request %s to %s: %s", streamChunkId,serverAddr, future.cause());logger.error(errorMsg, future.cause());handler.removeFetchRequest(streamChunkId);channel.close();try{callback.onFailure(chunkIndex,newIOException(errorMsg, future.cause()));}catch(Exception e){logger.error("Uncaught exception in RPC response callback handler!", e);}}}});}
publicvoid stream(finalString streamId,finalStreamCallback callback){finalString serverAddr =NettyUtils.getRemoteAddress(channel);finallong startTime =System.currentTimeMillis();logger.debug("Sending stream request for {} to {}", streamId, serverAddr);// Need to synchronize here so that the callback is added to the queue and the RPC is// written to the socket atomically, so that callbacks are called in the right order// when responses arrive.synchronized(this){handler.addStreamCallback(callback);channel.writeAndFlush(newStreamRequest(streamId)).addListener(newChannelFutureListener(){@Overridepublicvoid operationComplete(ChannelFuture future)throwsException{if(future.isSuccess()){long timeTaken =System.currentTimeMillis()- startTime;logger.trace("Sending request for {} to {} took {} ms", streamId, serverAddr,timeTaken);}else{String errorMsg =String.format("Failed to send request for %s to %s: %s", streamId,serverAddr, future.cause());logger.error(errorMsg, future.cause());channel.close();try{callback.onFailure(streamId,newIOException(errorMsg, future.cause()));}catch(Exception e){logger.error("Uncaught exception in RPC response callback handler!", e);}}}});}}
publicbyte[] sendRpcSync(byte[] message,long timeoutMs){finalSettableFuture<byte[]> result =SettableFuture.create();sendRpc(message,newRpcResponseCallback(){@Overridepublicvoid onSuccess(byte[] response){result.set(response);}@Overridepublicvoid onFailure(Throwable e){result.setException(e);}});try{return result.get(timeoutMs,TimeUnit.MILLISECONDS);}catch(ExecutionException e){throwThrowables.propagate(e.getCause());}catch(Exception e){throwThrowables.propagate(e);}}
spark源码阅读之network(2)的更多相关文章
- spark源码阅读之network(1)
spark将在1.6中替换掉akka,而采用netty实现整个集群的rpc的框架,netty的内存管理和NIO支持将有效的提高spark集群的网络传输能力,为了看懂这块代码,在网上找了两本书看< ...
- spark源码阅读之network(3)
TransportContext用来创建TransportServer和TransportclientFactory,同时使用TransportChannelHandler用来配置channel的pi ...
- Spark源码阅读之存储体系--存储体系概述与shuffle服务
一.概述 根据<深入理解Spark:核心思想与源码分析>一书,结合最新的spark源代码master分支进行源码阅读,对新版本的代码加上自己的一些理解,如有错误,希望指出. 1.块管理器B ...
- win7+idea+maven搭建spark源码阅读环境
1.参考. 利用IDEA工具编译Spark源码(1.60~2.20) https://blog.csdn.net/He11o_Liu/article/details/78739699 Maven编译打 ...
- spark源码阅读
根据spark2.2的编译顺序来确定源码阅读顺序,只阅读核心的基本部分. 1.common目录 ①Tags②Sketch③Networking④Shuffle Streaming Service⑤Un ...
- emacs+ensime+sbt打造spark源码阅读环境
欢迎转载,转载请注明出处,徽沪一郎. 概述 Scala越来越流行, Spark也愈来愈红火, 对spark的代码进行走读也成了一个很普遍的行为.不巧的是,当前java社区中很流行的ide如eclips ...
- spark源码阅读---Utils.getCallSite
1 作用 当该方法在spark内部代码中调用时,会返回当前调用spark代码的用户类的名称,以及其所调用的spark方法.所谓用户类,就是我们这些用户使用spark api的类. 2 内部实现 2.1 ...
- spark源码阅读--SparkContext启动过程
##SparkContext启动过程 基于spark 2.1.0 scala 2.11.8 spark源码的体系结构实在是很庞大,从使用spark-submit脚本提交任务,到向yarn申请容器,启 ...
- Spark源码阅读(1): Stage划分
Spark中job由action动作生成,那么stage是如何划分的呢?一般的解答是根据宽窄依赖划分.那么我们深入源码看看吧 一个action 例如count,会在多次runJob中传递,最终会到一个 ...
随机推荐
- iis部署网页时应该避免的特殊端口
1 tcpmux 7 echo 9 discard 11 systat 13 daytime 15 netstat 17 qotd 19 chargen 20 ftp data 21 ftp cont ...
- PADS Router 虚焊盘显示怎么办?
PADS Router 虚焊盘显示怎么办? 群里朋友有问不知道按了什么键,焊盘显示成以下这种,怎么还原? 解答比较简单,按个 T 就可以. 这个显示是有好处的,特别是焊盘有过孔时一眼就看到.
- 关于Apache Phoenix和Cloudera结合
1. 安装: phoenix的官网最新版4.13.2是有parcle版本的,并不需要从cloudera的labs(实验室)中下载.安装完成后,可以运行一下phoenix的shell来简单验证一下:/o ...
- Linux 应用层open调用驱动层open过程
内核版本:3.0.8 open.close.read.write.ioctl等等都是类似. ====================================================== ...
- fragment在水平/垂直时的应用
直接看代码 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedIns ...
- Linux下查询一个包是32位还是64位
Linux下查询一个包是32位还是64位 [root@localhost ~]# rpm -qa --queryformat %-{name}-%{version}-%{release}-%{arc ...
- java从键盘输入若干数,求其最大值,最小值,平均值。等等
总结:有一定基础的人,应该发现第一个程序可以运行,其实它有个致命的错误.有谁能一眼看出来呢?第二个程序是对的. 这个题目求最大值,最小值,平均值我不会求,不知道这个if判断放在类的外面还是main函数 ...
- MySQL 优化器
(system@127.0.0.1:3306) [trunk]> show variables like '%performance_sch%';+----------------------- ...
- 32位机,CPU是如何利用段寄存器寻址的
转自:http://blog.sina.com.cn/s/blog_640531380100xa15.html 32位cpu 地址线扩展成了32位,这和数据线的宽度是一致的.因此,在32位机里其实并不 ...
- Spring Cloud与分布式系统
本文不是讲解如何使用spring Cloud的教程,而是探讨Spring Cloud是什么,以及它诞生的背景和意义. 背景 2008年以后,国内互联网行业飞速发展,我们对软件系统的需求已经不再是过去” ...