Package org.apache.cassandra.gms
Class Gossiper
- java.lang.Object
-
- org.apache.cassandra.gms.Gossiper
-
- All Implemented Interfaces:
GossiperMBean,IFailureDetectionEventListener
public class Gossiper extends java.lang.Object implements IFailureDetectionEventListener, GossiperMBean
This module is responsible for Gossiping information for the local endpoint. This abstraction maintains the list of live and dead endpoints. Periodically i.e. every 1 second this module chooses a random node and initiates a round of Gossip with it. A round of Gossip involves 3 rounds of messaging. For instance if node A wants to initiate a round of Gossip with node B it starts off by sending node B a GossipDigestSynMessage. Node B on receipt of this message sends node A a GossipDigestAckMessage. On receipt of this message node A sends node B a GossipDigestAck2Message which completes a round of Gossip. This module as and when it hears one of the three above mentioned messages updates the Failure Detector with the liveness information. Upon hearing a GossipShutdownMessage, this module will instantly mark the remote node as down in the Failure Detector. This class is not threadsafe and any state changes should happen in the gossip stage.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classGossiper.Props
-
Field Summary
Fields Modifier and Type Field Description static longaVeryLongTimejava.util.concurrent.ConcurrentMap<InetAddressAndPort,EndpointState>endpointStateMapstatic Gossiperinstancestatic intintervalInMillisstatic java.lang.StringMBEAN_NAMEstatic intQUARANTINE_DELAY
-
Constructor Summary
Constructors Constructor Description Gossiper(boolean registerJmx)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaddExpireTimeForEndpoint(InetAddressAndPort endpoint, long expireTime)voidaddLocalApplicationState(ApplicationState applicationState, VersionedValue value)voidaddLocalApplicationStates(java.util.List<Pair<ApplicationState,VersionedValue>> states)voidaddSavedEndpoint(InetAddressAndPort ep)Add an endpoint we knew about previously, but whose state is unknownvoidadvertiseRemoving(InetAddressAndPort endpoint, java.util.UUID hostId, java.util.UUID localHostId)This method will begin removing an existing endpoint from the cluster by spoofing its state This should never be called unless this coordinator has had 'removenode' invokedvoidadvertiseTokenRemoved(InetAddressAndPort endpoint, java.util.UUID hostId)Handles switching the endpoint's state from REMOVING_TOKEN to REMOVED_TOKEN This should only be called after advertiseRemovingvoidapplyStateLocally(java.util.Map<InetAddressAndPort,EndpointState> epStateMap)voidassassinateEndpoint(java.lang.String address)Do not call this method unless you know what you are doing.voidclearUnsafe()intcompareEndpointStartup(InetAddressAndPort addr1, InetAddressAndPort addr2)determine which endpoint started up earlierjava.util.Map<java.lang.String,java.util.List<java.lang.String>>compareGossipAndTokenMetadata()Returns a map of endpoints that don't have matching tokenMetadata to gossip tokens.static longcomputeExpireTime()voidconvict(InetAddressAndPort endpoint, double phi)This method is part of IFailureDetectionEventListener interface.EndpointStatecopyEndpointStateForEndpoint(InetAddressAndPort ep)voiddoOnChangeNotifications(InetAddressAndPort addr, ApplicationState state, VersionedValue value)java.util.Map<InetAddressAndPort,EndpointState>doShadowRound()java.util.Map<InetAddressAndPort,EndpointState>doShadowRound(java.util.Set<InetAddressAndPort> peers)Do a single 'shadow' round of gossip by retrieving endpoint states that will be stored exclusively in the map return value, instead of endpointStateMap.voidexpireUpgradeFromVersion()voidforceNewerGeneration()java.lang.StringgetApplicationState(InetAddressAndPort endpoint, ApplicationState state)The value for the provided application state for the provided endpoint as currently known by this Gossip instance.intgetCurrentGenerationNumber(java.lang.String address)intgetCurrentGenerationNumber(InetAddressAndPort endpoint)intgetEndpointCount()longgetEndpointDowntime(java.lang.String address)longgetEndpointDowntime(InetAddressAndPort ep)com.google.common.collect.ImmutableSet<InetAddressAndPort>getEndpoints()EndpointStategetEndpointStateForEndpoint(InetAddressAndPort ep)protected longgetExpireTimeForEndpoint(InetAddressAndPort endpoint)java.lang.StringgetForEndpoint(InetAddressAndPort ep, ApplicationState state)java.util.UUIDgetHostId(InetAddressAndPort endpoint)java.util.UUIDgetHostId(InetAddressAndPort endpoint, java.util.Map<InetAddressAndPort,EndpointState> epStates)java.util.Set<InetAddressAndPort>getLiveMembers()java.util.Set<InetAddressAndPort>getLiveTokenOwners()CassandraVersiongetMinVersion(long delay, java.util.concurrent.TimeUnit timeUnit)CassandraVersiongetReleaseVersion(InetAddressAndPort ep)java.util.Map<java.lang.String,java.util.List<java.lang.String>>getReleaseVersionsWithPort()Returns each node's database release versionjava.util.UUIDgetSchemaVersion(InetAddressAndPort ep)java.util.List<java.lang.String>getSeeds()JMX endpoint for getting the list of seeds from the nodejava.util.Set<InetAddressAndPort>getUnreachableMembers()java.util.Set<InetAddressAndPort>getUnreachableTokenOwners()booleanhasMajorVersion3OrUnknownNodes()Returnsfalseonly if the information about the version of each node in the cluster is available and ALL the nodes are on 4.0+ (regardless of the patch version).voidinitializeNodeUnsafe(InetAddressAndPort addr, java.util.UUID uuid, int generationNbr)voidinitializeNodeUnsafe(InetAddressAndPort addr, java.util.UUID uuid, int netVersion, int generationNbr)voidinitializeUnreachableNodeUnsafe(InetAddressAndPort addr)Creates a new deadEndpointStatethat isempty.voidinjectApplicationState(InetAddressAndPort endpoint, ApplicationState state, VersionedValue value)booleaninJustRemovedEndpoints(InetAddressAndPort ep)booleanisAdministrativelyInactiveState(EndpointState epState)booleanisAdministrativelyInactiveState(InetAddressAndPort endpoint)booleanisAlive(InetAddressAndPort endpoint)booleanisDeadState(EndpointState epState)booleanisEnabled()booleanisGossipOnlyMember(InetAddressAndPort endpoint)booleanisInShadowRound()booleanisKnownEndpoint(InetAddressAndPort endpoint)booleanisSafeForStartup(InetAddressAndPort endpoint, java.util.UUID localHostUUID, boolean isBootstrapping, java.util.Map<InetAddressAndPort,EndpointState> epStates)Check if this node can safely be started and join the ring.booleanisSilentShutdownState(EndpointState epState)booleanisUpgradingFromVersionLowerThan(CassandraVersion referenceVersion)Returnstrueif there are nodes on version lower than the provided versionPair<java.lang.Boolean,CassandraVersion>isUpgradingFromVersionLowerThanC17653(CassandraVersion referenceVersion)protected voidmarkAsShutdown(InetAddressAndPort endpoint)This method is used to mark a node as shutdown; that is it gracefully exited on its own and told us about itvoidmarkDead(InetAddressAndPort addr, EndpointState localState)protected voidmaybeFinishShadowRound(InetAddressAndPort respondent, boolean isInShadowRound, java.util.Map<InetAddressAndPort,EndpointState> epStateMap)voidmaybeInitializeLocalState(int generationNbr)voidnotifyFailureDetector(java.util.Map<InetAddressAndPort,EndpointState> remoteEpStateMap)voidrealMarkAlive(InetAddressAndPort addr, EndpointState localState)voidregister(IEndpointStateChangeSubscriber subscriber)Register for interesting state changes.java.util.List<java.lang.String>reloadSeeds()JMX interface for triggering an update of the seed node list.voidremoveEndpoint(InetAddressAndPort endpoint)Removes the endpoint from Gossip but retains endpoint statevoidreplacedEndpoint(InetAddressAndPort endpoint)Remove the Endpoint and evict immediately, to avoid gossiping about this node.voidreplacementQuarantine(InetAddressAndPort endpoint)Quarantine endpoint specifically for replacement purposes.static voidrunInGossipStageBlocking(java.lang.Runnable runnable)booleanseenAnySeed()voidsetLastProcessedMessageAt(long timeInMillis)voidstart(int generationNumber)voidstart(int generationNbr, java.util.Map<ApplicationState,VersionedValue> preloadLocalStates)Start the gossiper with the generation number, preloading the map of application states before startingvoidstop()voidstopShutdownAndWait(long timeout, java.util.concurrent.TimeUnit unit)booleansufficientForStartupSafetyCheck(java.util.Map<InetAddressAndPort,EndpointState> epStateMap)voidunregister(IEndpointStateChangeSubscriber subscriber)Unregister interest for state changes.voidunsafeAnnulEndpoint(InetAddressAndPort endpoint)voidunsafeAssassinateEndpoint(java.lang.String address)java.util.Collection<InetAddressAndPort>unsafeClearRemoteState()voidunsafeGossipWith(InetAddressAndPort ep)voidunsafeSendLocalEndpointStateTo(InetAddressAndPort ep)voidunsafeSendShutdown(InetAddressAndPort to)voidunsafeSetEnabled()booleanwaitForSchemaAgreement(long maxWait, java.util.concurrent.TimeUnit unit, java.util.function.BooleanSupplier abortCondition)Blockingly wait for all live nodes to agree on the current schema version.static voidwaitToSettle()
-
-
-
Field Detail
-
MBEAN_NAME
public static final java.lang.String MBEAN_NAME
- See Also:
- Constant Field Values
-
intervalInMillis
public static final int intervalInMillis
- See Also:
- Constant Field Values
-
QUARANTINE_DELAY
public static final int QUARANTINE_DELAY
-
instance
public static final Gossiper instance
-
aVeryLongTime
public static final long aVeryLongTime
-
endpointStateMap
public final java.util.concurrent.ConcurrentMap<InetAddressAndPort,EndpointState> endpointStateMap
-
-
Method Detail
-
clearUnsafe
public void clearUnsafe()
-
expireUpgradeFromVersion
public void expireUpgradeFromVersion()
-
setLastProcessedMessageAt
public void setLastProcessedMessageAt(long timeInMillis)
-
seenAnySeed
public boolean seenAnySeed()
-
register
public void register(IEndpointStateChangeSubscriber subscriber)
Register for interesting state changes.- Parameters:
subscriber- module which implements the IEndpointStateChangeSubscriber
-
unregister
public void unregister(IEndpointStateChangeSubscriber subscriber)
Unregister interest for state changes.- Parameters:
subscriber- module which implements the IEndpointStateChangeSubscriber
-
getLiveMembers
public java.util.Set<InetAddressAndPort> getLiveMembers()
- Returns:
- a list of live gossip participants, including fat clients
-
getLiveTokenOwners
public java.util.Set<InetAddressAndPort> getLiveTokenOwners()
- Returns:
- a list of live ring members.
-
getUnreachableMembers
public java.util.Set<InetAddressAndPort> getUnreachableMembers()
- Returns:
- a list of unreachable gossip participants, including fat clients
-
getUnreachableTokenOwners
public java.util.Set<InetAddressAndPort> getUnreachableTokenOwners()
- Returns:
- a list of unreachable token owners
-
getEndpointDowntime
public long getEndpointDowntime(InetAddressAndPort ep)
-
runInGossipStageBlocking
public static void runInGossipStageBlocking(java.lang.Runnable runnable)
-
convict
public void convict(InetAddressAndPort endpoint, double phi)
This method is part of IFailureDetectionEventListener interface. This is invoked by the Failure Detector when it convicts an end point.- Specified by:
convictin interfaceIFailureDetectionEventListener- Parameters:
endpoint- end point that is convicted.phi- the value of phi with with ep was convicted
-
markAsShutdown
protected void markAsShutdown(InetAddressAndPort endpoint)
This method is used to mark a node as shutdown; that is it gracefully exited on its own and told us about it- Parameters:
endpoint- endpoint that has shut itself down
-
removeEndpoint
public void removeEndpoint(InetAddressAndPort endpoint)
Removes the endpoint from Gossip but retains endpoint state
-
unsafeAnnulEndpoint
public void unsafeAnnulEndpoint(InetAddressAndPort endpoint)
-
replacementQuarantine
public void replacementQuarantine(InetAddressAndPort endpoint)
Quarantine endpoint specifically for replacement purposes.- Parameters:
endpoint-
-
replacedEndpoint
public void replacedEndpoint(InetAddressAndPort endpoint)
Remove the Endpoint and evict immediately, to avoid gossiping about this node. This should only be called when a token is taken over by a new IP address.- Parameters:
endpoint- The endpoint that has been replaced
-
advertiseRemoving
public void advertiseRemoving(InetAddressAndPort endpoint, java.util.UUID hostId, java.util.UUID localHostId)
This method will begin removing an existing endpoint from the cluster by spoofing its state This should never be called unless this coordinator has had 'removenode' invoked- Parameters:
endpoint- - the endpoint being removedhostId- - the ID of the host being removedlocalHostId- - my own host ID for replication coordination
-
advertiseTokenRemoved
public void advertiseTokenRemoved(InetAddressAndPort endpoint, java.util.UUID hostId)
Handles switching the endpoint's state from REMOVING_TOKEN to REMOVED_TOKEN This should only be called after advertiseRemoving- Parameters:
endpoint-hostId-
-
unsafeAssassinateEndpoint
public void unsafeAssassinateEndpoint(java.lang.String address) throws java.net.UnknownHostException- Specified by:
unsafeAssassinateEndpointin interfaceGossiperMBean- Throws:
java.net.UnknownHostException
-
assassinateEndpoint
public void assassinateEndpoint(java.lang.String address) throws java.net.UnknownHostExceptionDo not call this method unless you know what you are doing. It will try extremely hard to obliterate any endpoint from the ring, even if it does not know about it.- Specified by:
assassinateEndpointin interfaceGossiperMBean- Parameters:
address-- Throws:
java.net.UnknownHostException
-
isKnownEndpoint
public boolean isKnownEndpoint(InetAddressAndPort endpoint)
-
getCurrentGenerationNumber
public int getCurrentGenerationNumber(InetAddressAndPort endpoint)
-
isGossipOnlyMember
public boolean isGossipOnlyMember(InetAddressAndPort endpoint)
-
isSafeForStartup
public boolean isSafeForStartup(InetAddressAndPort endpoint, java.util.UUID localHostUUID, boolean isBootstrapping, java.util.Map<InetAddressAndPort,EndpointState> epStates)
Check if this node can safely be started and join the ring. If the node is bootstrapping, examines gossip state for any previous status to decide whether it's safe to allow this node to start and bootstrap. If not bootstrapping, compares the host ID that the node itself has (obtained by reading from system.local or generated if not present) with the host ID obtained from gossip for the endpoint address (if any). This latter case prevents a non-bootstrapping, new node from being started with the same address of a previously started, but currently down predecessor.- Parameters:
endpoint- - the endpoint to checklocalHostUUID- - the host id to checkisBootstrapping- - whether the node intends to bootstrap when joiningepStates- - endpoint states in the cluster- Returns:
- true if it is safe to start the node, false otherwise
-
getExpireTimeForEndpoint
protected long getExpireTimeForEndpoint(InetAddressAndPort endpoint)
-
getEndpointStateForEndpoint
public EndpointState getEndpointStateForEndpoint(InetAddressAndPort ep)
-
inJustRemovedEndpoints
public boolean inJustRemovedEndpoints(InetAddressAndPort ep)
-
copyEndpointStateForEndpoint
public EndpointState copyEndpointStateForEndpoint(InetAddressAndPort ep)
-
getEndpoints
public com.google.common.collect.ImmutableSet<InetAddressAndPort> getEndpoints()
-
getForEndpoint
public java.lang.String getForEndpoint(InetAddressAndPort ep, ApplicationState state)
-
getEndpointCount
public int getEndpointCount()
-
getHostId
public java.util.UUID getHostId(InetAddressAndPort endpoint)
-
getHostId
public java.util.UUID getHostId(InetAddressAndPort endpoint, java.util.Map<InetAddressAndPort,EndpointState> epStates)
-
getApplicationState
public java.lang.String getApplicationState(InetAddressAndPort endpoint, ApplicationState state)
The value for the provided application state for the provided endpoint as currently known by this Gossip instance.- Parameters:
endpoint- the endpoint from which to get the endpoint state.state- the endpoint state to get.- Returns:
- the value of the application state
stateforendpoint, ornullif eitherendpointis not known by Gossip or has no value forstate.
-
compareEndpointStartup
public int compareEndpointStartup(InetAddressAndPort addr1, InetAddressAndPort addr2)
determine which endpoint started up earlier
-
notifyFailureDetector
public void notifyFailureDetector(java.util.Map<InetAddressAndPort,EndpointState> remoteEpStateMap)
-
realMarkAlive
public void realMarkAlive(InetAddressAndPort addr, EndpointState localState)
-
markDead
public void markDead(InetAddressAndPort addr, EndpointState localState)
-
isAlive
public boolean isAlive(InetAddressAndPort endpoint)
-
isDeadState
public boolean isDeadState(EndpointState epState)
-
isSilentShutdownState
public boolean isSilentShutdownState(EndpointState epState)
-
isAdministrativelyInactiveState
public boolean isAdministrativelyInactiveState(EndpointState epState)
-
isAdministrativelyInactiveState
public boolean isAdministrativelyInactiveState(InetAddressAndPort endpoint)
-
applyStateLocally
public void applyStateLocally(java.util.Map<InetAddressAndPort,EndpointState> epStateMap)
-
doOnChangeNotifications
public void doOnChangeNotifications(InetAddressAndPort addr, ApplicationState state, VersionedValue value)
-
start
public void start(int generationNumber)
-
start
public void start(int generationNbr, java.util.Map<ApplicationState,VersionedValue> preloadLocalStates)Start the gossiper with the generation number, preloading the map of application states before starting
-
doShadowRound
public java.util.Map<InetAddressAndPort,EndpointState> doShadowRound()
-
doShadowRound
public java.util.Map<InetAddressAndPort,EndpointState> doShadowRound(java.util.Set<InetAddressAndPort> peers)
Do a single 'shadow' round of gossip by retrieving endpoint states that will be stored exclusively in the map return value, instead of endpointStateMap. Used when preparing to join the ring:- when replacing a node, to get and assume its tokens
- when joining, to check that the local host id matches any previous id for the endpoint address
maybeFinishShadowRound(InetAddressAndPort, boolean, Map). This will updateendpointShadowStateMapwith received values, in order to return an immutable copy to the caller ofdoShadowRound(). Therefor only a single shadow round execution is permitted at the same time.- Parameters:
peers- Additional peers to try gossiping with.- Returns:
- endpoint states gathered during shadow round or empty map
-
reloadSeeds
public java.util.List<java.lang.String> reloadSeeds()
JMX interface for triggering an update of the seed node list.- Specified by:
reloadSeedsin interfaceGossiperMBean
-
getSeeds
public java.util.List<java.lang.String> getSeeds()
JMX endpoint for getting the list of seeds from the node- Specified by:
getSeedsin interfaceGossiperMBean
-
maybeInitializeLocalState
public void maybeInitializeLocalState(int generationNbr)
-
forceNewerGeneration
public void forceNewerGeneration()
-
addSavedEndpoint
public void addSavedEndpoint(InetAddressAndPort ep)
Add an endpoint we knew about previously, but whose state is unknown
-
addLocalApplicationState
public void addLocalApplicationState(ApplicationState applicationState, VersionedValue value)
-
addLocalApplicationStates
public void addLocalApplicationStates(java.util.List<Pair<ApplicationState,VersionedValue>> states)
-
stop
public void stop()
-
isEnabled
public boolean isEnabled()
-
sufficientForStartupSafetyCheck
public boolean sufficientForStartupSafetyCheck(java.util.Map<InetAddressAndPort,EndpointState> epStateMap)
-
maybeFinishShadowRound
protected void maybeFinishShadowRound(InetAddressAndPort respondent, boolean isInShadowRound, java.util.Map<InetAddressAndPort,EndpointState> epStateMap)
-
isInShadowRound
public boolean isInShadowRound()
-
initializeUnreachableNodeUnsafe
public void initializeUnreachableNodeUnsafe(InetAddressAndPort addr)
Creates a new deadEndpointStatethat isempty. This is used during host replacement for edge cases where the seed notified that the endpoint was empty, so need to add such state into gossip explicitly (as empty endpoints are not gossiped outside of the shadow round). see CASSANDRA-16213
-
initializeNodeUnsafe
public void initializeNodeUnsafe(InetAddressAndPort addr, java.util.UUID uuid, int generationNbr)
-
initializeNodeUnsafe
public void initializeNodeUnsafe(InetAddressAndPort addr, java.util.UUID uuid, int netVersion, int generationNbr)
-
injectApplicationState
public void injectApplicationState(InetAddressAndPort endpoint, ApplicationState state, VersionedValue value)
-
getEndpointDowntime
public long getEndpointDowntime(java.lang.String address) throws java.net.UnknownHostException- Specified by:
getEndpointDowntimein interfaceGossiperMBean- Throws:
java.net.UnknownHostException
-
getCurrentGenerationNumber
public int getCurrentGenerationNumber(java.lang.String address) throws java.net.UnknownHostException- Specified by:
getCurrentGenerationNumberin interfaceGossiperMBean- Throws:
java.net.UnknownHostException
-
addExpireTimeForEndpoint
public void addExpireTimeForEndpoint(InetAddressAndPort endpoint, long expireTime)
-
computeExpireTime
public static long computeExpireTime()
-
getReleaseVersion
@Nullable public CassandraVersion getReleaseVersion(InetAddressAndPort ep)
-
getReleaseVersionsWithPort
public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getReleaseVersionsWithPort()
Description copied from interface:GossiperMBeanReturns each node's database release version- Specified by:
getReleaseVersionsWithPortin interfaceGossiperMBean
-
getSchemaVersion
@Nullable public java.util.UUID getSchemaVersion(InetAddressAndPort ep)
-
waitToSettle
public static void waitToSettle()
-
waitForSchemaAgreement
public boolean waitForSchemaAgreement(long maxWait, java.util.concurrent.TimeUnit unit, java.util.function.BooleanSupplier abortCondition)Blockingly wait for all live nodes to agree on the current schema version.- Parameters:
maxWait- maximum time to wait for schema agreementunit- TimeUnit of maxWait- Returns:
- true if agreement was reached, false if not
-
hasMajorVersion3OrUnknownNodes
public boolean hasMajorVersion3OrUnknownNodes()
Returnsfalseonly if the information about the version of each node in the cluster is available and ALL the nodes are on 4.0+ (regardless of the patch version).
-
isUpgradingFromVersionLowerThan
public boolean isUpgradingFromVersionLowerThan(CassandraVersion referenceVersion)
Returnstrueif there are nodes on version lower than the provided version
-
isUpgradingFromVersionLowerThanC17653
public Pair<java.lang.Boolean,CassandraVersion> isUpgradingFromVersionLowerThanC17653(CassandraVersion referenceVersion)
-
stopShutdownAndWait
public void stopShutdownAndWait(long timeout, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException, java.util.concurrent.TimeoutException- Throws:
java.lang.InterruptedExceptionjava.util.concurrent.TimeoutException
-
getMinVersion
@Nullable public CassandraVersion getMinVersion(long delay, java.util.concurrent.TimeUnit timeUnit)
-
unsafeSetEnabled
public void unsafeSetEnabled()
-
unsafeClearRemoteState
public java.util.Collection<InetAddressAndPort> unsafeClearRemoteState()
-
unsafeGossipWith
public void unsafeGossipWith(InetAddressAndPort ep)
-
unsafeSendShutdown
public void unsafeSendShutdown(InetAddressAndPort to)
-
unsafeSendLocalEndpointStateTo
public void unsafeSendLocalEndpointStateTo(InetAddressAndPort ep)
-
compareGossipAndTokenMetadata
public java.util.Map<java.lang.String,java.util.List<java.lang.String>> compareGossipAndTokenMetadata()
Description copied from interface:GossiperMBeanReturns a map of endpoints that don't have matching tokenMetadata to gossip tokens. Values are lists of fixed size two (as Pair is not jmx safe), the first is the gossip tokens, the second tokenMetadata).- Specified by:
compareGossipAndTokenMetadatain interfaceGossiperMBean
-
-