限速的逻辑
首先我们自己可以想像限速的地方会在什么地方?
当reader读取数据,发送到内存通道的时候可以进行速度的控制。
顺着这个思路,我们开始阅读代码
1-我们知道BufferedRecordExchanger.sendToWriter()方法,是发送数据到内存通道的地方,
里面的flush();方法则是真正执行发送的地方。
@Override public void flush() { if(shutdown){ throw DataXException.asDataXException(CommonErrorCode.SHUT_DOWN_TASK, ""); } this.channel.pushAll(this.buffer);//加入到arrayBlockQueue this.buffer.clear(); this.bufferIndex = 0; this.memoryBytes.set(0); }
2-进入到com.alibaba.datax.core.transport.channel.Channel类的pushAll方法
public void pushAll(final Collection<Record> rs) { Validate.notNull(rs); Validate.noNullElements(rs); this.doPushAll(rs); this.statPush(rs.size(), this.getByteSize(rs));//限速在此处 }
可以看到整个发送数据内存通道的逻辑。
大致分为两步:1-批量发送数据,2-对数据发送速度的控制
3-到此,我们已经找到核心的代码了,继续看是怎么进行限速的
4-在Channel构造函数中会初始化限速的参数
long byteSpeed = configuration.getLong( CoreConstant.DATAX_CORE_TRANSPORT_CHANNEL_SPEED_BYTE, 1024 * 1024);//channel限制的速度1Mb/S long recordSpeed = configuration.getLong( CoreConstant.DATAX_CORE_TRANSPORT_CHANNEL_SPEED_RECORD, 10000); 默认情况下core.json里面配置的是: "speed": { "byte": -1, "record": -1 }, 代表不会进行限速的处理
5-我们可以看到在statPush方法中
boolean isChannelByteSpeedLimit = (this.byteSpeed > 0); boolean isChannelRecordSpeedLimit = (this.recordSpeed > 0); if (!isChannelByteSpeedLimit && !isChannelRecordSpeedLimit) {//判断是否配置了 return; } 这里代表会去判断byte和record是否大于0,然后才可以继续 如果配置了参数则会通过比较和判断计算出需要休眠的时间来达到限速 // 休眠时间取较大值 long sleepTime = byteLimitSleepTime < recordLimitSleepTime ? recordLimitSleepTime : byteLimitSleepTime; if (sleepTime > 0) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }
6-我们可以查看日志看到设置是否生效:
Channel set byte_speed_limit to 5242880.
注意channel.byte设置大之后,响应的内存参数也要加大,默认是"-Xms1g -Xmx1g"
到此如果需要对单个channel速度大小进行调整则可以修改此参数
类似:
"transport": { "channel": { "class": "com.alibaba.datax.core.transport.channel.memory.MemoryChannel", "speed": { "byte": 5242880, "record": -1 }, "flowControlInterval": 20, "capacity": 512, "byteCapacity": 67108864 }, "exchanger": { "class": "com.alibaba.datax.core.plugin.BufferedRecordExchanger", "bufferSize": 32 } }
后续会继续对几个配置进行解读,来看一下调整参数增加并发处理任务的方式