HDFS的读写限流方案
2017-11-16 09:40
211 查看
我们的集群有的时候一跑几个大的任务,就会把机房网络带宽瞬间打满,导致线上部分服务抖动.所以我们就想到了在HDFS对普通读写的限流.所以说,本文可以实质上说是一篇总结报告,阐述了方案的设想,实现以及结果.
在hadoop自身内部,就有一些限流操作:
1、Blancer平衡数据限流
2、FsImage镜像文件上传下载数据传输流
3、VolumeScanner: 磁盘扫描的数据读操作
一 DataTransderThrottler
对数据传输限制流量的一个类,他所指定的带宽大小或者速率被多个线程共享。
他的核心思想就是:通过单位时间内限制的指定字节数的方式来控制平均传输速度。比如如果发现IO传输速度过快,超过规定时间内的带宽限定字节数,则会进行等待操作,等待下一个允许带宽传输的周期到来
//设置一个期间或者周期,比如5s内只允许发送1024字节,这里的周期就是5s
private final
long period; //period over which
bw is imposed
private final
long periodExtension;
// Max period over which bw accumulates.
//周期内能够被发送的字节数量,1024字节就是允许发送的字节数
private long
bytesPerPeriod; // total number of bytes can be sent ineach period
//当前周期起始点
private long
curPeriodStart; // current period starting time
//当前能够发送的剩余字节数,比如周期前2s发送了500字节,那么还剩余524字节
private long
curReserve; // remaining bytes can be sent in theperiod
//和上面相对应,这个是已经使用到字节数,前2s发送了500字节,那么这500字节就是已经使用了的字节数
private
long bytesAlreadyUsed;
public synchronized
void throttle(long
numOfBytes, Canceler
canceler) {
if ( numOfBytes <=
0 ) {
return;
}
//当前的可传输的字节数减去当前发送/接收字节数
curReserve -= numOfBytes;
//当前字节使用量
bytesAlreadyUsed += numOfBytes;
while (curReserve <=
0) {
//如果设置了canceler对象,则不会进行限流操作
if (canceler !=
null &&
canceler.isCancelled()) {
return;
}
long now =
monotonicNow();
long curPeriodEnd =
curPeriodStart + period;
// 如果当前时间还在本周期时间内的话,则必须等待此周期的结束,
// 重新获取新的可传输字节量
if ( now <
curPeriodEnd ) {
// Wait for next period so that curReservecan be increased.
try {
wait( curPeriodEnd -
now );
}
catch (InterruptedException
e) {
// Abort throttle and reset interruptedstatus to make sure other
// interrupt handling higher in the callstack executes.
Thread.currentThread().interrupt();
break;
}
}
else if (
now < (curPeriodStart +
periodExtension)) {
// 如果当前时间已经超过此周期的时间且不大于最大周期间隔,则增加可接受字节数,
// 并更新周期起始时间为前一周期的末尾时间
curPeriodStart = curPeriodEnd;
curReserve += bytesPerPeriod;
}
else {
// discard the prev period.Throttler might not have
// been used for a long time.
// 如果当前时间超过curPeriodStart + periodExtension,则表示
// 已经长时间没有使用Throttler,重新重置时间
curPeriodStart = now;
curReserve = bytesPerPeriod -
bytesAlreadyUsed;
}
}
//传输结束,当前字节使用量进行移除
bytesAlreadyUsed -= numOfBytes;
}
}
所以在这里我们知道,影响带宽速率指标 不仅和带宽速度上限值 有关系,还和周期有关系,如果周期设置小了,那么发生等待的次数会相对变多,那么带宽平均速度回更低。
缺点:
1、周期默认是500,代码写死了,弄成可配置的更好
2、上述场景都不是在job层面,并没有在正常的readBlock和writeBlock操作做这样的限制,这样的话,job的数据传输,将会用光已有宽带。
在hadoop自身内部,就有一些限流操作:
1、Blancer平衡数据限流
2、FsImage镜像文件上传下载数据传输流
3、VolumeScanner: 磁盘扫描的数据读操作
一 DataTransderThrottler
对数据传输限制流量的一个类,他所指定的带宽大小或者速率被多个线程共享。
他的核心思想就是:通过单位时间内限制的指定字节数的方式来控制平均传输速度。比如如果发现IO传输速度过快,超过规定时间内的带宽限定字节数,则会进行等待操作,等待下一个允许带宽传输的周期到来
//设置一个期间或者周期,比如5s内只允许发送1024字节,这里的周期就是5s
private final
long period; //period over which
bw is imposed
private final
long periodExtension;
// Max period over which bw accumulates.
//周期内能够被发送的字节数量,1024字节就是允许发送的字节数
private long
bytesPerPeriod; // total number of bytes can be sent ineach period
//当前周期起始点
private long
curPeriodStart; // current period starting time
//当前能够发送的剩余字节数,比如周期前2s发送了500字节,那么还剩余524字节
private long
curReserve; // remaining bytes can be sent in theperiod
//和上面相对应,这个是已经使用到字节数,前2s发送了500字节,那么这500字节就是已经使用了的字节数
private
long bytesAlreadyUsed;
public synchronized
void throttle(long
numOfBytes, Canceler
canceler) {
if ( numOfBytes <=
0 ) {
return;
}
//当前的可传输的字节数减去当前发送/接收字节数
curReserve -= numOfBytes;
//当前字节使用量
bytesAlreadyUsed += numOfBytes;
while (curReserve <=
0) {
//如果设置了canceler对象,则不会进行限流操作
if (canceler !=
null &&
canceler.isCancelled()) {
return;
}
long now =
monotonicNow();
long curPeriodEnd =
curPeriodStart + period;
// 如果当前时间还在本周期时间内的话,则必须等待此周期的结束,
// 重新获取新的可传输字节量
if ( now <
curPeriodEnd ) {
// Wait for next period so that curReservecan be increased.
try {
wait( curPeriodEnd -
now );
}
catch (InterruptedException
e) {
// Abort throttle and reset interruptedstatus to make sure other
// interrupt handling higher in the callstack executes.
Thread.currentThread().interrupt();
break;
}
}
else if (
now < (curPeriodStart +
periodExtension)) {
// 如果当前时间已经超过此周期的时间且不大于最大周期间隔,则增加可接受字节数,
// 并更新周期起始时间为前一周期的末尾时间
curPeriodStart = curPeriodEnd;
curReserve += bytesPerPeriod;
}
else {
// discard the prev period.Throttler might not have
// been used for a long time.
// 如果当前时间超过curPeriodStart + periodExtension,则表示
// 已经长时间没有使用Throttler,重新重置时间
curPeriodStart = now;
curReserve = bytesPerPeriod -
bytesAlreadyUsed;
}
}
//传输结束,当前字节使用量进行移除
bytesAlreadyUsed -= numOfBytes;
}
}
所以在这里我们知道,影响带宽速率指标 不仅和带宽速度上限值 有关系,还和周期有关系,如果周期设置小了,那么发生等待的次数会相对变多,那么带宽平均速度回更低。
缺点:
1、周期默认是500,代码写死了,弄成可配置的更好
2、上述场景都不是在job层面,并没有在正常的readBlock和writeBlock操作做这样的限制,这样的话,job的数据传输,将会用光已有宽带。
相关文章推荐
- HDFS的读写限流方案
- hdfs java读写hdfs demo
- HDFS读写数据的原理
- 调用JAVA API对HDFS文件进行文件的读写、上传下载、删除等操作代码详解
- Spark WordCount 读写hdfs文件 (read file from hadoop hdfs and write output to hdfs)
- HDFS学习笔记(3)HDFS数据流读写
- HDFS读写流程
- HDFS读写文件的java代码
- HDFS追本溯源:租约,读写过程的容错处理及NN的主要数据结构
- HDFS 读写数据详细步骤
- 系统重启后,需要重新格式化HDFS问题解决方案
- 012 HDFS API 文件读写代码演示
- HDFS原理解析(总体架构,读写操作流程)
- HDFS 读写流程概要
- HDFS数据的读写过程
- java读写HDFS
- 基于Spring的MyBatis读写分离实现方案
- HDFS 主从结构以及读写策略探究
- IO读写方案
- hdfs读写原理