Allow tunable node sizes to adjust cache sizes, sweep timing, fetch

timing, and so on. Node size defaults to "tiny", which converves
memory and bandwidth.
This commit is contained in:
JoelKatz
2013-01-27 13:55:59 -08:00
parent bdd5d4af9f
commit e8ac00e1a3
12 changed files with 104 additions and 6 deletions

View File

@@ -211,6 +211,11 @@
# Examples: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE
# shfArahZT9Q9ckTf3s1psJ7C7qzVN
#
# [node_size]:
# Tunes the servers based on the expected load and available memory. Legal
# sizes are "tiny", "small", "medium", "large", and "huge".
# The default is "tiny".
#
# [cluster_nodes]:
# To extend full trust to other nodes, place their node public keys here.
# Generally, you should only do this for nodes under common administration.

View File

@@ -50,7 +50,7 @@ Application::Application() :
getRand(mNonce256.begin(), mNonce256.size());
getRand(reinterpret_cast<unsigned char *>(&mNonceST), sizeof(mNonceST));
mJobQueue.setThreadCount();
mSweepTimer.expires_from_now(boost::posix_time::seconds(60));
mSweepTimer.expires_from_now(boost::posix_time::seconds(20));
mSweepTimer.async_wait(boost::bind(&Application::sweep, this));
}
@@ -159,6 +159,9 @@ void Application::setup()
if (!theConfig.RUN_STANDALONE)
getUNL().nodeBootstrap();
mValidations.tune(theConfig.getSize(siValidationsSize), theConfig.getSize(siValidationsAge));
mHashedObjectStore.tune(theConfig.getSize(siNodeCacheSize), theConfig.getSize(siNodeCacheAge));
mLedgerMaster.tune(theConfig.getSize(siLedgerSize), theConfig.getSize(siLedgerAge));
//
// Allow peer connections.
@@ -294,7 +297,7 @@ void Application::sweep()
mTempNodeCache.sweep();
mValidations.sweep();
getMasterLedgerAcquire().sweep();
mSweepTimer.expires_from_now(boost::posix_time::seconds(60));
mSweepTimer.expires_from_now(boost::posix_time::seconds(theConfig.getSize(siSweepInterval)));
mSweepTimer.async_wait(boost::bind(&Application::sweep, this));
}

View File

@@ -27,6 +27,7 @@
#define SECTION_IPS "ips"
#define SECTION_NETWORK_QUORUM "network_quorum"
#define SECTION_NODE_SEED "node_seed"
#define SECTION_NODE_SIZE "node_size"
#define SECTION_PEER_CONNECT_LOW_WATER "peer_connect_low_water"
#define SECTION_PEER_IP "peer_ip"
#define SECTION_PEER_PORT "peer_port"
@@ -81,8 +82,9 @@ void Config::setup(const std::string& strConf, bool bTestNet, bool bQuiet)
// that with "db" as the data directory.
//
TESTNET = bTestNet;
QUIET = bQuiet;
TESTNET = bTestNet;
QUIET = bQuiet;
NODE_SIZE = 0;
// TESTNET forces a "testnet-" prefix on the conf file and db directory.
strDbPath = TESTNET ? "testnet-db" : "db";
@@ -329,6 +331,28 @@ void Config::load()
if (sectionSingleB(secConfig, SECTION_RPC_ALLOW_REMOTE, strTemp))
RPC_ALLOW_REMOTE = boost::lexical_cast<bool>(strTemp);
if (sectionSingleB(secConfig, SECTION_NODE_SIZE, strTemp))
{
if (strTemp == "tiny")
NODE_SIZE = 0;
else if (strTemp == "small")
NODE_SIZE = 1;
else if (strTemp == "medium")
NODE_SIZE = 2;
else if (strTemp == "large")
NODE_SIZE = 3;
else if (strTemp == "huge")
NODE_SIZE = 4;
else
{
NODE_SIZE = boost::lexical_cast<int>(strTemp);
if (NODE_SIZE < 0)
NODE_SIZE = 0;
else if (NODE_SIZE > 4)
NODE_SIZE = 4;
}
}
(void) sectionSingleB(secConfig, SECTION_WEBSOCKET_IP, WEBSOCKET_IP);
if (sectionSingleB(secConfig, SECTION_WEBSOCKET_PORT, strTemp))
@@ -427,4 +451,27 @@ void Config::load()
}
}
int Config::getSize(SizedItemName item)
{
SizedItem sizeTable[] = {
{ siSweepInterval, { 10, 30, 60, 90, 90 } },
{ siLedgerFetch, { 2, 4, 10, 10, 10 } },
{ siValidationsSize, { 256, 256, 512, 1024, 1024 } },
{ siValidationsAge, { 500, 500, 500, 500, 500 } },
{ siNodeCacheSize, { 8192, 32768, 131072, 1048576, 0 } },
{ siNodeCacheAge, { 30, 60, 90, 300, 600 } },
{ siLedgerSize, { 32, 64, 128, 1024, 0 } },
{ siLedgerAge, { 30, 60, 120, 300, 600 } },
};
for (int i = 0; i < (sizeof(sizeTable) / sizeof(SizedItem)); ++i)
{
if (sizeTable[i].item == item)
return sizeTable[i].sizes[NODE_SIZE];
}
assert(false);
return -1;
}
// vim:ts=4

View File

@@ -48,6 +48,24 @@ const int SYSTEM_WEBSOCKET_PUBLIC_PORT = 6563; // XXX Going away.
// Might connect with fewer for testing.
#define DEFAULT_PEER_CONNECT_LOW_WATER 4
enum SizedItemName
{
siSweepInterval,
siValidationsSize,
siValidationsAge,
siNodeCacheSize,
siNodeCacheAge,
siLedgerSize,
siLedgerAge,
siLedgerFetch,
};
struct SizedItem
{
SizedItemName item;
int sizes[5];
};
class Config
{
public:
@@ -139,6 +157,7 @@ public:
// Node storage configuration
uint32 LEDGER_HISTORY;
int NODE_SIZE;
// Client behavior
int ACCOUNT_PROBE_MAX; // How far to scan for accounts.
@@ -150,6 +169,7 @@ public:
Config();
int getSize(SizedItemName);
void setup(const std::string& strConf, bool bTestNet, bool bQuiet);
void load();
};

View File

@@ -20,6 +20,12 @@ HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) :
mWriteSet.reserve(128);
}
void HashedObjectStore::tune(int size, int age)
{
mCache.setTargetSize(size);
mCache.setTargetAge(age);
}
bool HashedObjectStore::store(HashedObjectType type, uint32 index,
const std::vector<unsigned char>& data, const uint256& hash)

View File

@@ -67,6 +67,7 @@ public:
void bulkWrite();
void waitWrite();
void tune(int size, int age);
void sweep() { mCache.sweep(); mNegativeCache.sweep(); }
int import(const std::string&);

View File

@@ -115,4 +115,10 @@ Ledger::pointer LedgerHistory::canonicalizeLedger(Ledger::pointer ledger, bool s
return ledger;
}
void LedgerHistory::tune(int size, int age)
{
mLedgersByHash.setTargetSize(size);
mLedgersByHash.setTargetAge(age);
}
// vim:ts=4

View File

@@ -19,6 +19,7 @@ public:
Ledger::pointer getLedgerBySeq(uint32 index);
Ledger::pointer getLedgerByHash(const uint256& hash);
Ledger::pointer canonicalizeLedger(Ledger::pointer, bool cache);
void tune(int size, int age);
void sweep() { mLedgersByHash.sweep(); }
};

View File

@@ -195,7 +195,8 @@ bool LedgerMaster::acquireMissingLedger(Ledger::ref origLedger, const uint256& l
theApp->getIOService().post(boost::bind(&LedgerMaster::missingAcquireComplete, this, mMissingLedger));
}
if (theApp->getMasterLedgerAcquire().getFetchCount() < 4)
int fetch = theConfig.getSize(siLedgerFetch);
if (theApp->getMasterLedgerAcquire().getFetchCount() < fetch)
{
int count = 0;
typedef std::pair<uint32, uint256> u_pair;
@@ -203,7 +204,7 @@ bool LedgerMaster::acquireMissingLedger(Ledger::ref origLedger, const uint256& l
std::vector<u_pair> vec = origLedger->getLedgerHashes();
BOOST_REVERSE_FOREACH(const u_pair& it, vec)
{
if ((count < 3) && (it.first < ledgerSeq) &&
if ((count < fetch) && (it.first < ledgerSeq) &&
!mCompleteLedgers.hasValue(it.first) && !theApp->getMasterLedgerAcquire().find(it.second))
{
++count;

View File

@@ -129,6 +129,7 @@ public:
void resumeAcquiring();
void tune(int size, int age) { mLedgerHistory.tune(size, age); }
void sweep(void) { mLedgerHistory.sweep(); }
void addValidateCallback(callback& c) { mOnValidate.push_back(c); }

View File

@@ -12,6 +12,12 @@ SETUP_LOG();
typedef std::map<uint160, SerializedValidation::pointer>::value_type u160_val_pair;
typedef boost::shared_ptr<ValidationSet> VSpointer;
void ValidationCollection::tune(int size, int age)
{
mValidations.setTargetSize(size);
mValidations.setTargetAge(age);
}
VSpointer ValidationCollection::findCreateSet(const uint256& ledgerHash)
{
VSpointer j = mValidations.fetch(ledgerHash);

View File

@@ -48,6 +48,7 @@ public:
boost::unordered_map<uint256, currentValidationCount> getCurrentValidations(uint256 currentLedger);
std::list<SerializedValidation::pointer> getCurrentTrustedValidations();
void tune(int size, int age);
void flush();
void sweep() { mValidations.sweep(); }
};