r/m nodeprobe bootstrap

patch by jbellis; reviewed by Eric Evans for CASSANDRA-438

git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/trunk@822877 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jonathan Ellis 2009-10-07 19:42:01 +00:00
parent ff3dd4dcec
commit 303951c458
5 changed files with 32 additions and 96 deletions

View File

@ -1,3 +1,12 @@
0.5 dev
* All non-seed nodes will attempt to bootstrap when started, until
bootstrap successfully completes. -b option is removed.
* Unless a token is manually specified in the configuration xml,
a bootstraping node will use a token that gives it half the
keys from the most-heavily-loaded node in the cluster,
instead of generating a random token.
0.4.1 0.4.1
* Fix FlushPeriod columnfamily configuration regression * Fix FlushPeriod columnfamily configuration regression
(CASSANDRA-455) (CASSANDRA-455)

View File

@ -145,6 +145,7 @@ public class Gossiper implements IFailureDetectionEventListener, IEndPointStateC
StageManager.registerStage( Gossiper.GOSSIP_STAGE, new SingleThreadedStage("GMFD") ); StageManager.registerStage( Gossiper.GOSSIP_STAGE, new SingleThreadedStage("GMFD") );
} }
/** Register with the Gossiper for EndPointState notifications */
public void register(IEndPointStateChangeSubscriber subscriber) public void register(IEndPointStateChangeSubscriber subscriber)
{ {
subscribers_.add(subscriber); subscribers_.add(subscriber);
@ -881,6 +882,10 @@ public class Gossiper implements IFailureDetectionEventListener, IEndPointStateC
} }
} }
/**
* Start the gossiper with the generation # retrieved from the System
* table
*/
public void start(EndPoint localEndPoint, int generationNbr) throws IOException public void start(EndPoint localEndPoint, int generationNbr) throws IOException
{ {
localEndPoint_ = localEndPoint; localEndPoint_ = localEndPoint;

View File

@ -83,7 +83,7 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
public final static String rangeVerbHandler_ = "RANGE-VERB-HANDLER"; public final static String rangeVerbHandler_ = "RANGE-VERB-HANDLER";
public final static String bootstrapTokenVerbHandler_ = "SPLITS-VERB-HANDLER"; public final static String bootstrapTokenVerbHandler_ = "SPLITS-VERB-HANDLER";
private static StorageService instance_; private static volatile StorageService instance_;
private static EndPoint tcpAddr_; private static EndPoint tcpAddr_;
private static EndPoint udpAddr_; private static EndPoint udpAddr_;
private static IPartitioner partitioner_; private static IPartitioner partitioner_;
@ -139,15 +139,13 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
{ {
if (instance_ == null) if (instance_ == null)
{ {
boolean bootstrap = !(DatabaseDescriptor.getSeeds().contains(getLocalControlEndPoint().getHost()) || SystemTable.isBootstrapped());
synchronized (StorageService.class) synchronized (StorageService.class)
{ {
if (instance_ == null) if (instance_ == null)
{ {
try try
{ {
instance_ = new StorageService(bootstrap); instance_ = new StorageService();
} }
catch (Throwable th) catch (Throwable th)
{ {
@ -248,9 +246,8 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
} }
} }
public StorageService(boolean isBootstrapMode) public StorageService()
{ {
this.isBootstrapMode = isBootstrapMode;
bootstrapSet = new HashSet<EndPoint>(); bootstrapSet = new HashSet<EndPoint>();
init(); init();
storageLoadBalancer_ = new StorageLoadBalancer(this); storageLoadBalancer_ = new StorageLoadBalancer(this);
@ -316,6 +313,8 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
storageMetadata_ = SystemTable.initMetadata(); storageMetadata_ = SystemTable.initMetadata();
tcpAddr_ = new EndPoint(DatabaseDescriptor.getStoragePort()); tcpAddr_ = new EndPoint(DatabaseDescriptor.getStoragePort());
udpAddr_ = new EndPoint(DatabaseDescriptor.getControlPort()); udpAddr_ = new EndPoint(DatabaseDescriptor.getControlPort());
isBootstrapMode = !(DatabaseDescriptor.getSeeds().contains(udpAddr_.getHost()) || SystemTable.isBootstrapped());
/* Listen for application messages */ /* Listen for application messages */
MessagingService.instance().listen(tcpAddr_); MessagingService.instance().listen(tcpAddr_);
/* Listen for control messages */ /* Listen for control messages */
@ -327,19 +326,6 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
/* starts a load timer thread */ /* starts a load timer thread */
loadTimer_.schedule( new LoadDisseminator(), StorageService.threshold_, StorageService.threshold_); loadTimer_.schedule( new LoadDisseminator(), StorageService.threshold_, StorageService.threshold_);
/* Start the storage load balancer */
storageLoadBalancer_.start();
/* Register with the Gossiper for EndPointState notifications */
Gossiper.instance().register(this);
/*
* Start the gossiper with the generation # retrieved from the System
* table
*/
Gossiper.instance().start(udpAddr_, storageMetadata_.getGeneration());
/* Make sure this token gets gossiped around. */
tokenMetadata_.update(storageMetadata_.getToken(), StorageService.tcpAddr_, isBootstrapMode);
ApplicationState state = new ApplicationState(StorageService.getPartitioner().getTokenFactory().toString(storageMetadata_.getToken()));
Gossiper.instance().addApplicationState(StorageService.nodeId_, state);
if (isBootstrapMode) if (isBootstrapMode)
{ {
logger_.info("Starting in bootstrap mode (first, sleeping to get load information)"); logger_.info("Starting in bootstrap mode (first, sleeping to get load information)");
@ -379,9 +365,19 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
updateToken(t); updateToken(t);
} }
} }
doBootstrap(StorageService.getLocalStorageEndPoint());
BootStrapper bs = new BootStrapper(new EndPoint[] {getLocalStorageEndPoint()}, storageMetadata_.getToken());
bootStrapper_.submit(bs);
Gossiper.instance().addApplicationState(BOOTSTRAP_MODE, new ApplicationState("")); Gossiper.instance().addApplicationState(BOOTSTRAP_MODE, new ApplicationState(""));
} }
storageLoadBalancer_.start();
Gossiper.instance().register(this);
Gossiper.instance().start(udpAddr_, storageMetadata_.getGeneration());
/* Make sure this token gets gossiped around. */
tokenMetadata_.update(storageMetadata_.getToken(), StorageService.tcpAddr_, isBootstrapMode);
ApplicationState state = new ApplicationState(StorageService.getPartitioner().getTokenFactory().toString(storageMetadata_.getToken()));
Gossiper.instance().addApplicationState(StorageService.nodeId_, state);
} }
private Token<?> getBootstrapTokenFrom(EndPoint maxEndpoint) private Token<?> getBootstrapTokenFrom(EndPoint maxEndpoint)
@ -659,42 +655,7 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
updateToken(newToken); updateToken(newToken);
} }
} }
/**
* This method takes a colon separated string of nodes that need
* to be bootstrapped. * <i>nodes</i> must be specified as A:B:C.
* @throws UnknownHostException
*
*/
private void doBootstrap(String nodes) throws UnknownHostException
{
String[] allNodes = nodes.split(":");
EndPoint[] endpoints = new EndPoint[allNodes.length];
Token[] tokens = new Token[allNodes.length];
for ( int i = 0; i < allNodes.length; ++i )
{
String host = allNodes[i].trim();
InetAddress ip = InetAddress.getByName(host);
host = ip.getHostAddress();
endpoints[i] = new EndPoint( host, DatabaseDescriptor.getStoragePort() );
tokens[i] = tokenMetadata_.getToken(endpoints[i]);
}
/* Start the bootstrap algorithm */
bootStrapper_.submit( new BootStrapper(endpoints, tokens) );
}
/**
* Starts the bootstrap operations for the specified endpoint.
* @param endpoint
*/
public final void doBootstrap(EndPoint endpoint)
{
Token token = tokenMetadata_.getToken(endpoint);
bootStrapper_.submit(new BootStrapper(new EndPoint[]{endpoint}, token));
}
/** /**
* Deliver hints to the specified node when it has crashed * Deliver hints to the specified node when it has crashed
* and come back up/ marked as alive after a network partition * and come back up/ marked as alive after a network partition
@ -757,11 +718,6 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
return Gossiper.instance().getCurrentGenerationNumber(udpAddr_); return Gossiper.instance().getCurrentGenerationNumber(udpAddr_);
} }
public void bootstrapNodes(String nodes) throws UnknownHostException
{
doBootstrap(nodes);
}
public void forceTableCleanup() throws IOException public void forceTableCleanup() throws IOException
{ {
List<String> tables = DatabaseDescriptor.getTables(); List<String> tables = DatabaseDescriptor.getTables();
@ -772,9 +728,6 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto
} }
} }
/**
* Trigger the immediate compaction of all tables.
*/
public void forceTableCompaction() throws IOException public void forceTableCompaction() throws IOException
{ {
List<String> tables = DatabaseDescriptor.getTables(); List<String> tables = DatabaseDescriptor.getTables();

View File

@ -78,20 +78,7 @@ public interface StorageServiceMBean
* Forces major compaction (all sstable files compacted) * Forces major compaction (all sstable files compacted)
*/ */
public void forceTableCompaction() throws IOException; public void forceTableCompaction() throws IOException;
/**
* This method will cause the local node initiate
* the bootstrap process for all the nodes specified
* in the string parameter passed in. This local node
* will calculate who gives what ranges to the nodes
* and then instructs the nodes to do so.
*
* @param nodes colon delimited list of endpoints that need
* to be bootstrapped
* @throws UnknownHostException
*/
public void bootstrapNodes(String nodes) throws UnknownHostException;
/** /**
* Trigger a cleanup of keys on all tables. * Trigger a cleanup of keys on all tables.
*/ */

View File

@ -178,11 +178,6 @@ public class NodeProbe
ssProxy.forceTableCleanup(); ssProxy.forceTableCleanup();
} }
public void bootstrapNodes(String nodeList) throws UnknownHostException
{
ssProxy.bootstrapNodes(nodeList);
}
public void forceTableCompaction() throws IOException public void forceTableCompaction() throws IOException
{ {
ssProxy.forceTableCompaction(); ssProxy.forceTableCompaction();
@ -469,7 +464,7 @@ public class NodeProbe
{ {
HelpFormatter hf = new HelpFormatter(); HelpFormatter hf = new HelpFormatter();
String header = String.format( String header = String.format(
"%nAvailable commands: ring, cluster, info, cleanup, compact, cfstats, snapshot [name], clearsnapshot, bootstrap, tpstats, flush_binary, " + "%nAvailable commands: ring, cluster, info, cleanup, compact, cfstats, snapshot [name], clearsnapshot, tpstats, flush_binary, " +
" getcompactionthreshold, setcompactionthreshold [minthreshold] ([maxthreshold])"); " getcompactionthreshold, setcompactionthreshold [minthreshold] ([maxthreshold])");
String usage = String.format("java %s -host <arg> <command>%n", NodeProbe.class.getName()); String usage = String.format("java %s -host <arg> <command>%n", NodeProbe.class.getName());
hf.printHelp(usage, "", options, header); hf.printHelp(usage, "", options, header);
@ -541,19 +536,6 @@ public class NodeProbe
{ {
probe.clearSnapshot(); probe.clearSnapshot();
} }
else if (cmdName.equals("bootstrap"))
{
if (arguments.length == 2)
{
probe.bootstrapNodes(arguments[1]);
}
else
{
System.err.println(cmdName + " needs a node to work with");
NodeProbe.printUsage();
System.exit(1);
}
}
else if (cmdName.equals("tpstats")) else if (cmdName.equals("tpstats"))
{ {
probe.printThreadPoolStats(System.out); probe.printThreadPoolStats(System.out);