alluxio源码解析-netty部分(2)
netty简介
netty作为alluxio中重要的通讯组件
在常见的客户端上传,下载中,都会有netty的参与

关于这个图,可以看上篇文章的介绍:
https://www.cnblogs.com/victor2302/p/10490253.html
- 解耦ufs和worker缓存的功能
- 解耦 BlockHandler和 ShortCircuitBlockHandler
- 解耦异步上传,同步上传
- 高性能传输
netty客户端部分:
1.固定的处理器:alluxio.network.netty.NettyClient
final Bootstrap boot = new Bootstrap(); boot.group(WORKER_GROUP)
.channel(NettyUtils.getClientChannelClass(!(address instanceof InetSocketAddress)));
boot.option(ChannelOption.SO_KEEPALIVE, true);
boot.option(ChannelOption.TCP_NODELAY, true);
boot.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
if (NettyUtils.USER_CHANNEL_TYPE == ChannelType.EPOLL) {
boot.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
} // After 10 missed heartbeat attempts and no write activity, the server will close the channel.
final long timeoutMs = Configuration.getMs(PropertyKey.NETWORK_NETTY_HEARTBEAT_TIMEOUT_MS);
final long heartbeatPeriodMs = Math.max(timeoutMs / 10, 1);
boot.handler(new ChannelInitializer<Channel>() {
@Override
public void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(RPCMessage.createFrameDecoder());
pipeline.addLast(ENCODER);
pipeline.addLast(DECODER);
pipeline.addLast(new IdleStateHandler(0, heartbeatPeriodMs, 0, TimeUnit.MILLISECONDS));
pipeline.addLast(new IdleWriteHandler());
}
});
2.临时的处理器:针对通用response注册回调(ShortCircuitBlockHandler 调用)
public static ProtoMessage call(final NettyRPCContext context, ProtoMessage request)
throws IOException {
Channel channel = Preconditions.checkNotNull(context.getChannel());
final Promise<ProtoMessage> promise = channel.eventLoop().newPromise();
channel.pipeline().addLast(new RPCHandler(promise));
channel.writeAndFlush(new RPCProtoMessage(request)).addListener((ChannelFuture future) -> {
if (future.cause() != null) {
future.channel().close();
promise.tryFailure(future.cause());
}
});
ProtoMessage message;
try {
message = promise.get(context.getTimeoutMs(), TimeUnit.MILLISECONDS);
} catch (ExecutionException | TimeoutException e) {
CommonUtils.closeChannel(channel);
throw new IOException(e);
} catch (InterruptedException e) {
CommonUtils.closeChannel(channel);
throw new RuntimeException(e);
} finally {
if (channel.isOpen()) {
channel.pipeline().removeLast();
}
}
if (message.isResponse()) {
CommonUtils.unwrapResponseFrom(message.asResponse(), context.getChannel());
}
return message;
}
3.临时的处理器:针对读写操作注册回调(BlockHandler)
private NettyPacketReader(FileSystemContext context, WorkerNetAddress address,
Protocol.ReadRequest readRequest) throws IOException {
mContext = context;
mAddress = address;
mPosToRead = readRequest.getOffset();
mReadRequest = readRequest; mChannel = mContext.acquireNettyChannel(address);
mChannel.pipeline().addLast(new PacketReadHandler());
mChannel.writeAndFlush(new RPCProtoMessage(new ProtoMessage(mReadRequest)))
.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} private NettyPacketWriter(FileSystemContext context, final WorkerNetAddress address, long id,
long length, long packetSize, Protocol.RequestType type, OutStreamOptions options,
Channel channel) {
mContext = context;
mAddress = address;
mLength = length;
Protocol.WriteRequest.Builder builder =
Protocol.WriteRequest.newBuilder().setId(id).setTier(options.getWriteTier()).setType(type);
if (type == Protocol.RequestType.UFS_FILE) {
Protocol.CreateUfsFileOptions ufsFileOptions =
Protocol.CreateUfsFileOptions.newBuilder().setUfsPath(options.getUfsPath())
.setOwner(options.getOwner()).setGroup(options.getGroup())
.setMode(options.getMode().toShort()).setMountId(options.getMountId()).build();
builder.setCreateUfsFileOptions(ufsFileOptions);
}
mPartialRequest = builder.buildPartial();
mPacketSize = packetSize;
mChannel = channel;
mChannel.pipeline().addLast(new PacketWriteResponseHandler());
}
netty服务端:
注册处理器列表:
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
final long timeoutMs = Configuration.getMs(PropertyKey.NETWORK_NETTY_HEARTBEAT_TIMEOUT_MS);
// Decoders & Encoders
pipeline.addLast("frameDecoder", RPCMessage.createFrameDecoder());
pipeline.addLast("RPCMessageDecoder", new RPCMessageDecoder());
pipeline.addLast("RPCMessageEncoder", new RPCMessageEncoder());
// Idle Event Handlers
pipeline.addLast("idleEventHandler", new IdleStateHandler(timeoutMs, 0, 0,
TimeUnit.MILLISECONDS));
pipeline.addLast("idleReadHandler", new IdleReadHandler());
pipeline.addLast("heartbeatHandler", new HeartbeatHandler());
// Block Handlers
pipeline.addLast("blockReadHandler",
new BlockReadHandler(NettyExecutors.BLOCK_READER_EXECUTOR,
mWorkerProcess.getWorker(BlockWorker.class), mFileTransferType));
pipeline.addLast("blockWriteHandler", new BlockWriteHandler(
NettyExecutors.BLOCK_WRITER_EXECUTOR, mWorkerProcess.getWorker(BlockWorker.class),
mWorkerProcess.getUfsManager()));
pipeline.addLast("shortCircuitBlockReadHandler",
new ShortCircuitBlockReadHandler(NettyExecutors.RPC_EXECUTOR,
mWorkerProcess.getWorker(BlockWorker.class)));
pipeline.addLast("shortCircuitBlockWriteHandler",
new ShortCircuitBlockWriteHandler(NettyExecutors.RPC_EXECUTOR,
mWorkerProcess.getWorker(BlockWorker.class)));
pipeline.addLast("asyncCacheHandler", new AsyncCacheHandler(mRequestManager));
// UFS Handlers
pipeline.addLast("ufsFileWriteHandler", new UfsFileWriteHandler(
NettyExecutors.FILE_WRITER_EXECUTOR, mWorkerProcess.getUfsManager()));
// Unsupported Message Handler
pipeline.addLast("unsupportedMessageHandler", new UnsupportedMessageHandler());
}
写入或者读取配置
alluxio.client.file.options.CreateFileOptions是FileSystem类createFile的第二个参数,可以选定不同的写入策略
例如:
- MUST_CACHE(只写入Alluxio,必须存储在Alluxio中)
- CACHE_THROUGH(尝试缓存,同步写入到UnderFS)
- THROUGH(无缓存,同步写入到UnderFS)
- ASYNC_THROUGH(异步写入到UnderFS,实现特性)
FileOutStream createFile(AlluxioURI path, CreateFileOptions options)
throws FileAlreadyExistsException, InvalidPathException, IOException, AlluxioException;
而这种写入选项,就是通过在传递netty message时,设置不同的标识,然后在netty中分派到不同的pipeline节点,处理各自的特性的
代码实例:
是否需要写入到ufs,则在UfsFileWriteHandler的acceptMessage方法中进行判断的
alluxio.worker.netty.UfsFileWriteHandler#acceptMessage
protected boolean acceptMessage(Object object) {
if (!super.acceptMessage(object)) {
return false;
}
Protocol.WriteRequest request = ((RPCProtoMessage) object).getMessage().asWriteRequest();
return request.getType() == Protocol.RequestType.UFS_FILE;
}
alluxio源码解析-netty部分(2)的更多相关文章
- Netty 源码解析: Netty 的 ChannelPipeline
ChannelPipeline和Inbound.Outbound 我想很多读者应该或多或少都有 Netty 中 pipeline 的概念.前面我们说了,使用 Netty 的时候,我们通 ...
- alluxio源码解析-rpc调用概述-client和worker之间的block模块的通讯架构(netty版本)(3)
(1.8版本)client和worker之间的block模块的通讯架构 block作为alluxio文件读取或者存储的最小基本单位,都是通过BlockOutStream和BlockInputtream ...
- alluxio源码解析-层次化存储(4)
层次化存储-特性介绍: https://www.alluxio.org/docs/1.6/cn/Tiered-Storage-on-Alluxio.html 引入分层存储后,Alluxio管理的数据块 ...
- alluxio源码解析-rpc调用概述(1)
alluxio中几种角色以及角色之间的rpc调用: 作为分布式架构的文件缓存系统,rpc调用必不可少 client作为客户端 master提供thrift rpc的服务,管理以下信息: block信息 ...
- Netty 4源码解析:请求处理
Netty 4源码解析:请求处理 通过之前<Netty 4源码解析:服务端启动>的分析,我们知道在最前端"扛压力"的是NioEventLoop.run()方法.我们指定 ...
- Netty 4源码解析:服务端启动
Netty 4源码解析:服务端启动 1.基础知识 1.1 Netty 4示例 因为Netty 5还处于测试版,所以选择了目前比较稳定的Netty 4作为学习对象.而且5.0的变化也不像4.0这么大,好 ...
- netty服务端启动--ServerBootstrap源码解析
netty服务端启动--ServerBootstrap源码解析 前面的第一篇文章中,我以spark中的netty客户端的创建为切入点,分析了netty的客户端引导类Bootstrap的参数设置以及启动 ...
- Netty源码解析—客户端启动
Netty源码解析-客户端启动 Bootstrap示例 public final class EchoClient { static final boolean SSL = System.getPro ...
- Netty源码解析---服务端启动
Netty源码解析---服务端启动 一个简单的服务端代码: public class SimpleServer { public static void main(String[] args) { N ...
随机推荐
- HDU 5510:Bazinga(暴力KMP)
http://acm.hdu.edu.cn/showproblem.php?pid=5510 Bazinga Problem Description Ladies and gentlemen, p ...
- HashMap源码分析(一):JDK源码分析系列
正文开始 注:JDK版本为1.8 HashMap1.8和1.8之前的源码差别很大 目录 简介 数据结构 类结构 属性 构造方法 增加 删除 修改 总结 1.HashMap简介 HashMap基于哈希表 ...
- PLC_SIM 出现I/O访问错误-技术论坛-工业支持中心-西门子中国
PLC_SIM 作为SIEMENS S7-300/400 系列PLC 的仿真软件,在使用时需要有些注意事项,毕竟任何的仿真软件和真正的设备还是有一定差异的,由此而产生的误会经常会令很多客户摸不着头脑, ...
- 数字IC前后端设计中的时序收敛(二)--Setup违反的修复方法
本文转自:自己的微信公众号<数字集成电路设计及EDA教程> 里面主要讲解数字IC前端.后端.DFT.低功耗设计以及验证等相关知识,并且讲解了其中用到的各种EDA工具的教程. 考虑到微信公众 ...
- 网络下载器 Pan Download v2.0.5 Lite 绿色便携版
下载地址:点我 基本介绍 PanDownload最新版是一款能够快速下载百度网盘内资源的强大工具.PanDownload最新版能够无限速高速下载,满速下载百度云盘里的各种资源.而且PanDownloa ...
- 阿里云体验:安装jdk
在阿里云的linux服务器上默认是没有安装java环境的,需要自己安装.查了许多资料,发现这篇文章简洁易用.http://www.cnblogs.com/cloudwind/archive/2012/ ...
- CDQZ集训DAY8 日记
又一次翻车…… 先提一句昨晚的事.昨天晚上身后一帮成都七中的人用十分戏谑的语气交出了达哥的名字,看着NOI2017的获奖名单,如果他们真的是在嘲笑的话,真的挺想上去干他们一顿的…… 上午考试第一题一脸 ...
- redux、react-redux、redux-thunk、redux-saga使用及dva对比
一.redux使用 Redux的核心概念其实很简单:将需要修改的state都存入到store里,发起一个action用来描述发生了什么,用reducers描述action如何改变state tree ...
- 个人永久性免费-Excel催化剂功能第102波-批量上传本地图片至网络图床(外网可访问)
自我突破,在100+功能后,再做有质量的功能,非常不易,相对录制视频这些轻松活,还是按捺不住去写代码,此功能虽小,但功课也做了不少,希望对真正有需要的群体带来一些惊喜. 背景介绍 图床的使用,一般是写 ...
- 将Ueditor文件上传至OSS
前人已经将ueditor集成了oss,本次是作为记录 1:点击到下载页面 下载并按照文档安装 2:将 com.zip(在UEditor-for-aliyun-OSS-master\ueditor\sr ...