Package org.apache.hadoop.hbase.rsgroup
Class RSGroupInfoManagerImpl
java.lang.Object
org.apache.hadoop.hbase.rsgroup.RSGroupInfoManagerImpl
- All Implemented Interfaces:
RSGroupInfoManager
This is an implementation of
RSGroupInfoManager which makes use of an HBase table as the
persistence store for the group information. It also makes use of zookeeper to store group
information needed for bootstrapping during offline mode.
Admin-managed and auto-managed groups
An admin-managed group is a non-default group that is not regex-governed (seehbase.rsgroup.regex.<group>). Its servers are set
by an administrator and are stored in hbase:rsgroup and ZooKeeper. A group whose regex is invalid
is admin-managed until the regex is fixed. In that time the servers that the group holds in
memory count as admin-managed when the membership is computed
(resolveRegexBasedRSGroupMembership). After a master restart the group holds only what
was stored at the last flush.
An auto-managed group is 'default' or a regex-governed group. Its servers are computed
from the live servers and, while the regex is valid, are not stored in hbase:rsgroup and
ZooKeeper.
Auto-managed groups exist to make RSGroup work with auto-scaling when HBase runs in a cloud
environment such as AWS or GCP. An admin-managed group does not give the elasticity that
automatic upscaling and downscaling need: each new RegionServer must be moved into the group by
hand. It fits a fixed number of RegionServers, for example to host internal system tables like
hbase:meta and hbase:namespace. End user facing tables must be placed on an elastic group, so
RegionServers join and leave it automatically. That is the need for auto-managed groups.
Concurrency
RSGroup state is kept locally in Maps. There is a rsgroup name to cached RSGroupInfo Map atRSGroupInfoManagerImpl.RSGroupInfoHolder.groupName2Group. These Maps are persisted to the
hbase:rsgroup table (and cached in zk) on each modification.
Mutations on state are synchronized but reads can continue without having to wait on an instance
monitor, mutations do wholesale replace of the Maps on update -- Copy-On-Write; the local Maps of
state are read-only, just-in-case (see flushConfig).
Reads must not block else there is a danger we'll deadlock.
Clients of this class, the RSGroupAdminEndpoint for example, want to query and then act
on the results of the query modifying cache in zookeeper without another thread making
intermediate modifications. These clients synchronize on the 'this' instance so no other has
access concurrently. Reads must be able to continue concurrently.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static final classprivate static final class(package private) static classprivate classprivate class -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final AsyncClusterConnection(package private) static final intDefine the default number of retries(package private) static final StringDefine the config key of retries threshold when movements failedprivate static final Pattern(package private) static final Stringprivate static final org.slf4j.Loggerprivate final MasterServices(package private) static final byte[](package private) static final byte[](package private) static final Stringprivate static final byte[](package private) static final StringConfig key prefix;hbase.rsgroup.regex.<groupname>=<regex>private static final Stringprivate static final TableDescriptorTable descriptor forhbase:rsgroupcatalog table(package private) static final TableNameprivate final RSGroupInfoManagerImpl.RSGroupStartupWorkerprivate final RSGroupInfoManagerImpl.ServerEventsListenerprivate final ZKWatcher -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate voidaddRegion(LinkedList<RegionInfo> regions, RegionInfo hri) voidaddRSGroup(RSGroupInfo rsGroupInfo) Add given RSGroupInfo to existing list of group infos.private static voidapplyAutoManagedRSGroupServers(Map<String, RSGroupInfo> groupMap, Map<String, SortedSet<Address>> newRSGroupToServers) balanceRSGroup(String groupName, BalanceRequest request) Balance a region server group.private voidcheckForDeadOrOnlineServers(Set<Address> servers) Check if the set of servers are belong to dead servers list or online servers list.private voidcheckGroupName(String groupName) private voidcheckMoveAgreesWithRegex(Set<Address> movedServers, String dstGroup) Regex-based membership always wins: the next server event or refresh puts a server back where its hostname says, so an explicit move that disagrees would only make regions flap.private voidcheckOnlineServersOnly(Set<Address> servers) computeAutoManagedRSGroupServers(Collection<RSGroupInfo> existingGroups) private static RSGroupInfocopyOf(RSGroupInfo src) Returns a copy ofsrc, safe to mutate without affecting the liveholder.groupName2Groupentry -- callers must not mutate the object returned bygetRSGroupInfo(java.lang.String)orgetRSGroupOfServer(org.apache.hadoop.hbase.net.Address)in place, since a subsequentflushConfig(Map)can still reject the change and the live state must stay untouched until the change is actually persisted.determineRSGroupInfoForTable(TableName tableName) DetermineRSGroupInfofor the given table.private static voiddropRegexGovernedServersFromOtherGroups(Map<String, RSGroupInfo> groupMap, Map<String, SortedSet<Address>> autoManagedServers) Stored membership of admin-managed groups is not recomputed on refresh, so a server that was placed in one of them before a regex claimed it would end up in two groups.private voidprivate voidflushConfig(Map<String, RSGroupInfo> newGroupMap) private voidflushConfigTable(Map<String, RSGroupInfo> groupMap) (package private) static RSGroupInfoManagergetInstance(MasterServices masterServices) getMatchingRSGroupNames(String hostname, Map<String, Pattern> rsGroupNameToPatternMap) Returns Set of online Servers named for their hostname and port (not ServerName).getRegexGroupMap(org.apache.hadoop.conf.Configuration conf) Parseshbase.rsgroup.regex.<groupname>=<regex>entries out ofconf.private List<RegionInfo>getRegions(Address server) Returns List of Regions associated with thisserver.getRSGroup(String groupName) GetsRSGroupInfofor the given group name.(package private) Map<TableName,Map<ServerName, List<RegionInfo>>> getRSGroupAssignmentsByTable(TableStateManager tableStateManager, String groupName) This is an EXPENSIVE clone.getRSGroupForTable(TableName tableName) GetRSGroupInfofor the given table.private RSGroupInfogetRSGroupInfo(String groupName) getRSGroupOfServer(Address serverHostPort) Gets the group info of server.private voidCalled synchronously fromServerListener#serverAdded/#serverRemoved.private voidinit()private static booleanisMasterRunning(MasterServices masterServices) booleanisOnline()Whether the manager is able to fully return group metadataprivate booleanisTableInGroup(TableName tableName, String groupName, Set<TableName> tablesInGroupCache) List the existingRSGroupInfos.private voidmigrate()private voidmigrate(Collection<RSGroupInfo> groupList) private <T> voidmoveRegionsBetweenGroups(Set<T> regionsOwners, Set<Address> newRegionsOwners, String targetGroupName, String sourceGroupName, Function<T, List<RegionInfo>> getRegionsInfo, Function<RegionInfo, Boolean> validation) private voidmoveServerRegionsFromGroup(Set<Address> movedServers, Set<Address> srcGrpServers, String targetGroupName, String sourceGroupName) Move every region from servers which are currently located on these servers, but should not be located there.voidmoveServers(Set<Address> servers, String targetGroupName) Move servers to a new group.moveServers(Set<Address> servers, String srcGroup, String dstGroup) private voidmoveTablesAndWait(Set<TableName> tables, String targetGroup) private voidmultiMutate(List<Mutation> mutations) private voidrefresh(boolean forceOnline) Read rsgroup info from the source of truth, the hbase:rsgroup table.voidremoveRSGroup(String groupName) Remove a region server group.voidremoveServers(Set<Address> servers) Remove decommissioned servers from rsgroupvoidrenameRSGroup(String oldName, String newName) Rename rsgroupprivate voidresetRSGroupMap(Map<String, RSGroupInfo> newRSGroupMap) Make changes visible.(package private) static RSGroupInfoManagerImpl.RegexBasedRSGroupMembershipResolutionresolveRegexBasedRSGroupMembership(Map<String, Pattern> rsGroupNameToPatternMap, Set<Address> onlineServers, Collection<RSGroupInfo> existingGroups) resolveServerAddrToRSGroupName(Set<Address> onlineServers, Map<String, Pattern> rsGroupNameToPatternMap, Set<String> existingGroupNames) Resolves every server inonlineServerswhose hostname unambiguously matches exactly one entry ofrsGroupNameToPatternMapnaming a group inexistingGroupNames.private List<RSGroupInfo>private List<RSGroupInfo>private Map<String,RegionState> rsGroupGetRegionsInTransition(String groupName) private voidsaveRSGroupMapToZK(Map<String, RSGroupInfo> newGroupMap) voidsetRSGroup(Set<TableName> tables, String groupName) Set group for tables.voidstart()private voidupdateCacheOfRSGroups(Set<String> currentGroups) Update cache of rsgroups.voidupdateRSGroupConfig(String groupName, Map<String, String> configuration) Update RSGroup configurationprivate voidwaitForRegionMovement(List<Pair<RegionInfo, Future<byte[]>>> regionMoveFutures, Set<String> failedRegions, String sourceGroupName, int retryCount) Wait for all the region move to complete.private Map<String,RSGroupInfo> withoutRegexGovernedServers(Map<String, RSGroupInfo> groupMap) Returns a copy ofgroupMapwhere every regex-governed group has an empty server set.(package private) static booleanwouldEmptyDefaultGroup(Set<Address> onlineServers, Set<Address> adminManagedServers, Set<Address> regexMatchedServers) Returnstrueif every online server is either admin-managed or regex-matched.
-
Field Details
-
LOG
-
RSGROUP_TABLE_NAME
-
KEEP_ONE_SERVER_IN_DEFAULT_ERROR_MESSAGE
- See Also:
-
FAILED_MOVE_MAX_RETRY
Define the config key of retries threshold when movements failed- See Also:
-
DEFAULT_MAX_RETRY_VALUE
Define the default number of retries- See Also:
-
RS_GROUP_REGEX_PREFIX
Config key prefix;hbase.rsgroup.regex.<groupname>=<regex>- See Also:
-
GROUP_NAME_PATTERN
-
RS_GROUP_ZNODE
- See Also:
-
META_FAMILY_BYTES
-
META_QUALIFIER_BYTES
-
MIGRATE_THREAD_NAME
- See Also:
-
ROW_KEY
-
RSGROUP_TABLE_DESC
Table descriptor forhbase:rsgroupcatalog table -
holder
-
masterServices
-
conn
-
watcher
-
rsGroupStartupWorker
-
serverEventsListener
-
prevRSGroups
-
script
-
-
Constructor Details
-
RSGroupInfoManagerImpl
-
-
Method Details
-
handleServerEvent
Called synchronously fromServerListener#serverAdded/#serverRemoved. Server membership of 'default' and of every regex-governed group is never persisted, so it is recomputed from the live servers and applied in memory only -- nohbase:rsgroup/ZK I/O. -
init
- Throws:
IOException
-
getInstance
- Throws:
IOException
-
start
- Specified by:
startin interfaceRSGroupInfoManager
-
addRSGroup
Description copied from interface:RSGroupInfoManagerAdd given RSGroupInfo to existing list of group infos.- Specified by:
addRSGroupin interfaceRSGroupInfoManager- Throws:
IOException
-
getRSGroupInfo
- Throws:
ConstraintException
-
getOnlineServers
Returns Set of online Servers named for their hostname and port (not ServerName). -
copyOf
Returns a copy ofsrc, safe to mutate without affecting the liveholder.groupName2Groupentry -- callers must not mutate the object returned bygetRSGroupInfo(java.lang.String)orgetRSGroupOfServer(org.apache.hadoop.hbase.net.Address)in place, since a subsequentflushConfig(Map)can still reject the change and the live state must stay untouched until the change is actually persisted. -
moveServers
public Set<Address> moveServers(Set<Address> servers, String srcGroup, String dstGroup) throws IOException - Throws:
IOException
-
checkMoveAgreesWithRegex
private void checkMoveAgreesWithRegex(Set<Address> movedServers, String dstGroup) throws ConstraintException Regex-based membership always wins: the next server event or refresh puts a server back where its hostname says, so an explicit move that disagrees would only make regions flap. Such a move is rejected. A server whose hostname matches no regex (or an ambiguous or dangling one, which fall back to ordinary placement) may go anywhere except into a regex-governed group.- Throws:
ConstraintException
-
getRSGroupOfServer
Description copied from interface:RSGroupInfoManagerGets the group info of server.- Specified by:
getRSGroupOfServerin interfaceRSGroupInfoManager
-
getRSGroup
Description copied from interface:RSGroupInfoManagerGetsRSGroupInfofor the given group name.- Specified by:
getRSGroupin interfaceRSGroupInfoManager
-
removeRSGroup
Description copied from interface:RSGroupInfoManagerRemove a region server group.- Specified by:
removeRSGroupin interfaceRSGroupInfoManager- Throws:
IOException
-
listRSGroups
Description copied from interface:RSGroupInfoManagerList the existingRSGroupInfos.- Specified by:
listRSGroupsin interfaceRSGroupInfoManager
-
isOnline
Description copied from interface:RSGroupInfoManagerWhether the manager is able to fully return group metadata- Specified by:
isOnlinein interfaceRSGroupInfoManager- Returns:
- whether the manager is in online mode
-
removeServers
Description copied from interface:RSGroupInfoManagerRemove decommissioned servers from rsgroup- Specified by:
removeServersin interfaceRSGroupInfoManager- Parameters:
servers- set of servers to remove- Throws:
IOException
-
retrieveGroupListFromGroupTable
- Throws:
IOException
-
retrieveGroupListFromZookeeper
- Throws:
IOException
-
migrate
-
migrate
-
refresh
Read rsgroup info from the source of truth, the hbase:rsgroup table. Update zk cache. Called on startup of the manager.- Throws:
IOException
-
flushConfigTable
- Throws:
IOException
-
flushConfig
- Throws:
IOException
-
flushConfig
- Throws:
IOException
-
withoutRegexGovernedServers
Returns a copy ofgroupMapwhere every regex-governed group has an empty server set. Their membership is recomputed from the live servers (seerefresh(boolean)), so persisting it would only add I/O and leave stale data behind. -
saveRSGroupMapToZK
- Throws:
IOException
-
resetRSGroupMap
Make changes visible. Caller must be synchronized on 'this'. -
updateCacheOfRSGroups
Update cache of rsgroups. Caller must be synchronized on 'this'.- Parameters:
currentGroups- Current list of Groups.
-
getRegexGroupMap
Parseshbase.rsgroup.regex.<groupname>=<regex>entries out ofconf. Entries with an invalid group name, targeting the reservedRSGroupInfo.DEFAULT_GROUP, or with an unparsable regex are logged and skipped. -
getMatchingRSGroupNames
-
resolveServerAddrToRSGroupName
static Map<Address,String> resolveServerAddrToRSGroupName(Set<Address> onlineServers, Map<String, Pattern> rsGroupNameToPatternMap, Set<String> existingGroupNames) Resolves every server inonlineServerswhose hostname unambiguously matches exactly one entry ofrsGroupNameToPatternMapnaming a group inexistingGroupNames. A server matching multiple regexes, or matching a regex for a group that does not (yet) exist, is omitted (warn-only) rather than resolved. -
wouldEmptyDefaultGroup
static boolean wouldEmptyDefaultGroup(Set<Address> onlineServers, Set<Address> adminManagedServers, Set<Address> regexMatchedServers) Returnstrueif every online server is either admin-managed or regex-matched. -
resolveRegexBasedRSGroupMembership
static RSGroupInfoManagerImpl.RegexBasedRSGroupMembershipResolution resolveRegexBasedRSGroupMembership(Map<String, Pattern> rsGroupNameToPatternMap, Set<Address> onlineServers, Collection<RSGroupInfo> existingGroups) -
computeAutoManagedRSGroupServers
private Map<String,SortedSet<Address>> computeAutoManagedRSGroupServers(Collection<RSGroupInfo> existingGroups) -
applyAutoManagedRSGroupServers
private static void applyAutoManagedRSGroupServers(Map<String, RSGroupInfo> groupMap, Map<String, SortedSet<Address>> newRSGroupToServers) -
dropRegexGovernedServersFromOtherGroups
private static void dropRegexGovernedServersFromOtherGroups(Map<String, RSGroupInfo> groupMap, Map<String, SortedSet<Address>> autoManagedServers) Stored membership of admin-managed groups is not recomputed on refresh, so a server that was placed in one of them before a regex claimed it would end up in two groups. Unlike the runtime paths, refresh cannot reject this: it runs in the startup worker, which retries forever on failure and would keep the manager offline. Instead, resolve it the waycomputeAutoManagedRSGroupServers(java.util.Collection<org.apache.hadoop.hbase.rsgroup.RSGroupInfo>)already does -- the regex wins -- in memory only; storage is corrected by the next flush. -
isMasterRunning
-
multiMutate
- Throws:
IOException
-
checkGroupName
- Throws:
ConstraintException
-
getRSGroupForTable
Description copied from interface:RSGroupInfoManagerGetRSGroupInfofor the given table.- Specified by:
getRSGroupForTablein interfaceRSGroupInfoManager- Throws:
IOException
-
checkForDeadOrOnlineServers
Check if the set of servers are belong to dead servers list or online servers list.- Parameters:
servers- servers to remove- Throws:
IOException
-
checkOnlineServersOnly
- Throws:
IOException
-
getRegions
Returns List of Regions associated with thisserver. -
addRegion
-
moveServerRegionsFromGroup
private void moveServerRegionsFromGroup(Set<Address> movedServers, Set<Address> srcGrpServers, String targetGroupName, String sourceGroupName) throws IOException Move every region from servers which are currently located on these servers, but should not be located there.- Parameters:
movedServers- the servers that are moved to new groupsrcGrpServers- all servers in the source group, excluding the movedServerstargetGroupName- the target groupsourceGroupName- the source group- Throws:
IOException- if moving the server and tables fail
-
moveRegionsBetweenGroups
private <T> void moveRegionsBetweenGroups(Set<T> regionsOwners, Set<Address> newRegionsOwners, String targetGroupName, String sourceGroupName, Function<T, List<RegionInfo>> getRegionsInfo, Function<RegionInfo, throws IOExceptionBoolean> validation) - Throws:
IOException
-
waitForRegionMovement
private void waitForRegionMovement(List<Pair<RegionInfo, Future<byte[]>>> regionMoveFutures, Set<String> failedRegions, String sourceGroupName, int retryCount) Wait for all the region move to complete. Keep waiting for other region movement completion even if some region movement fails. -
isTableInGroup
private boolean isTableInGroup(TableName tableName, String groupName, Set<TableName> tablesInGroupCache) throws IOException - Throws:
IOException
-
rsGroupGetRegionsInTransition
- Throws:
IOException
-
getRSGroupAssignmentsByTable
Map<TableName,Map<ServerName, getRSGroupAssignmentsByTableList<RegionInfo>>> (TableStateManager tableStateManager, String groupName) throws IOException This is an EXPENSIVE clone. Cloning though is the safest thing to do. Can't let out original since it can change and at least the load balancer wants to iterate this exported list. Load balancer should iterate over this list because cloned list will ignore disabled table and split parent region cases. This method is invoked bybalanceRSGroup(java.lang.String, org.apache.hadoop.hbase.client.BalanceRequest)- Returns:
- A clone of current assignments for this group.
- Throws:
IOException
-
balanceRSGroup
Description copied from interface:RSGroupInfoManagerBalance a region server group.- Specified by:
balanceRSGroupin interfaceRSGroupInfoManager- Throws:
IOException
-
moveTablesAndWait
- Throws:
IOException
-
setRSGroup
Description copied from interface:RSGroupInfoManagerSet group for tables.- Specified by:
setRSGroupin interfaceRSGroupInfoManager- Throws:
IOException
-
moveServers
Description copied from interface:RSGroupInfoManagerMove servers to a new group.- Specified by:
moveServersin interfaceRSGroupInfoManager- Throws:
IOException
-
determineRSGroupInfoForTable
Description copied from interface:RSGroupInfoManagerDetermineRSGroupInfofor the given table.- Specified by:
determineRSGroupInfoForTablein interfaceRSGroupInfoManager- Parameters:
tableName- table name- Returns:
- rsgroup name
-
renameRSGroup
Description copied from interface:RSGroupInfoManagerRename rsgroup- Specified by:
renameRSGroupin interfaceRSGroupInfoManager- Parameters:
oldName- old rsgroup namenewName- new rsgroup name- Throws:
IOException
-
updateRSGroupConfig
public void updateRSGroupConfig(String groupName, Map<String, String> configuration) throws IOExceptionDescription copied from interface:RSGroupInfoManagerUpdate RSGroup configuration- Specified by:
updateRSGroupConfigin interfaceRSGroupInfoManager- Parameters:
groupName- the group nameconfiguration- new configuration of the group name to be set- Throws:
IOException- if a remote or network exception occurs
-