An Apache Geode PartitionedRegion partitions its entries into buckets among all the servers where it is defined. Properties that affect the number and location of the buckets include total-num-buckets
and redundant-copies
. The total-num-buckets
configures the number of buckets across all the members of the DistributedSystem. The redundant-copies
configures the number of copies of each bucket. The primary bucket is hosted on one server, and if redundant-copies
is greater than zero, the secondary buckets are hosted on other servers.
In addition, the redundancy-zone
property helps determine where buckets are located. If two redundancy zones are defined and redundant-copies
is one (meaning 2 copies of each bucket), then the primary bucket will be in a member in one zone, and the secondary bucket will be in a member in the other zone.
This article is a companion to my Logging Apache Geode PartitionedRegion Entry Details Per Bucket article. It provides an example of a compact view of the primary and secondary bucket locations per server and redundancy zone.
All source code described in this article as well as an example usage is available here.
The GetBucketIdsFunction
is executed on each server and:
ServerBucketIds
object containing these valuesThe GetBucketIdsResultCollector
created on the client combines each ServerBucketIds
object into an AllBucketIds
object.
The AllBucketIds
object contains:
GetBucketIdsFunction
The GetBucketIdsFunction
execute
method first gets the PartitionedRegion. The PartitionedRegion provides the configured number of buckets. Its PartitionedRegionDataStore
provides the local bucket ids and the local primary bucket ids. The redundancy zone is retrieved from the DistributionConfig
. Finally, the Function creates and returns the ServerBucketIds
object.
public void execute(FunctionContext<Object[]> context) {
// Get the region name
Object[] arguments = context.getArguments();
String regionName = (String) arguments[0];
context.getCache().getLogger().info("GetBucketIdsFunction getting bucket ids for regionName=" + regionName);
// Get the region
PartitionedRegion region = (PartitionedRegion) context.getCache().getRegion(regionName);
// Create the data structure
String redundancyZone = ((InternalDistributedSystem) context.getCache().getDistributedSystem()).getConfig().getRedundancyZone();
int configuredNumberOfBuckets = region.getTotalNumberOfBuckets();
List<Integer> allBucketIds = new ArrayList<>(region.getDataStore().getAllLocalBucketIds());
List<Integer> primaryBucketIds = new ArrayList<>(region.getDataStore().getAllLocalPrimaryBucketIds());
ServerBucketIds ids = new ServerBucketIds(regionName, redundancyZone, configuredNumberOfBuckets, allBucketIds, primaryBucketIds);
// Return result
context.getResultSender().lastResult(ids);
}
ServerBucketIds
ResultThe GetBucketIdsResultCollector
addResult
method is called on the client when the ServerBucketIds
result from each server is received. The method calls AllBucketIds
process to process the ServerBucketIds
object like:
public void addResult(DistributedMember server, ServerBucketIds serverBucketIds) {
this.allBucketIds.process(server.getName(), serverBucketIds);
}
The AllBucketIds
process method sets the region name, configured number of buckets and the redundancy zones per server. In addition, it updates the bucket ids per server and redundancy zone.
public void process(String server, ServerBucketIds serverBucketIds) {
this.regionName = serverBucketIds.getRegionName();
this.configuredNumberOfBuckets = serverBucketIds.getConfiguredNumberOfBuckets();
this.redundancyZonesPerServer.put(server, serverBucketIds.getRedundancyZone());
updateBucketsPerServer(server, serverBucketIds);
updateBucketsPerRedundancyZone(serverBucketIds);
}
The AllBucketIds
updateBucketsPerServer
method:
private void updateBucketsPerServer(String server, ServerBucketIds serverBucketIds) {
// Sort and add all bucket ids
Collections.sort(serverBucketIds.getAllBucketIds());
this.allBucketIdsPerServer.put(server, serverBucketIds.getAllBucketIds());
this.totalNumberOfBucketIds += serverBucketIds.getTotalNumberOfBucketIds();
// Sort and add primary bucket ids
Collections.sort(serverBucketIds.getPrimaryBucketIds());
this.primaryBucketIdsPerServer.put(server, serverBucketIds.getPrimaryBucketIds());
this.totalNumberOfPrimaryBucketIds += serverBucketIds.getTotalNumberOfPrimaryBucketIds();
}
The AllBucketIds
updateBucketsPerRedundancyZone
method:
private void updateBucketsPerRedundancyZone(ServerBucketIds serverBucketIds) {
// Sort and add all bucket ids
String redundancyZone = serverBucketIds.getRedundancyZone();
List<Integer> redundancyZoneAllBucketIds = this.allBucketIdsPerRedundancyZone.computeIfAbsent(redundancyZone, k -> new ArrayList<>());
redundancyZoneAllBucketIds.addAll(serverBucketIds.getAllBucketIds());
Collections.sort(redundancyZoneAllBucketIds);
// Sort and add primary bucket ids
List<Integer> redundancyZonePrimaryBucketIds = this.primaryBucketIdsPerRedundancyZone.computeIfAbsent(redundancyZone, k -> new ArrayList<>());
redundancyZonePrimaryBucketIds.addAll(serverBucketIds.getPrimaryBucketIds());
Collections.sort(redundancyZonePrimaryBucketIds);
}
The AllBucketIds
getDisplayString
method builds the message containing the primary and secondary bucket locations per server and redundancy zone like:
public String getDisplayString() {
StringBuilder builder = new StringBuilder();
builder
.append("Region: ")
.append(this.regionName)
.append("\nConfigured Number of Buckets: ")
.append(this.configuredNumberOfBuckets);
// Add all bucket ids per server
addAllServerBucketIds(builder);
// Add primary bucket ids per server
addPrimaryServerBucketIds(builder);
// Add all bucket ids per redundancy zone
addAllRedundancyZoneBucketIds(builder);
// Add primary bucket ids per redundancy zone
addPrimaryRedundancyZoneBucketIds(builder);
// Add missing bucket ids in each redundancy zone
addMissingBucketsInRedundancyZone(builder);
// Add extra bucket ids in each redundancy zone
addExtraBucketsInRedundancyZone(builder);
return builder.toString();
}
Executing the GetBucketIdsFunction
will cause the client to log a message like this showing the primary and secondary bucket locations per server and redundancy zone:
Region: Customer
Configured Number of Buckets: 113
The 6 servers contain the following 226 bucket ids:
Server server-1-a in zone zoneA contains 38 bucket ids: [1, 3, 9, 10, 18, 19, 22, 23, 29, 32, 34, 35, 37, 40, 43, 50, 51, 55, 61, 63, 68, 72, 73, 76, 79, 81, 85, 88, 89, 91, 93, 96, 99, 103, 106, 108, 109, 112]
Server server-1-b in zone zoneB contains 38 bucket ids: [1, 4, 6, 10, 12, 14, 16, 17, 19, 24, 31, 33, 34, 39, 43, 45, 47, 49, 53, 58, 62, 66, 67, 68, 71, 72, 75, 81, 82, 83, 92, 95, 96, 98, 99, 100, 105, 111]
Server server-2-a in zone zoneA contains 38 bucket ids: [0, 5, 6, 7, 8, 12, 14, 17, 20, 25, 30, 31, 36, 41, 42, 45, 47, 49, 52, 53, 59, 62, 64, 66, 69, 71, 74, 77, 82, 83, 86, 87, 90, 94, 98, 101, 102, 107]
Server server-3-a in zone zoneA contains 37 bucket ids: [2, 4, 11, 13, 15, 16, 21, 24, 26, 27, 28, 33, 38, 39, 44, 46, 48, 54, 56, 57, 58, 60, 65, 67, 70, 75, 78, 80, 84, 92, 95, 97, 100, 104, 105, 110, 111]
Server server-2-b in zone zoneB contains 37 bucket ids: [2, 5, 9, 11, 20, 22, 23, 26, 27, 30, 35, 37, 40, 41, 44, 48, 51, 52, 54, 60, 61, 65, 73, 74, 78, 84, 86, 87, 88, 89, 90, 93, 94, 101, 103, 107, 112]
Server server-3-b in zone zoneB contains 38 bucket ids: [0, 3, 7, 8, 13, 15, 18, 21, 25, 28, 29, 32, 36, 38, 42, 46, 50, 55, 56, 57, 59, 63, 64, 69, 70, 76, 77, 79, 80, 85, 91, 97, 102, 104, 106, 108, 109, 110]
The 6 servers contain the following 113 primary bucket ids:
Server server-1-a in zone zoneA contains 18 primary bucket ids: [1, 3, 10, 18, 22, 35, 37, 40, 51, 55, 61, 63, 68, 73, 81, 93, 103, 109]
Server server-1-b in zone zoneB contains 19 primary bucket ids: [4, 6, 12, 19, 24, 34, 43, 49, 62, 67, 72, 75, 82, 83, 92, 96, 99, 100, 111]
Server server-2-a in zone zoneA contains 19 primary bucket ids: [0, 5, 8, 14, 17, 20, 31, 36, 42, 45, 47, 53, 66, 71, 77, 87, 90, 98, 102]
Server server-3-a in zone zoneA contains 19 primary bucket ids: [2, 13, 16, 21, 26, 28, 33, 39, 46, 48, 56, 58, 65, 70, 80, 84, 95, 97, 105]
Server server-2-b in zone zoneB contains 19 primary bucket ids: [9, 11, 23, 27, 30, 41, 44, 52, 54, 60, 74, 78, 86, 88, 89, 94, 101, 107, 112]
Server server-3-b in zone zoneB contains 19 primary bucket ids: [7, 15, 25, 29, 32, 38, 50, 57, 59, 64, 69, 76, 79, 85, 91, 104, 106, 108, 110]
The 2 redundancy zones contain the following bucket ids:
Zone zoneB contains 113 bucket ids: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112]
Zone zoneA contains 113 bucket ids: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112]
The 2 redundancy zones contain the following primary bucket ids:
Zone zoneB contains 57 primary bucket ids: [4, 6, 7, 9, 11, 12, 15, 19, 23, 24, 25, 27, 29, 30, 32, 34, 38, 41, 43, 44, 49, 50, 52, 54, 57, 59, 60, 62, 64, 67, 69, 72, 74, 75, 76, 78, 79, 82, 83, 85, 86, 88, 89, 91, 92, 94, 96, 99, 100, 101, 104, 106, 107, 108, 110, 111, 112]
Zone zoneA contains 56 primary bucket ids: [0, 1, 2, 3, 5, 8, 10, 13, 14, 16, 17, 18, 20, 21, 22, 26, 28, 31, 33, 35, 36, 37, 39, 40, 42, 45, 46, 47, 48, 51, 53, 55, 56, 58, 61, 63, 65, 66, 68, 70, 71, 73, 77, 80, 81, 84, 87, 90, 93, 95, 97, 98, 102, 103, 105, 109]
The 2 redundancy zones contain the following missing bucket ids:
Zone zoneB has 0 missing bucket ids: []
Zone zoneA has 0 missing bucket ids: []
The 2 redundancy zones contain the following extra bucket ids:
Zone zoneB has 0 extra bucket ids: []
Zone zoneA has 0 extra bucket ids: []
A gfsh command and Function that provides PartitionedRegion primary and secondary bucket locations per server and redundancy zone like this example would be a useful addition to Apache Geode.