CLOUDSTACK-6049: Give priority to cache stores where data object is already there instead of randomly picking one in case there are multiple cache stores in the scope.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/bac2c1e5 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/bac2c1e5 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/bac2c1e5 Branch: refs/heads/rbac Commit: bac2c1e5b49a1b5c4be37ca17d5e4829a2906782 Parents: 04766c6 Author: Min Chen <min.c...@citrix.com> Authored: Thu Feb 6 17:19:24 2014 -0800 Committer: Min Chen <min.c...@citrix.com> Committed: Thu Feb 6 17:19:24 2014 -0800 ---------------------------------------------------------------------- .../api/storage/StorageCacheManager.java | 2 ++ .../cache/allocator/StorageCacheAllocator.java | 3 ++ .../allocator/StorageCacheRandomAllocator.java | 38 ++++++++++++++++++++ .../cache/manager/StorageCacheManagerImpl.java | 13 +++++++ .../motion/AncientDataMotionStrategy.java | 2 +- 5 files changed, 57 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bac2c1e5/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java ---------------------------------------------------------------------- diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java index 6d1ac2d..b8aeb5c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java @@ -21,6 +21,8 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public interface StorageCacheManager { DataStore getCacheStorage(Scope scope); + DataStore getCacheStorage(DataObject data, Scope scope); + DataObject createCacheObject(DataObject data, Scope scope); /** http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bac2c1e5/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java ---------------------------------------------------------------------- diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java index 4259d9e..96251c5 100644 --- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java @@ -18,9 +18,12 @@ */ package org.apache.cloudstack.storage.cache.allocator; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; public interface StorageCacheAllocator { DataStore getCacheStore(Scope scope); + + DataStore getCacheStore(DataObject data, Scope scope); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bac2c1e5/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java ---------------------------------------------------------------------- diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java index 7c11561..b4ef595 100644 --- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java @@ -26,9 +26,13 @@ import javax.inject.Inject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import com.cloud.storage.ScopeType; @@ -37,6 +41,8 @@ public class StorageCacheRandomAllocator implements StorageCacheAllocator { private static final Logger s_logger = Logger.getLogger(StorageCacheRandomAllocator.class); @Inject DataStoreManager dataStoreMgr; + @Inject + ObjectInDataStoreManager objectInStoreMgr; @Override public DataStore getCacheStore(Scope scope) { @@ -54,4 +60,36 @@ public class StorageCacheRandomAllocator implements StorageCacheAllocator { Collections.shuffle(cacheStores); return cacheStores.get(0); } + + @Override + public DataStore getCacheStore(DataObject data, Scope scope) { + if (scope.getScopeType() != ScopeType.ZONE) { + s_logger.debug("Can only support zone wide cache storage"); + return null; + } + + List<DataStore> cacheStores = dataStoreMgr.getImageCacheStores(scope); + if (cacheStores.size() <= 0) { + s_logger.debug("Can't find staging storage in zone: " + scope.getScopeId()); + return null; + } + + // if there are multiple cache stores, we give priority to the one where data is already there + if (cacheStores.size() > 1) { + for (DataStore store : cacheStores) { + DataObjectInStore obj = objectInStoreMgr.findObject(data, store); + if (obj != null && obj.getState() == ObjectInDataStoreStateMachine.State.Ready) { + s_logger.debug("pick the cache store " + store.getId() + " where data is already there"); + return store; + } + } + + // otherwise, just random pick one + Collections.shuffle(cacheStores); + } + return cacheStores.get(0); + + } + + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bac2c1e5/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java index fe2543c..3a502d1 100644 --- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java @@ -90,6 +90,19 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return null; } + + @Override + public DataStore getCacheStorage(DataObject data, Scope scope) { + for (StorageCacheAllocator allocator : storageCacheAllocator) { + DataStore store = allocator.getCacheStore(data, scope); + if (store != null) { + return store; + } + } + return null; + } + + protected List<DataStore> getCacheStores() { QueryBuilder<ImageStoreVO> sc = QueryBuilder.create(ImageStoreVO.class); sc.and(sc.entity().getRole(), SearchCriteria.Op.EQ, DataStoreRole.ImageCache); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bac2c1e5/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java ---------------------------------------------------------------------- diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 7ae793f..0556479 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -195,7 +195,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { protected DataObject cacheSnapshotChain(SnapshotInfo snapshot, Scope scope) { DataObject leafData = null; - DataStore store = cacheMgr.getCacheStorage(scope); + DataStore store = cacheMgr.getCacheStorage(snapshot, scope); while (snapshot != null) { DataObject cacheData = cacheMgr.createCacheObject(snapshot, store); if (leafData == null) {