IGNITE-4442 Implemented cache affinity configuration.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f4a1e6ca Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f4a1e6ca Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f4a1e6ca Branch: refs/heads/ignite-3477 Commit: f4a1e6ca86bcc6054ca6066107ad58b6b19d665a Parents: 828b9b6 Author: Vasiliy Sisko <vsi...@gridgain.com> Authored: Thu Dec 29 14:48:45 2016 +0700 Committer: Andrey Novikov <anovi...@gridgain.com> Committed: Thu Dec 29 14:48:45 2016 +0700 ---------------------------------------------------------------------- modules/web-console/backend/app/mongo.js | 19 +++++ .../generator/AbstractTransformer.js | 5 ++ .../modules/configuration/generator/Beans.js | 4 + .../generator/ConfigurationGenerator.js | 36 +++++++++ .../states/configuration/caches/affinity.jade | 82 ++++++++++++++++++++ .../states/configuration/caches/memory.jade | 4 +- .../frontend/views/configuration/caches.jade | 1 + 7 files changed, 149 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/f4a1e6ca/modules/web-console/backend/app/mongo.js ---------------------------------------------------------------------- diff --git a/modules/web-console/backend/app/mongo.js b/modules/web-console/backend/app/mongo.js index 58ab119..dd71f3a 100644 --- a/modules/web-console/backend/app/mongo.js +++ b/modules/web-console/backend/app/mongo.js @@ -140,6 +140,25 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose cacheMode: {type: String, enum: ['PARTITIONED', 'REPLICATED', 'LOCAL']}, atomicityMode: {type: String, enum: ['ATOMIC', 'TRANSACTIONAL']}, + affinity: { + kind: {type: String, enum: ['Default', 'Rendezvous', 'Fair', 'Custom']}, + Rendezvous: { + affinityBackupFilter: String, + partitions: Number, + excludeNeighbors: Boolean + }, + Fair: { + affinityBackupFilter: String, + partitions: Number, + excludeNeighbors: Boolean + }, + Custom: { + className: String + } + }, + + affinityMapper: String, + nodeFilter: { kind: {type: String, enum: ['Default', 'Exclude', 'IGFS', 'OnNodes', 'Custom']}, Exclude: { http://git-wip-us.apache.org/repos/asf/ignite/blob/f4a1e6ca/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js b/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js index f5afe59..40d937e 100644 --- a/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js +++ b/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js @@ -211,6 +211,11 @@ export default class AbstractTransformer { } // Generate cache memory group. + static cacheAffinity(cache) { + return this.toSection(this.generator.cacheAffinity(cache)); + } + + // Generate cache memory group. static cacheMemory(cache) { return this.toSection(this.generator.cacheMemory(cache)); } http://git-wip-us.apache.org/repos/asf/ignite/blob/f4a1e6ca/modules/web-console/frontend/app/modules/configuration/generator/Beans.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/configuration/generator/Beans.js b/modules/web-console/frontend/app/modules/configuration/generator/Beans.js index ca19342..0972eac 100644 --- a/modules/web-console/frontend/app/modules/configuration/generator/Beans.js +++ b/modules/web-console/frontend/app/modules/configuration/generator/Beans.js @@ -116,6 +116,10 @@ export class Bean extends EmptyBean { return this._property(this.arguments, 'int', model, null, _.nonNil); } + boolConstructorArgument(model) { + return this._property(this.arguments, 'boolean', model, null, _.nonNil); + } + classConstructorArgument(model) { return this._property(this.arguments, 'java.lang.Class', model, null, _.nonEmpty); } http://git-wip-us.apache.org/repos/asf/ignite/blob/f4a1e6ca/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js index 8770bf6..de2b750 100644 --- a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js +++ b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js @@ -1453,6 +1453,41 @@ export default class IgniteConfigurationGenerator { return ccfg; } + // Generation of constructor for affinity function. + static cacheAffinityFunction(cls, func) { + const affBean = new Bean(cls, 'affinityFunction', func); + + affBean.boolConstructorArgument('excludeNeighbors') + .intProperty('partitions') + .emptyBeanProperty('affinityBackupFilter'); + + return affBean; + } + + // Generate cache memory group. + static cacheAffinity(cache, ccfg = this.cacheConfigurationBean(cache)) { + switch (_.get(cache, 'affinity.kind')) { + case 'Rendezvous': + ccfg.beanProperty('affinity', this.cacheAffinityFunction('org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction', cache.affinity.Rendezvous)); + + break; + case 'Fair': + ccfg.beanProperty('affinity', this.cacheAffinityFunction('org.apache.ignite.cache.affinity.fair.FairAffinityFunction', cache.affinity.Fair)); + + break; + case 'Custom': + ccfg.emptyBeanProperty('affinity.Custom.className', 'affinity'); + + break; + default: + // No-op. + } + + ccfg.emptyBeanProperty('affinityMapper'); + + return ccfg; + } + // Generate cache memory group. static cacheMemory(cache, ccfg = this.cacheConfigurationBean(cache)) { ccfg.enumProperty('memoryMode'); @@ -1728,6 +1763,7 @@ export default class IgniteConfigurationGenerator { static cacheConfiguration(cache, ccfg = this.cacheConfigurationBean(cache)) { this.cacheGeneral(cache, ccfg); + this.cacheAffinity(cache, ccfg); this.cacheMemory(cache, ccfg); this.cacheQuery(cache, cache.domains, ccfg); this.cacheStore(cache, cache.domains, ccfg); http://git-wip-us.apache.org/repos/asf/ignite/blob/f4a1e6ca/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.jade new file mode 100644 index 0000000..3c4746b --- /dev/null +++ b/modules/web-console/frontend/app/modules/states/configuration/caches/affinity.jade @@ -0,0 +1,82 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + +include /app/helpers/jade/mixins.jade + +-var form = 'affinity' +-var model = 'backupItem' +-var affModel = model + '.affinity' +-var affMapModel = model + '.affinityMapper' +-var rendezvousAff = affModel + '.kind === "Rendezvous"' +-var fairAff = affModel + '.kind === "Fair"' +-var customAff = affModel + '.kind === "Custom"' +-var customAffMapper = affMapModel + '.kind === "Custom"' +-var rendPartitionsRequired = rendezvousAff + ' && ' + affModel + '.Rendezvous.affinityBackupFilter' +-var fairPartitionsRequired = fairAff + ' && ' + affModel + '.Fair.affinityBackupFilter' + +.panel.panel-default(ng-form=form novalidate) + .panel-heading(bs-collapse-toggle='' ng-click='ui.loadPanel("#{form}")') + ignite-form-panel-chevron + label Affinity Collocation + ignite-form-field-tooltip.tipLabel + | Collocate data with data to improve performance and scalability of your application#[br] + | #[a(href="http://apacheignite.gridgain.org/docs/affinity-collocation" target="_blank") More info] + ignite-form-revert + .panel-collapse(role='tabpanel' bs-collapse-target id=form) + .panel-body(ng-if='ui.isPanelLoaded("#{form}")') + .col-sm-6 + .settings-row + +dropdown('Function:', affModel + '.kind', '"AffinityKind"', 'true', 'Default', + '[\ + {value: "Rendezvous", label: "Rendezvous"},\ + {value: "Fair", label: "Fair"},\ + {value: "Custom", label: "Custom"},\ + {value: undefined, label: "Default"}\ + ]', + 'Key topology resolver to provide mapping from keys to nodes\ + <ul>\ + <li>Rendezvous - Based on Highest Random Weight algorithm<br/></li>\ + <li>Fair - Tries to ensure that all nodes get equal number of partitions with minimum amount of reassignments between existing nodes<br/></li>\ + <li>Custom - Custom implementation of key affinity fynction<br/></li>\ + <li>Default - By default rendezvous affinity function with 1024 partitions is used<br/></li>\ + </ul>') + .panel-details(ng-if=rendezvousAff) + .details-row + +number-required('Partitions', affModel + '.Rendezvous.partitions', '"RendPartitions"', 'true', rendPartitionsRequired, '1024', '1', 'Number of partitions') + .details-row + +java-class('Backup filter', affModel + '.Rendezvous.affinityBackupFilter', '"RendAffinityBackupFilter"', 'true', 'false', + 'Backups will be selected from all nodes that pass this filter') + .details-row + +checkbox('Exclude neighbors', affModel + '.Rendezvous.excludeNeighbors', '"RendExcludeNeighbors"', + 'Exclude same - host - neighbors from being backups of each other and specified number of backups') + .panel-details(ng-if=fairAff) + .details-row + +number-required('Partitions', affModel + '.Fair.partitions', '"FairPartitions"', 'true', fairPartitionsRequired, '256', '1', 'Number of partitions') + .details-row + +java-class('Backup filter', affModel + '.Fair.affinityBackupFilter', '"FairAffinityBackupFilter"', 'true', 'false', + 'Backups will be selected from all nodes that pass this filter') + .details-row + +checkbox('Exclude neighbors', affModel + '.Fair.excludeNeighbors', '"FairExcludeNeighbors"', + 'Exclude same - host - neighbors from being backups of each other and specified number of backups') + .panel-details(ng-if=customAff) + .details-row + +java-class('Class name:', affModel + '.Custom.className', '"AffCustomClassName"', 'true', customAff, + 'Custom key affinity function implementation class name') + .settings-row + +java-class('Mapper:', model + '.affinityMapper', '"AffMapCustomClassName"', 'true', 'false', + 'Provide custom affinity key for any given key') + .col-sm-6 + +preview-xml-java(model, 'cacheAffinity') http://git-wip-us.apache.org/repos/asf/ignite/blob/f4a1e6ca/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade index f2d3e2b..e8dfb3a 100644 --- a/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade +++ b/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade @@ -61,7 +61,7 @@ include /app/helpers/jade/mixins.jade Note that in this mode entries can be evicted only to swap\ </li>\ </ul>') - .settings-row(data-ng-show=model + '.memoryMode !== "OFFHEAP_VALUES"') + .settings-row(ng-show=model + '.memoryMode !== "OFFHEAP_VALUES"') +dropdown-required('Off-heap memory:', model + '.offHeapMode', '"offHeapMode"', 'true', model + '.memoryMode === "OFFHEAP_TIERED"', 'Disabled', @@ -76,7 +76,7 @@ include /app/helpers/jade/mixins.jade <li>Limited - Off-heap storage has limited size</li>\ <li>Unlimited - Off-heap storage grow infinitely (it is up to user to properly add and remove entries from cache to ensure that off-heap storage does not grow infinitely)</li>\ </ul>') - .settings-row(data-ng-if=model + '.offHeapMode === 1 && ' + model + '.memoryMode !== "OFFHEAP_VALUES"') + .settings-row(ng-if=model + '.offHeapMode === 1 && ' + model + '.memoryMode !== "OFFHEAP_VALUES"') +number-required('Off-heap memory max size:', model + '.offHeapMaxMemory', '"offHeapMaxMemory"', 'true', model + '.offHeapMode === 1', 'Enter off-heap memory size', '1', 'Maximum amount of memory available to off-heap storage in bytes') http://git-wip-us.apache.org/repos/asf/ignite/blob/f4a1e6ca/modules/web-console/frontend/views/configuration/caches.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/views/configuration/caches.jade b/modules/web-console/frontend/views/configuration/caches.jade index 4a4cf2e..73a6309 100644 --- a/modules/web-console/frontend/views/configuration/caches.jade +++ b/modules/web-console/frontend/views/configuration/caches.jade @@ -44,6 +44,7 @@ include /app/helpers/jade/mixins.jade +advanced-options-toggle-default div(ng-show='ui.expanded') + include /app/modules/states/configuration/caches/affinity.jade include /app/modules/states/configuration/caches/concurrency.jade include /app/modules/states/configuration/caches/near-cache-client.jade include /app/modules/states/configuration/caches/near-cache-server.jade