2006-03-01 jrandom

* More aggressive tunnel throttling as we approach our bandwidth limit,
      and throttle based off periods wider than 1 second.
    * Included Doubtful Salmon's syndie stylings (thanks!)
This commit is contained in:
jrandom
2006-03-01 23:01:20 +00:00
committed by zzz
parent 2b79e2df3f
commit 2c6d953359
6 changed files with 414 additions and 79 deletions

View File

@ -1016,12 +1016,26 @@ class CoalesceStatsJob extends JobImpl {
super(ctx);
ctx.statManager().createRateStat("bw.receiveBps", "How fast we receive data (in KBps)", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("bw.sendBps", "How fast we send data (in KBps)", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("bw.sendRate", "Low level bandwidth send rate, averaged every minute", "Bandwidth", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("bw.recvRate", "Low level bandwidth receive rate, averaged every minute", "Bandwidth", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("router.activePeers", "How many peers we are actively talking with", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("router.highCapacityPeers", "How many high capacity peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("router.fastPeers", "How many fast peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
}
public String getName() { return "Coalesce stats"; }
public void runJob() {
int active = getContext().commSystem().countActivePeers();
getContext().statManager().addRateData("router.activePeers", active, 60*1000);
int fast = getContext().profileOrganizer().countFastPeers();
getContext().statManager().addRateData("router.fastPeers", fast, 60*1000);
int highCap = getContext().profileOrganizer().countHighCapacityPeers();
getContext().statManager().addRateData("router.highCapacityPeers", highCap, 60*1000);
getContext().statManager().addRateData("bw.sendRate", (long)getContext().bandwidthLimiter().getSendBps(), 0);
getContext().statManager().addRateData("bw.recvRate", (long)getContext().bandwidthLimiter().getReceiveBps(), 0);
getContext().statManager().coalesceStats();
RateStat receiveRate = getContext().statManager().getRate("transport.receiveMessageSize");
@ -1043,16 +1057,7 @@ class CoalesceStatsJob extends JobImpl {
getContext().statManager().addRateData("bw.sendBps", (long)KBps, 60*1000);
}
}
int active = getContext().commSystem().countActivePeers();
getContext().statManager().addRateData("router.activePeers", active, 60*1000);
int fast = getContext().profileOrganizer().countFastPeers();
getContext().statManager().addRateData("router.fastPeers", fast, 60*1000);
int highCap = getContext().profileOrganizer().countHighCapacityPeers();
getContext().statManager().addRateData("router.highCapacityPeers", highCap, 60*1000);
requeue(60*1000);
}
}

View File

@ -88,36 +88,8 @@ class RouterThrottleImpl implements RouterThrottle {
}
long lag = _context.jobQueue().getMaxLag();
/*
RateStat rs = _context.statManager().getRate("router.throttleNetworkCause");
Rate r = null;
if (rs != null)
r = rs.getRate(60*1000);
long throttleEvents = (r != null ? r.getCurrentEventCount() + r.getLastEventCount() : 0);
if (throttleEvents > THROTTLE_EVENT_LIMIT) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Refusing tunnel request with the job lag of " + lag
+ " since there have been " + throttleEvents
+ " throttle events in the last 15 minutes or so");
_context.statManager().addRateData("router.throttleTunnelCause", lag, lag);
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
*/
RateStat rs = _context.statManager().getRate("transport.sendProcessingTime");
Rate r = null;
/*
if (rs != null)
r = rs.getRate(1*60*1000);
double processTime = (r != null ? r.getAverageValue() : 0);
if (processTime > 2000) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Refusing tunnel request with the job lag of " + lag
+ "since the 10 minute message processing time is too slow (" + processTime + ")");
_context.statManager().addRateData("router.throttleTunnelProcessingTime10m", (long)processTime, (long)processTime);
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
*/
if (rs != null)
r = rs.getRate(60*1000);
double processTime = (r != null ? r.getAverageValue() : 0);
@ -129,27 +101,6 @@ class RouterThrottleImpl implements RouterThrottle {
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
/*
rs = _context.statManager().getRate("transport.sendMessageFailureLifetime");
r = null;
if (rs != null)
r = rs.getRate(60*1000);
double failCount = (r != null ? r.getCurrentEventCount() + r.getLastEventCount() : 0);
if (failCount > 100) {
long periods = r.getLifetimePeriods();
long maxFailCount = r.getExtremeEventCount();
if ( (periods > 0) && (maxFailCount > 100) ) {
if (_context.random().nextInt((int)maxFailCount) <= failCount) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Refusing tunnel request with the job lag of " + lag
+ "since the 1 minute message failure count is too high (" + failCount + "/" + maxFailCount + ")");
_context.statManager().addRateData("router.throttleTunnelFailCount1m", (long)failCount, (long)maxFailCount);
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
}
}
*/
int numTunnels = _context.tunnelManager().getParticipatingCount();
if (numTunnels > getMinThrottleTunnels()) {
@ -244,9 +195,7 @@ class RouterThrottleImpl implements RouterThrottle {
double messagesPerTunnel = (r != null ? r.getAverageValue() : 0d);
if (messagesPerTunnel < DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE)
messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
int participatingTunnels = (r != null ? (int) (r.getLastEventCount() + r.getCurrentEventCount()) : 0);
if (participatingTunnels <= 0)
participatingTunnels = _context.tunnelManager().getParticipatingCount();
int participatingTunnels = _context.tunnelManager().getParticipatingCount();
double bytesAllocated = messagesPerTunnel * participatingTunnels * 1024;
if (!allowTunnel(bytesAllocated, numTunnels)) {
@ -261,6 +210,32 @@ class RouterThrottleImpl implements RouterThrottle {
+ " tunnels with lag of " + lag + ")");
return TUNNEL_ACCEPT;
}
private int get1sRate() {
return (int)Math.max(_context.bandwidthLimiter().getSendBps(), _context.bandwidthLimiter().getReceiveBps());
}
private int get1mRate() {
int send = 0;
RateStat rs = _context.statManager().getRate("bw.sendRate");
if (rs != null)
send = (int)rs.getRate(1*60*1000).getAverageValue();
int recv = 0;
rs = _context.statManager().getRate("bw.recvRate");
if (rs != null)
recv = (int)rs.getRate(1*60*1000).getAverageValue();
return Math.max(send, recv);
}
private int get5mRate() {
int send = 0;
RateStat rs = _context.statManager().getRate("bw.sendRate");
if (rs != null)
send = (int)rs.getRate(5*60*1000).getAverageValue();
int recv = 0;
rs = _context.statManager().getRate("bw.recvRate");
if (rs != null)
recv = (int)rs.getRate(5*60*1000).getAverageValue();
return Math.max(send, recv);
}
private static final int DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE = 600; // 1KBps
@ -272,14 +247,17 @@ class RouterThrottleImpl implements RouterThrottle {
*/
private boolean allowTunnel(double bytesAllocated, int numTunnels) {
int maxKBps = Math.min(_context.bandwidthLimiter().getOutboundKBytesPerSecond(), _context.bandwidthLimiter().getInboundKBytesPerSecond());
int used = (int)Math.max(_context.bandwidthLimiter().getSendBps(), _context.bandwidthLimiter().getReceiveBps());
int used1s = get1sRate();
int used1m = get1mRate();
int used5m = get5mRate();
int used = Math.max(Math.max(used1s, used1m), used5m);
int availBps = (int)(((maxKBps*1024) - used) * getSharePercentage());
_context.statManager().addRateData("router.throttleTunnelBytesUsed", used, maxKBps);
_context.statManager().addRateData("router.throttleTunnelBytesAllowed", availBps, (long)bytesAllocated);
if (maxKBps <= 8) {
// lets be more conservative for dialup users and assume 1KBps per tunnel
if (availBps <= 8*1024) {
// lets be more conservative for people near their limit and assume 1KBps per tunnel
return ( (numTunnels + 1)*1024 < availBps);
}
@ -295,8 +273,8 @@ class RouterThrottleImpl implements RouterThrottle {
+ "Bps/" + allocatedKBps + "KBps allocated through " + numTunnels + " tunnels");
return true;
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Rejecting the tunnel w/ " + pctFull + " of our " + availBps
if (_log.shouldLog(Log.WARN))
_log.warn("Rejecting the tunnel w/ " + pctFull + " of our " + availBps
+ "Bps allowed (" + toAllocate + "bytes / " + allocatedKBps
+ "KBps) through " + numTunnels + " tunnels");
return false;

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.363 $ $Date: 2006/02/27 14:05:40 $";
public final static String ID = "$Revision: 1.364 $ $Date: 2006/02/27 22:55:19 $";
public final static String VERSION = "0.6.1.12";
public final static long BUILD = 1;
public final static long BUILD = 2;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -47,7 +47,6 @@ public class FIFOBandwidthLimiter {
private long _lastTotalSent;
private long _lastTotalReceived;
private long _lastStatsUpdated;
private long _lastRateUpdated;
private float _sendBps;
private float _recvBps;
@ -65,8 +64,6 @@ public class FIFOBandwidthLimiter {
_context.statManager().createRateStat("bwLimiter.pendingInboundRequests", "How many inbound requests are ahead of the current one (ignoring ones with 0)?", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_context.statManager().createRateStat("bwLimiter.outboundDelayedTime", "How long it takes to honor an outbound request (ignoring ones with that go instantly)?", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_context.statManager().createRateStat("bwLimiter.inboundDelayedTime", "How long it takes to honor an inbound request (ignoring ones with that go instantly)?", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_context.statManager().createRateStat("bw.sendRate", "Low level bandwidth send rate, averaged every minute", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_context.statManager().createRateStat("bw.recvRate", "Low level bandwidth receive rate, averaged every minute", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_pendingInboundRequests = new ArrayList(16);
_pendingOutboundRequests = new ArrayList(16);
_lastTotalSent = _totalAllocatedOutboundBytes;
@ -74,7 +71,6 @@ public class FIFOBandwidthLimiter {
_sendBps = 0;
_recvBps = 0;
_lastStatsUpdated = now();
_lastRateUpdated = _lastStatsUpdated;
_refiller = new FIFOBandwidthRefiller(_context, this);
I2PThread t = new I2PThread(_refiller);
t.setName("BWRefiller" + (++__id));
@ -295,11 +291,6 @@ public class FIFOBandwidthLimiter {
_context.statManager().getStatLog().addData("bw", "bw.recvBps1s", (long)_recvBps, recv);
}
}
if (60*1000 + _lastRateUpdated <= now) {
_lastRateUpdated = now;
_context.statManager().addRateData("bw.sendRate", (long)_sendBps, 0);
_context.statManager().addRateData("bw.recvRate", (long)_recvBps, 0);
}
}
/**