use of org.apache.geode.internal.cache.PartitionedRegion in project geode by apache.
the class PartitionedRegionRebalanceOp method buildModel.
/**
* Build a model of the load on the partitioned region, which can determine which buckets to move,
* etc.
*
* @param detailsMap
* @param resourceManager
*/
private PartitionedRegionLoadModel buildModel(BucketOperator operator, Map<PartitionedRegion, InternalPRInfo> detailsMap, InternalResourceManager resourceManager) {
PartitionedRegionLoadModel model;
final boolean isDebugEnabled = logger.isDebugEnabled();
final DM dm = leaderRegion.getDistributionManager();
AddressComparor comparor = new AddressComparor() {
public boolean areSameZone(InternalDistributedMember member1, InternalDistributedMember member2) {
return dm.areInSameZone(member1, member2);
}
public boolean enforceUniqueZones() {
return dm.enforceUniqueZone();
}
};
int redundantCopies = leaderRegion.getRedundantCopies();
int totalNumberOfBuckets = leaderRegion.getTotalNumberOfBuckets();
Set<InternalDistributedMember> criticalMembers = resourceManager.getResourceAdvisor().adviseCritialMembers();
;
boolean removeOverRedundancy = true;
debug("Building Model for rebalancing " + leaderRegion + ". redundantCopies=" + redundantCopies + ", totalNumBuckets=" + totalNumberOfBuckets + ", criticalMembers=" + criticalMembers + ", simulate=" + simulate);
model = new PartitionedRegionLoadModel(operator, redundantCopies, totalNumberOfBuckets, comparor, criticalMembers, leaderRegion);
for (Map.Entry<PartitionedRegion, InternalPRInfo> entry : detailsMap.entrySet()) {
PartitionedRegion region = entry.getKey();
InternalPRInfo details = entry.getValue();
OfflineMemberDetails offlineDetails;
if (replaceOfflineData) {
offlineDetails = OfflineMemberDetails.EMPTY_DETAILS;
} else {
offlineDetails = details.getOfflineMembers();
}
boolean enforceLocalMaxMemory = !region.isEntryEvictionPossible();
debug("Added Region to model region=" + region + ", offlineDetails=" + offlineDetails + ", enforceLocalMaxMemory=" + enforceLocalMaxMemory);
for (PartitionMemberInfo memberDetails : details.getPartitionMemberInfo()) {
debug("For Region: " + region + ", Member: " + memberDetails.getDistributedMember() + "LOAD=" + ((InternalPartitionDetails) memberDetails).getPRLoad() + ", equivalentMembers=" + dm.getMembersInSameZone((InternalDistributedMember) memberDetails.getDistributedMember()));
}
Set<InternalPartitionDetails> memberDetailSet = details.getInternalPartitionDetails();
model.addRegion(region.getFullPath(), memberDetailSet, offlineDetails, enforceLocalMaxMemory);
}
model.initialize();
debug("Rebalancing {} starting. Model:\n{}", leaderRegion, model);
return model;
}
use of org.apache.geode.internal.cache.PartitionedRegion in project geode by apache.
the class PartitionedRegionRebalanceOp method execute.
/**
* Do the actual rebalance
*
* @return the details of the rebalance.
*/
public Set<PartitionRebalanceInfo> execute() {
long start = System.nanoTime();
InternalResourceManager resourceManager = InternalResourceManager.getInternalResourceManager(leaderRegion.getCache());
MembershipListener listener = new MembershipChangeListener();
if (isRebalance) {
InternalResourceManager.getResourceObserver().rebalancingStarted(targetRegion);
} else {
InternalResourceManager.getResourceObserver().recoveryStarted(targetRegion);
}
RecoveryLock lock = null;
try {
if (!checkAndSetColocatedRegions()) {
return Collections.emptySet();
}
// have full redundancy.
if (!isRebalanceNecessary()) {
return Collections.emptySet();
}
if (!simulate) {
lock = leaderRegion.getRecoveryLock();
lock.lock();
}
// have fixed it already.
if (!isRebalanceNecessary()) {
return Collections.emptySet();
}
// register a listener to notify us if the new members leave or join.
// When a membership change occurs, we want to restart the rebalancing
// from the beginning.
// TODO rebalance - we should really add a membership listener to ALL of
// the colocated regions.
leaderRegion.getRegionAdvisor().addMembershipListener(listener);
PartitionedRegionLoadModel model = null;
InternalCache cache = leaderRegion.getCache();
Map<PartitionedRegion, InternalPRInfo> detailsMap = fetchDetails(cache);
BucketOperatorWrapper serialOperator = getBucketOperator(detailsMap);
ParallelBucketOperator parallelOperator = new ParallelBucketOperator(MAX_PARALLEL_OPERATIONS, cache.getDistributionManager().getWaitingThreadPool(), serialOperator);
model = buildModel(parallelOperator, detailsMap, resourceManager);
for (PartitionRebalanceDetailsImpl details : serialOperator.getDetailSet()) {
details.setPartitionMemberDetailsBefore(model.getPartitionedMemberDetails(details.getRegionPath()));
}
director.initialize(model);
for (; ; ) {
if (cancelled.get()) {
return Collections.emptySet();
}
if (membershipChange) {
membershipChange = false;
// refetch the partitioned region details after
// a membership change.
debug("Rebalancing {} detected membership changes. Refetching details", leaderRegion);
if (this.stats != null) {
this.stats.incRebalanceMembershipChanges(1);
}
model.waitForOperations();
detailsMap = fetchDetails(cache);
model = buildModel(parallelOperator, detailsMap, resourceManager);
director.membershipChanged(model);
}
leaderRegion.checkClosed();
cache.getCancelCriterion().checkCancelInProgress(null);
if (logger.isDebugEnabled()) {
logger.debug("Rebalancing {} Model:{}\n", leaderRegion, model);
}
if (!director.nextStep()) {
// Stop when the director says we can't rebalance any more.
break;
}
}
debug("Rebalancing {} complete. Model:{}\n", leaderRegion, model);
long end = System.nanoTime();
for (PartitionRebalanceDetailsImpl details : serialOperator.getDetailSet()) {
if (!simulate) {
details.setTime(end - start);
}
details.setPartitionMemberDetailsAfter(model.getPartitionedMemberDetails(details.getRegionPath()));
}
return Collections.<PartitionRebalanceInfo>unmodifiableSet(serialOperator.getDetailSet());
} finally {
if (lock != null) {
try {
lock.unlock();
} catch (CancelException e) {
// lock service has been destroyed
} catch (Exception e) {
logger.error(LocalizedMessage.create(LocalizedStrings.PartitionedRegionRebalanceOp_UNABLE_TO_RELEASE_RECOVERY_LOCK), e);
}
}
try {
if (isRebalance) {
InternalResourceManager.getResourceObserver().rebalancingFinished(targetRegion);
} else {
InternalResourceManager.getResourceObserver().recoveryFinished(targetRegion);
}
} catch (Exception e) {
logger.error(LocalizedMessage.create(LocalizedStrings.PartitionedRegionRebalanceOp_ERROR_IN_RESOURCE_OBSERVER), e);
}
try {
leaderRegion.getRegionAdvisor().removeMembershipListener(listener);
} catch (Exception e) {
logger.error(LocalizedMessage.create(LocalizedStrings.PartitionedRegionRebalanceOp_ERROR_IN_RESOURCE_OBSERVER), e);
}
}
}
use of org.apache.geode.internal.cache.PartitionedRegion in project geode by apache.
the class PartitionedRegionRebalanceOp method fetchDetails.
private Map<PartitionedRegion, InternalPRInfo> fetchDetails(InternalCache cache) {
LoadProbe probe = cache.getInternalResourceManager().getLoadProbe();
Map<PartitionedRegion, InternalPRInfo> detailsMap = new LinkedHashMap<PartitionedRegion, InternalPRInfo>(colocatedRegions.size());
for (PartitionedRegion colocatedRegion : colocatedRegions) {
if (ColocationHelper.isColocationComplete(colocatedRegion)) {
InternalPRInfo info = colocatedRegion.getRedundancyProvider().buildPartitionedRegionInfo(true, probe);
detailsMap.put(colocatedRegion, info);
}
}
return detailsMap;
}
use of org.apache.geode.internal.cache.PartitionedRegion in project geode by apache.
the class IndexCreationMsg method process.
/**
* Process this index creation message on the receiver.
*/
@Override
public void process(final DistributionManager dm) {
final boolean isDebugEnabled = logger.isDebugEnabled();
Throwable thr = null;
boolean sendReply = true;
PartitionedRegion pr = null;
try {
if (isDebugEnabled) {
logger.debug("Trying to get pr with id: {}", this.regionId);
}
try {
if (isDebugEnabled) {
logger.debug("Again trying to get pr with id : {}", this.regionId);
}
pr = PartitionedRegion.getPRFromId(this.regionId);
if (isDebugEnabled) {
logger.debug("Index creation message got the pr {}", pr);
}
if (null == pr) {
boolean wait = true;
int attempts = 0;
while (wait && attempts < 30) {
// max 30 seconds of wait.
dm.getCancelCriterion().checkCancelInProgress(null);
if (isDebugEnabled) {
logger.debug("Waiting for Partitioned Region to be intialized with id {}for processing index creation messages", this.regionId);
}
try {
boolean interrupted = Thread.interrupted();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
interrupted = true;
dm.getCancelCriterion().checkCancelInProgress(e);
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
pr = PartitionedRegion.getPRFromId(this.regionId);
if (null != pr) {
wait = false;
if (isDebugEnabled) {
logger.debug("Indexcreation message got the pr {}", pr);
}
}
attempts++;
} catch (CancelException ignorAndLoopWait) {
if (isDebugEnabled) {
logger.debug("IndexCreationMsg waiting for pr to be properly created with prId : {}", this.regionId);
}
}
}
}
} catch (CancelException letPRInitialized) {
// to the PR being initialized.
if (logger.isDebugEnabled()) {
logger.debug("Waiting for notification from pr being properly created on {}", this.regionId);
}
boolean wait = true;
while (wait) {
dm.getCancelCriterion().checkCancelInProgress(null);
try {
boolean interrupted = Thread.interrupted();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
interrupted = true;
dm.getCancelCriterion().checkCancelInProgress(e);
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
pr = PartitionedRegion.getPRFromId(this.regionId);
wait = false;
if (logger.isDebugEnabled()) {
logger.debug("Indexcreation message got the pr {}", pr);
}
} catch (CancelException ignorAndLoopWait) {
if (logger.isDebugEnabled()) {
logger.debug("IndexCreationMsg waiting for pr to be properly created with prId : {}", this.regionId);
}
}
}
}
if (pr == null) /* && failIfRegionMissing() */
{
String msg = LocalizedStrings.IndexCreationMsg_COULD_NOT_GET_PARTITIONED_REGION_FROM_ID_0_FOR_MESSAGE_1_RECEIVED_ON_MEMBER_2_MAP_3.toLocalizedString(new Object[] { Integer.valueOf(this.regionId), this, dm.getId(), PartitionedRegion.dumpPRId() });
throw new PartitionedRegionException(msg, new RegionNotFoundException(msg));
}
sendReply = operateOnPartitionedRegion(dm, pr, 0);
} catch (PRLocallyDestroyedException pre) {
if (isDebugEnabled) {
logger.debug("Region is locally Destroyed ");
}
thr = pre;
} catch (VirtualMachineError err) {
SystemFailure.initiateFailure(err);
// now, so don't let this thread continue.
throw err;
} catch (Throwable t) {
// Whenever you catch Error or Throwable, you must also
// catch VirtualMachineError (see above). However, there is
// _still_ a possibility that you are dealing with a cascading
// error condition, so you also need to check to see if the JVM
// is still usable:
SystemFailure.checkFailure();
// log the exception at fine level if there is no reply to the message
if (this.processorId == 0) {
logger.debug("{} exception while processing message:{}", this, t.getMessage(), t);
} else if (logger.isDebugEnabled(LogMarker.DM) && (t instanceof RuntimeException)) {
logger.debug(LogMarker.DM, "Exception caught while processing message: {}", t.getMessage(), t);
}
if (t instanceof RegionDestroyedException && pr != null) {
if (pr.isClosed) {
logger.info(LocalizedMessage.create(LocalizedStrings.IndexCreationMsg_REGION_IS_LOCALLY_DESTROYED_THROWING_REGIONDESTROYEDEXCEPTION_FOR__0, pr));
thr = new RegionDestroyedException(LocalizedStrings.IndexCreationMsg_REGION_IS_LOCALLY_DESTROYED_ON_0.toLocalizedString(dm.getId()), pr.getFullPath());
}
} else {
thr = t;
}
} finally {
if (sendReply && this.processorId != 0) {
ReplyException rex = null;
if (thr != null) {
rex = new ReplyException(thr);
}
sendReply(getSender(), this.processorId, dm, rex, pr, 0);
}
}
}
use of org.apache.geode.internal.cache.PartitionedRegion in project geode by apache.
the class DumpB2NRegion method process.
@Override
public void process(final DistributionManager dm) {
PartitionedRegion pr = null;
// Get the region, or die trying...
final long finish = System.currentTimeMillis() + 10 * 1000;
try {
for (; ; ) {
dm.getCancelCriterion().checkCancelInProgress(null);
// pr = null; (redundant assignment)
pr = PartitionedRegion.getPRFromId(this.regionId);
if (pr != null) {
break;
}
if (System.currentTimeMillis() > finish) {
ReplyException rex = new ReplyException(new TimeoutException("Waited too long for region to initialize"));
sendReply(getSender(), this.processorId, dm, rex, null, 0);
return;
}
// wait a little
boolean interrupted = Thread.interrupted();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
interrupted = true;
pr.checkReadiness();
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
// Now, wait for the PR to finish initializing
pr.waitForData();
// OK, now it's safe to process this.
super.process(dm);
} catch (CancelException e) {
sendReply(this.sender, this.processorId, dm, new ReplyException(e), pr, 0);
} catch (PRLocallyDestroyedException e) {
sendReply(this.sender, this.processorId, dm, new ReplyException(e), pr, 0);
return;
} catch (RegionDestroyedException rde) {
sendReply(this.sender, this.processorId, dm, new ReplyException(rde), pr, 0);
return;
}
}
Aggregations