On Dec 10, 2007, at 6:00 PM, Matthew Toseland wrote:
> [...]
>> If we are leaving our stores behind, I would predict that for many
>> nodes (running suffecient to have meaningful stats) that the
>> 'storeDist' value may become arbitrary. And if it approaches the
>> 'furthestSuccess' value the store is "left-behind"; whereas the
>> cacheDist will maintain approx. the same (once reliable).
>
> IMHO we need the histogram, or at least a measure of spread, not
> just an
> average key.
>> Do you want this in the trunk? I don't think that I have the time to
>> do much data collection.
>
> Your diff is empty. Might be a problem on my end though.
It came up alright in the message coming back to me through the list,
but I've pasted it on the end of the message to avoid any attachment
trouble.
On Dec 9, 2007, at 11:47 AM, David Sowder (Zothar) wrote:
> As I see it currently, stuff being kicked out of the datastore isn't
> happening except when the datastore is being shrunk since AFAIK,
> nobody's datastore is filling, only their datacache is.
On Dec 10, 2007, at 11:27 AM, Robert Hailey wrote:
>> Not true. We have mechanisms to get popular data back into the
>> datastore. The
>> main one is 1 in every 100 successful requests gets turned into an
>> insert
>> post-completion.
>
>
> That is intriguing. I wonder how much of my 0.3% store-hit-successes
> (my present value) are actually blocks recently-inserted from the 1%
> healing (i.e. bleed-over from the cache).
I've got another idea from the code I saw while forming this stats
diff...
Whereas:
(1) presently we always check the datastore before the datacache,
(2) the datacache has a 8-9x better hit rate,
(3) I suspect that the hits from the store may actually be in the
cache as well
I think that we should reverse the fetch()es to try the cache first
(since it is more likely anyway). Certainly we are running on caches
alone, no? If my suspicion is correct, the false-hits for the data
store will be removed, and the store-hit-rate may tank to 0.000%.
Arguably it would not promote the data in the store, but presently it
doesn't promote it in the cache.
--
Robert Hailey
<Inserted here: freenet-datastore-location-stats.diff>
Index: src/freenet/node/NodeStats.java
===================================================================
--- src/freenet/node/NodeStats.java (revision 16462)
+++ src/freenet/node/NodeStats.java (working copy)
@@ -22,6 +22,7 @@
import freenet.support.api.IntCallback;
import freenet.support.api.LongCallback;
import freenet.support.math.RunningAverage;
+import freenet.support.math.SimpleRunningAverage;
import freenet.support.math.TimeDecayingRunningAverage;
import freenet.support.math.TrivialRunningAverage;
@@ -144,8 +145,17 @@
// various metrics
public final RunningAverage routingMissDistance;
public final RunningAverage backedOffPercent;
+ public final RunningAverage avgCacheLocation;
+ public final RunningAverage avgStoreLocation;
+ public final RunningAverage avgCacheSuccess;
+ public final RunningAverage avgStoreSuccess;
+ // FIXME: does furthest{Store,Cache}Success need to be synchronized?
+ public double furthestCacheSuccess=0.0;
+ public double furthestStoreSuccess=0.0;
protected final Persister persister;
+ protected final RunningAverage avgRequestLocation;
+
// ThreadCounting stuffs
public final ThreadGroup rootThreadGroup;
private int threadLimit;
@@ -176,6 +186,14 @@
this.hardRandom = node.random;
this.routingMissDistance = new TimeDecayingRunningAverage(0.0,
180000, 0.0, 1.0, node);
this.backedOffPercent = new TimeDecayingRunningAverage(0.0,
180000, 0.0, 1.0, node);
+ // FIXME PLEASE remove (int) casts
+ double nodeLoc=node.lm.getLocation();
+ this.avgCacheLocation=new
SimpleRunningAverage((int)node.maxCacheKeys, nodeLoc);
+ this.avgStoreLocation=new
SimpleRunningAverage((int)node.maxStoreKeys, nodeLoc);
+ // FIXME average for success-location may not need to be so
large
as the store.
+ this.avgCacheSuccess=new SimpleRunningAverage(10000, nodeLoc);
+ this.avgStoreSuccess=new SimpleRunningAverage(10000, nodeLoc);
+ this.avgRequestLocation=new SimpleRunningAverage(10000,
nodeLoc);
preemptiveRejectReasons = new StringCounter();
localPreemptiveRejectReasons = new StringCounter();
pInstantRejectIncoming = new TimeDecayingRunningAverage(0,
60000,
0.0, 1.0, node);
@@ -186,6 +204,18 @@
new TimeDecayingRunningAverage(1, 10*60*1000 /* should
be
significantly longer than a typical transfer */, 0, Long.MAX_VALUE,
node);
nodePinger = new NodePinger(node);
+ // FIXME: data-store/cache averages need to be persisted to be
valuable (or scanned at every launch).
+ /*
+ if (node.isAdvancedModeEnabled()) {
+ //Uggghh....
+ System.err.println("Scanning datastore/cache for
location values");
+ chkDatastore.kludgeScan(avgStoreLocation);
+ sskDatastore.kludgeScan(avgStoreLocation);
+ chkDatacache.kludgeScan(avgCacheLocation);
+ sskDatacache.kludgeScan(avgCacheLocation);
+ }
+ */
+
previous_input_stat = 0;
previous_output_stat = 0;
previous_io_stat_time = 1;
Index: src/freenet/node/Node.java
===================================================================
--- src/freenet/node/Node.java (revision 16462)
+++ src/freenet/node/Node.java (working copy)
@@ -247,8 +247,8 @@
/** The maximum number of keys stored in each of the datastores,
cache and store combined. */
private long maxTotalKeys;
- private long maxCacheKeys;
- private long maxStoreKeys;
+ long maxCacheKeys;
+ long maxStoreKeys;
/** The maximum size of the datastore. Kept to avoid rounding
turning 5G into 5368698672 */
private long maxTotalDatastoreSize;
/** If true, store shrinks occur immediately even if they are over
10% of the store size. If false,
@@ -1767,11 +1767,23 @@
public SSKBlock fetch(NodeSSK key, boolean dontPromote) {
if(logMINOR) dumpStoreHits();
try {
+ double loc=key.toNormalizedDouble();
+ double dist=Location.distance(lm.getLocation(), loc);
+ nodeStats.avgRequestLocation.report(loc);
SSKBlock block = sskDatastore.fetch(key, dontPromote);
if(block != null) {
+ nodeStats.avgStoreSuccess.report(loc);
+ if (dist > nodeStats.furthestStoreSuccess)
+ nodeStats.furthestStoreSuccess=dist;
return block;
}
- return sskDatacache.fetch(key, dontPromote);
+ block=sskDatacache.fetch(key, dontPromote);
+ if (block != null) {
+ nodeStats.avgCacheSuccess.report(loc);
+ if (dist > nodeStats.furthestCacheSuccess)
+ nodeStats.furthestCacheSuccess=dist;
+ }
+ return block;
} catch (IOException e) {
Logger.error(this, "Cannot fetch data: "+e, e);
return null;
@@ -1781,9 +1793,23 @@
public CHKBlock fetch(NodeCHK key, boolean dontPromote) {
if(logMINOR) dumpStoreHits();
try {
+ double loc=key.toNormalizedDouble();
+ double dist=Location.distance(lm.getLocation(), loc);
+ nodeStats.avgRequestLocation.report(loc);
CHKBlock block = chkDatastore.fetch(key, dontPromote);
- if(block != null) return block;
- return chkDatacache.fetch(key, dontPromote);
+ if (block != null) {
+ nodeStats.avgStoreSuccess.report(loc);
+ if (dist > nodeStats.furthestStoreSuccess)
+ nodeStats.furthestStoreSuccess=dist;
+ return block;
+ }
+ block=chkDatacache.fetch(key, dontPromote);
+ if (block != null) {
+ nodeStats.avgCacheSuccess.report(loc);
+ if (dist > nodeStats.furthestCacheSuccess)
+ nodeStats.furthestCacheSuccess=dist;
+ }
+ return block;
} catch (IOException e) {
Logger.error(this, "Cannot fetch data: "+e, e);
return null;
@@ -1835,10 +1861,13 @@
private void store(CHKBlock block, boolean deep) {
try {
+ double loc=block.getKey().toNormalizedDouble();
if(deep) {
chkDatastore.put(block);
+ nodeStats.avgStoreLocation.report(loc);
}
chkDatacache.put(block);
+ nodeStats.avgCacheLocation.report(loc);
if(clientCore != null && clientCore.requestStarters !=
null)
clientCore.requestStarters.chkFetchScheduler.tripPendingKey(block);
} catch (IOException e) {
@@ -2498,6 +2527,10 @@
return usm;
}
+ public double getNodeLocation() {
+ return lm.getLocation();
+ }
+
public int getSwaps() {
return LocationManager.swaps;
}
Index: src/freenet/clients/http/StatisticsToadlet.java
===================================================================
--- src/freenet/clients/http/StatisticsToadlet.java (revision 16462)
+++ src/freenet/clients/http/StatisticsToadlet.java (working copy)
@@ -29,6 +29,7 @@
import freenet.support.SizeUtil;
import freenet.support.TimeUtil;
import freenet.support.api.HTTPRequest;
+import freenet.support.math.SimpleRunningAverage;
public class StatisticsToadlet extends Toadlet {
@@ -422,8 +423,47 @@
"\u00a0(" + ((storeHits*100) /
(storeAccesses)) + "%)");
storeSizeList.addChild("li",
- "Avg. access rate:\u00a0" +
thousendPoint.format(overallAccesses/
nodeUptimeSeconds) + "/sec");
+ "Avg. access rate:\u00a0" +
thousendPoint.format(cacheAccesses/
nodeUptimeSeconds) + "/sec, "+thousendPoint.format(storeAccesses/
nodeUptimeSeconds)+"/sec");
+ // location-based stats
+ boolean hasLoc=true;
+ double nodeLoc=0.0;
+ try {
+ nodeLoc=node.getNodeLocation();
+ } catch (Error e) {
+ //FIXME: PLEASE, how do we get the node location on the
stats page?
+ //Logger.error(this, "why?", e);
+ e.printStackTrace();
+ hasLoc=false;
+ }
+ double
avgCacheLocation=node.nodeStats.avgCacheLocation.currentValue();
+ double
avgStoreLocation=node.nodeStats.avgStoreLocation.currentValue();
+ double
avgCacheSuccess=node.nodeStats.avgCacheSuccess.currentValue();
+ double
avgStoreSuccess=node.nodeStats.avgStoreSuccess.currentValue();
+ double furthestCacheSuccess=node.nodeStats.furthestCacheSuccess;
+ double furthestStoreSuccess=node.nodeStats.furthestStoreSuccess;
+ double storeDist=Location.distance(nodeLoc, avgStoreLocation);
+ double cacheDist=Location.distance(nodeLoc, avgCacheLocation);
+
+ storeSizeList.addChild("li", "avgCacheLocation:\u00a0" +
thousendPoint.format(avgCacheLocation));
+ storeSizeList.addChild("li", "avgStoreLocation:\u00a0" +
thousendPoint.format(avgStoreLocation));
+
+ storeSizeList.addChild("li", "avgCacheSuccess:\u00a0" +
thousendPoint.format(avgCacheSuccess));
+ storeSizeList.addChild("li", "avgStoreSuccess:\u00a0" +
thousendPoint.format(avgStoreSuccess));
+
+ storeSizeList.addChild("li", "furthestCacheSuccess:\u00a0" +
thousendPoint.format(furthestCacheSuccess));
+ storeSizeList.addChild("li", "furthestStoreSuccess:\u00a0" +
thousendPoint.format(furthestStoreSuccess));
+
+ if (hasLoc) {
+ storeSizeList.addChild("li", "cacheDist:\u00a0" +
thousendPoint.format(cacheDist));
+ storeSizeList.addChild("li", "storeDist:\u00a0" +
thousendPoint.format(storeDist));
+ long
cacheLocationReports
=((SimpleRunningAverage)node.nodeStats.avgCacheLocation).countReports();
+ long
storeLocationReports
=((SimpleRunningAverage)node.nodeStats.avgStoreLocation).countReports();
+ double
cachePrimePercent=((1.0*cacheLocationReports)/cachedKeys);
+ double
storePrimePercent=((1.0*storeLocationReports)/storeKeys);
+ storeSizeList.addChild("li", "locStatsReliability:
\u00a0"+fix3p1pct.format(cachePrimePercent)+" /
"+fix3p1pct.format(storePrimePercent));
+ }
+
}
private void drawUnclaimedFIFOMessageCountsBox(HTMLNode
unclaimedFIFOMessageCountsInfobox) {
-------------------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<https://emu.freenetproject.org/pipermail/devl/attachments/20071211/ce2e454a/attachment.html>