/******************************************************************************* * Copyright (c) 2012 GigaSpaces Technologies Ltd. All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package org.openspaces.admin.pu.elastic.config; import java.util.Map; import org.openspaces.admin.Admin; import org.openspaces.admin.internal.pu.elastic.GridServiceContainerConfig; import org.openspaces.admin.internal.pu.elastic.ProcessingUnitSchemaConfig; import org.openspaces.admin.internal.pu.elastic.config.AbstractElasticProcessingUnitConfig; import org.openspaces.admin.pu.config.ProcessingUnitConfig; import org.openspaces.admin.pu.topology.ElasticStatefulProcessingUnitConfigHolder; /** * @author itaif * @since 9.0.1 */ public class ElasticStatefulProcessingUnitConfig extends AbstractElasticProcessingUnitConfig implements ElasticStatefulProcessingUnitConfigHolder { public static final String MAX_MEMORY_CAPACITY_MEGABYTES_DYNAMIC_PROPERTY = "max-memory-capacity-megabytes"; public static final String MIN_MEMORY_CAPACITY_MEGABYTES_DYNAMIC_PROPERTY = "min-memory-capacity-megabytes"; Map<String,String> scaleStrategy; private long maxMemoryCapacityInMB; private int numberOfBackupInstancesPerPartition = 1; private int numberOfPartitions; private int maxProcessingUnitInstancesFromSamePartitionPerMachine = 1; private double maxNumberOfCpuCores; private double minNumberOfCpuCoresPerMachine; private Admin admin; private boolean allowAboveAverageMemoryPerMachine; public ElasticStatefulProcessingUnitConfig() { super(); // add an elastic property indicating the cluster schema partitioned-sync2backup new ProcessingUnitSchemaConfig(super.getElasticProperties()).setPartitionedSync2BackupSchema(); } @Override public ProcessingUnitConfig toProcessingUnitConfig() { ProcessingUnitConfig config = super.toProcessingUnitConfig(); if (getMachineProvisioning() != null && getMinNumberOfCpuCoresPerMachine() <= 0) { // try to figure out from machine provisioning setMinNumberOfCpuCoresPerMachine(super.getMachineProvisioning().getMinimumNumberOfCpuCoresPerMachine()); if (getMinNumberOfCpuCoresPerMachine() <= 0 && !(getMachineProvisioning() instanceof DiscoveredMachineProvisioningConfig)) { throw new IllegalStateException("Elastic Machine Provisioning configuration must supply the expected minimum number of CPU cores per machine."); } } if (this.getMaxMemoryCapacityInMB() == 0 && this.getNumberOfPartitions() == 0) { throw new IllegalStateException("maxMemoryCapacity must be defined."); } if (this.getMaxMemoryCapacityInMB() != 0 && this.getNumberOfPartitions() != 0) { throw new IllegalStateException("numberOfPartitions conflicts with maxMemoryCapacity. Please specify only one of these properties."); } if (this.getMaxNumberOfCpuCores() != 0 && this.getNumberOfPartitions() != 0) { throw new IllegalStateException("numberOfPartitions conflicts with maxNumberOfCpuCores. Please specify only one of these properties."); } int numberOfInstances = this.getNumberOfPartitions(); if (numberOfInstances == 0) { numberOfInstances = Math.max(calcNumberOfPartitionsFromMemoryRequirements(),calcNumberOfPartitionsFromCpuRequirements(admin)); } if (getNumberOfBackupInstancesPerPartition() == 0) { // allow instances from DIFFERENT partitions to deploy on same Container config.setMaxInstancesPerMachine(0); config.setMaxInstancesPerVM(0); } else { // disallow instances from SAME partition to deploy on same Container config.setMaxInstancesPerVM(1); // allow or disallow instances from SAME partition to deploy on same Container config.setMaxInstancesPerMachine(this.getMaxProcessingUnitInstancesFromSamePartitionPerMachine()); } config.setClusterSchema("partitioned-sync2backup"); config.setNumberOfInstances(numberOfInstances); config.setNumberOfBackups(getNumberOfBackupInstancesPerPartition()); return config; } protected int calcNumberOfPartitionsFromMemoryRequirements() { long maximumMemoryCapacityInMB = new GridServiceContainerConfig(super.getElasticProperties()).getMaximumMemoryCapacityInMB(); if (maximumMemoryCapacityInMB <= 0) { throw new IllegalStateException("memoryCapacityPerContainer is undefined."); } double totalNumberOfInstances = Math.ceil(((double)getMaxMemoryCapacityInMB())/maximumMemoryCapacityInMB); int numberOfPartitions = (int) Math.ceil(totalNumberOfInstances / (getNumberOfBackupInstancesPerPartition()+1)); return Math.max(1, numberOfPartitions); } protected int calcNumberOfPartitionsFromCpuRequirements(Admin admin) { int maximumNumberOfPrimaryInstances = 1; if (getMaxNumberOfCpuCores() > 0) { if (getMinNumberOfCpuCoresPerMachine() <= 0) { if (admin == null) { throw new IllegalStateException("call #setAdmin() or #setNumberOfPartitions() before calling toProcessingUnitConfig()"); } setMinNumberOfCpuCoresPerMachine(DiscoveredMachineProvisioningConfig.detectMinimumNumberOfCpuCoresPerMachine(admin)); } maximumNumberOfPrimaryInstances =(int) Math.ceil(this.getMaxNumberOfCpuCores() / getMinNumberOfCpuCoresPerMachine()); } return maximumNumberOfPrimaryInstances; } public long getMaxMemoryCapacityInMB() { return maxMemoryCapacityInMB; } public void setMaxMemoryCapacityInMB(long maxMemoryCapacityInMB) { this.maxMemoryCapacityInMB = maxMemoryCapacityInMB; } public int getNumberOfBackupInstancesPerPartition() { return numberOfBackupInstancesPerPartition; } public void setNumberOfBackupInstancesPerPartition(int numberOfBackupInstancesPerPartition) { this.numberOfBackupInstancesPerPartition = numberOfBackupInstancesPerPartition; } public int getNumberOfPartitions() { return numberOfPartitions; } public void setNumberOfPartitions(int numberOfPartitions) { this.numberOfPartitions = numberOfPartitions; } public int getMaxProcessingUnitInstancesFromSamePartitionPerMachine() { return maxProcessingUnitInstancesFromSamePartitionPerMachine; } public void setMaxProcessingUnitInstancesFromSamePartitionPerMachine( int maxProcessingUnitInstancesFromSamePartitionPerMachine) { this.maxProcessingUnitInstancesFromSamePartitionPerMachine = maxProcessingUnitInstancesFromSamePartitionPerMachine; } public double getMaxNumberOfCpuCores() { return maxNumberOfCpuCores; } public void setMaxNumberOfCpuCores(double maxNumberOfCpuCores) { this.maxNumberOfCpuCores = maxNumberOfCpuCores; } @Deprecated public double getMinNumberOfCpuCoresPerMachine() { return minNumberOfCpuCoresPerMachine; } @Deprecated public void setMinNumberOfCpuCoresPerMachine(double minNumberOfCpuCoresPerMachine) { this.minNumberOfCpuCoresPerMachine = minNumberOfCpuCoresPerMachine; } public boolean isAllowAboveAverageMemoryPerMachine() { return allowAboveAverageMemoryPerMachine; } public void setAllowAboveAverageMemoryPerMachine(boolean allowAboveAverageMemoryPerMachine) { this.allowAboveAverageMemoryPerMachine = allowAboveAverageMemoryPerMachine; } @Override public void setAdmin(Admin admin) { this.admin = admin; } }