public class PeerSelector extends Object
penalize(Peer, long)) to avoid
sending/receiving data from them. Attempts are made to balance communications ("busier"
nodes will TransferDirection.SEND more and TransferDirection.RECEIVE fewer
flowfiles from this instance).| Modifier and Type | Field and Description |
|---|---|
private EventReporter |
eventReporter |
private static org.slf4j.Logger |
logger |
private static long |
PEER_CACHE_MILLIS |
private ConcurrentMap<PeerDescription,Long> |
peerPenaltyExpirations |
private PeerPersistence |
peerPersistence |
private PeerStatusCache |
peerStatusCache |
private PeerStatusProvider |
peerStatusProvider |
| Constructor and Description |
|---|
PeerSelector(PeerStatusProvider peerStatusProvider,
PeerPersistence peerPersistence)
Returns a peer selector with the provided collaborators.
|
| Modifier and Type | Method and Description |
|---|---|
(package private) LinkedHashMap<PeerStatus,Double> |
buildWeightedPeerMap(Set<PeerStatus> statuses,
TransferDirection direction)
Returns a map of peers prepared for flowfile transfer in the specified direction.
|
private static double |
calculateNormalizedWeight(TransferDirection direction,
long totalFlowFileCount,
int flowFileCount,
int peerCount)
Returns the normalized weight for this ratio of peer flowfiles to total flowfiles and the given direction.
|
void |
clear()
Resets all penalization states for the peers.
|
private @NotNull Map<PeerStatus,Double> |
createDestinationMap(Set<PeerStatus> peerStatuses,
TransferDirection direction)
Returns a map indexed by a peer to the normalized weight (number of flowfiles currently being
processed by the peer as a percentage of the total).
|
private Set<PeerStatus> |
fetchRemotePeerStatuses(Set<PeerDescription> peersToRequestClusterInfoFrom)
Returns a set of
PeerStatus objects representing all remote peers for the provided
PeerDescriptions. |
private PeerStatus |
getAvailablePeerStatus(Map<PeerStatus,Double> orderedPeerStatuses)
Returns the
PeerStatus identifying the next peer to send/receive data. |
private long |
getCacheAge()
Returns the cache age in milliseconds.
|
private @NotNull Set<PeerStatus> |
getLastFetchedQueryablePeers()
Returns the set of queryable peers (
PeerStatus.isQueryForPeers()) most recently fetched. |
PeerStatus |
getNextPeerStatus(TransferDirection direction)
Return status of a peer that will be used for the next communication.
|
private @NotNull Set<PeerStatus> |
getPeerStatuses()
Returns the set of peer statuses.
|
private Set<PeerDescription> |
getPeersToQuery()
Returns the set of
PeerDescription objects uniquely identifying each NiFi node which should be queried for PeerStatus. |
private boolean |
isCacheExpired(PeerStatusCache cache)
Returns
true if this cache has expired. |
private boolean |
isPeerRefreshNeeded()
Returns
true if the internal collection of peers is empty or the refresh time has passed. |
boolean |
isPenalized(PeerStatus peerStatus)
Returns
true if this peer is currently penalized and should not send/receive flowfiles. |
void |
penalize(PeerDescription peerDescription,
long penalizationMillis)
Updates internal state map to penalize a PeerStatus that points to the
specified peer.
|
void |
penalize(Peer peer,
long penalizationMillis)
Updates internal state map to penalize a PeerStatus that points to the
specified peer.
|
private void |
persistPeerStatuses(PeerStatusCache peerStatusCache)
Persists the provided cache instance (in memory and via the
PeerPersistence (e.g. |
private static void |
printDistributionStatistics(Map<PeerStatus,Double> sortedPeerWorkloads,
TransferDirection direction)
Prints the distribution of the peers to the logger.
|
void |
refresh()
Allows for external callers to trigger a refresh of the internal peer status cache.
|
private void |
refreshPeerStatusCache()
Refreshes the list of S2S peers that flowfiles can be sent to or received from.
|
private void |
restoreInitialPeerStatusCache()
Populates the peer status cache from the peer persistence provider (e.g.
|
void |
setEventReporter(EventReporter eventReporter)
Sets the event reporter instance.
|
private static LinkedHashMap<PeerStatus,Double> |
sortMapByWeight(Map<PeerStatus,Double> unsortedMap)
Returns an ordered map of peers sorted in descending order by value (relative weight).
|
private static double |
sumMapValues(Map<PeerStatus,Double> peerWeightMap)
Returns the total of all values in the map.
|
private static final org.slf4j.Logger logger
private static final long PEER_CACHE_MILLIS
private final PeerPersistence peerPersistence
private final PeerStatusProvider peerStatusProvider
private final ConcurrentMap<PeerDescription,Long> peerPenaltyExpirations
private volatile PeerStatusCache peerStatusCache
private EventReporter eventReporter
public PeerSelector(PeerStatusProvider peerStatusProvider, PeerPersistence peerPersistence)
peerStatusProvider - the service which retrieves peer statepeerPersistence - the service which persists peer stateprivate void restoreInitialPeerStatusCache()
private static double calculateNormalizedWeight(TransferDirection direction, long totalFlowFileCount, int flowFileCount, int peerCount)
direction - the transfer direction (SEND weights the destinations higher if they have fewer flowfiles, RECEIVE weights them higher if they have more)totalFlowFileCount - the total flowfile count in the remote instance (standalone or cluster)flowFileCount - the flowfile count for the given peerpeerCount - the number of peers in the remote instanceprivate static LinkedHashMap<PeerStatus,Double> sortMapByWeight(Map<PeerStatus,Double> unsortedMap)
unsortedMap - the unordered map of peers to weightsprivate static void printDistributionStatistics(Map<PeerStatus,Double> sortedPeerWorkloads, TransferDirection direction)
sortedPeerWorkloads - the peers and relative weightsprivate static double sumMapValues(Map<PeerStatus,Double> peerWeightMap)
peerWeightMap - the map of peers to flowfile counts or relative weightspublic void clear()
public PeerStatus getNextPeerStatus(TransferDirection direction)
direction - the amount of workload is calculated based on transaction direction,
for SEND, a peer with fewer flow files is preferred,
for RECEIVE, a peer with more flow files is preferredpublic boolean isPenalized(PeerStatus peerStatus)
true if this peer is currently penalized and should not send/receive flowfiles.peerStatus - the peer status identifying the peerpublic void penalize(Peer peer, long penalizationMillis)
peer - the peerpenalizationMillis - period of time to penalize a given peer (relative time, not absolute)public void penalize(PeerDescription peerDescription, long penalizationMillis)
peerDescription - the peer description (identifies the peer)penalizationMillis - period of time to penalize a given peer (relative time, not absolute)public void refresh()
public void setEventReporter(EventReporter eventReporter)
eventReporter - the event reporterLinkedHashMap<PeerStatus,Double> buildWeightedPeerMap(Set<PeerStatus> statuses, TransferDirection direction)
SEND will be [A:40.0, B:35.0, C:25.0] (1 - .2 => .8 * 100 / (3-1)) => 40.0).statuses - the set of all peersdirection - the direction of transfer (SEND weights the destinations higher if they have more flowfiles, RECEIVE weights them higher if they have fewer)@NotNull private @NotNull Map<PeerStatus,Double> createDestinationMap(Set<PeerStatus> peerStatuses, TransferDirection direction)
peerStatuses - the set of peers, along with their current workload (number of flowfiles)direction - whether sending flowfiles to these peers or receiving themprivate Set<PeerStatus> fetchRemotePeerStatuses(Set<PeerDescription> peersToRequestClusterInfoFrom) throws IOException
PeerStatus objects representing all remote peers for the provided
PeerDescriptions. If a queried peer returns updated state on a peer which has already
been captured, the new state is used.
Example:
3 node cluster with nodes A, B, C
Node A knows about Node B and Node C, B about A and C, etc.
Action | Statuses
query(A) -> B.status, C.status | Bs1, Cs1
query(B) -> A.status, C.status | As1, Bs1, Cs2
query(C) -> A.status, B.status | As2, Bs2, Cs2
peersToRequestClusterInfoFrom - the set of peers to queryIOException - if there is a problem fetching peer statusesprivate PeerStatus getAvailablePeerStatus(Map<PeerStatus,Double> orderedPeerStatuses)
PeerStatus identifying the next peer to send/receive data. This uses random
selection of peers, weighted by the relative desirability (i.e. for SEND, peers with more
flowfiles are more likely to be selected, and for RECEIVE, peers with fewer flowfiles are
more likely).orderedPeerStatuses - the map of peers to relative weights, sorted in descending order by weightprivate long getCacheAge()
-1.@NotNull private @NotNull Set<PeerStatus> getLastFetchedQueryablePeers()
PeerStatus.isQueryForPeers()) most recently fetched.null)@NotNull private @NotNull Set<PeerStatus> getPeerStatuses()
null or empty, refreshes the cache first and then returns the new peer status set.null)private Set<PeerDescription> getPeersToQuery() throws IOException
PeerDescription objects uniquely identifying each NiFi node which should be queried for PeerStatus.IOException - if there is a problem retrieving the list of peers to queryprivate boolean isCacheExpired(PeerStatusCache cache)
true if this cache has expired.cache - the peer status cacheprivate boolean isPeerRefreshNeeded()
true if the internal collection of peers is empty or the refresh time has passed.private void persistPeerStatuses(PeerStatusCache peerStatusCache)
PeerPersistence (e.g. in cluster state or a local file)) for future retrieval.peerStatusCache - the cache of current peer statuses to persistprivate void refreshPeerStatusCache()
Copyright © 2023 Apache NiFi Project. All rights reserved.