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中传递,最终会到一个 ...
随机推荐
- UVA136 Ugly Numbers
题意 PDF 分析 用堆和集合维护即可. 时间复杂度\(O(1500 \log n)\) 代码 #include<iostream> #include<cstdio> #inc ...
- jfrog artifactory docker 安装试用
预备环境(docker 安装模式,使用的免费版本): docker-ce (启用镜像加速) 1. 镜像拉取 docker.bintray.io/jfrog/artifactory-oss 2. 启动 ...
- 限制UITextfield的输入字符为50个字符
1.实现UITextfieldDelegate 2.在UITextfield的代理方法中判断添加字符还是删除字符,从而做不同的操作 #pragma mark-UITextfield的代理方法 - (B ...
- (转)WebApi发送HTML表单数据:文件上传与多部分MIME
5.3 Sending HTML Form Data5.3 发送HTML表单数据(2) 本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/282 ...
- (转)Oracle执行字符串
declare v_out ); begin execute immediate 'select p_guid from c_itcomp where rownum = 1 ' into v_out; ...
- VisualGDB:使用VS创建CMake Linux项目
转载地址:点击打开链接 根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 本文介绍如何使用 ...
- JSP搭建
Tomcat7已经发布多时,Tomcat7增加了对Servlet 3.0,JSP 2.2和JSP-EL 2.2的支持.支持web application内存泄露的检测和防护等很多新功能.本片教程主要介 ...
- Android:通过滤镜实现点击图片变暗效果
实现点击图片(ImageView)变暗效果,有一个较简单的方法,就是讲目标图片设置为背景图片(setBackground),再创建一个selector.xml文件,里面放置一张普通状态时的透明图片,一 ...
- 【树莓派】开机自启动脚本方法之一(.Desktop文件)
转载处: 又一个让树莓派开机运行Python脚本的方法 Linux 创建启动器(.Desktop文件) 首先,树莓派使用的是官方推荐的镜像:RASPBIAN: 在树莓派上常常会需要开机自启动pytho ...
- 利用JS 在网页上获取并显示当前日期 星期
下边的HTML代码,可以取出日期与星期 <html><body><h1><script language=JavaScript>var d, s = & ...