internal virtual bool ScheduleMoves4Block(Mover.StorageTypeDiff diff, LocatedBlock lb) { IList <Mover.MLocation> locations = Mover.MLocation.ToLocations(lb); Sharpen.Collections.Shuffle(locations); Dispatcher.DBlock db = this._enclosing.NewDBlock(lb.GetBlock().GetLocalBlock(), locations ); foreach (StorageType t in diff.existing) { foreach (Mover.MLocation ml in locations) { Dispatcher.Source source = this._enclosing.storages.GetSource(ml); if (ml.storageType == t && source != null) { // try to schedule one replica move. if (this.ScheduleMoveReplica(db, source, diff.expected)) { return(true); } } } } return(false); }
private void Add(Dispatcher.Source source, Dispatcher.DDatanode.StorageGroup target ) { sources.Put(source); if (target != null) { targets.Put(target); GetTargetStorages(target.GetStorageType()).AddItem(target); } }
private void MatchSourceWithTargetToMove(Dispatcher.Source source, Dispatcher.DDatanode.StorageGroup target) { long size = Math.Min(source.AvailableSizeToMove(), target.AvailableSizeToMove()); Dispatcher.Task task = new Dispatcher.Task(target, size); source.AddTask(task); target.IncScheduledSize(task.GetSize()); dispatcher.Add(source, target); Log.Info("Decided to move " + StringUtils.ByteDesc(size) + " bytes from " + source .GetDisplayName() + " to " + target.GetDisplayName()); }
/// <exception cref="System.IO.IOException"/> internal virtual void Init() { InitStoragePolicies(); IList <DatanodeStorageReport> reports = dispatcher.Init(); foreach (DatanodeStorageReport r in reports) { Dispatcher.DDatanode dn = dispatcher.NewDatanode(r.GetDatanodeInfo()); foreach (StorageType t in StorageType.GetMovableTypes()) { Dispatcher.Source source = dn.AddSource(t, long.MaxValue, dispatcher); long maxRemaining = GetMaxRemaining(r, t); Dispatcher.DDatanode.StorageGroup target = maxRemaining > 0L ? dn.AddTarget(t, maxRemaining ) : null; storages.Add(source, target); } } }
/// <summary>Choose the target storage within same Datanode if possible.</summary> internal virtual bool ChooseTargetInSameNode(Dispatcher.DBlock db, Dispatcher.Source source, IList <StorageType> targetTypes) { foreach (StorageType t in targetTypes) { Dispatcher.DDatanode.StorageGroup target = this._enclosing.storages.GetTarget(source .GetDatanodeInfo().GetDatanodeUuid(), t); if (target == null) { continue; } Dispatcher.PendingMove pm = source.AddPendingMove(db, target); if (pm != null) { this._enclosing.dispatcher.ExecutePendingMove(pm); return(true); } } return(false); }
internal virtual bool ChooseTarget(Dispatcher.DBlock db, Dispatcher.Source source , IList <StorageType> targetTypes, Matcher matcher) { NetworkTopology cluster = this._enclosing.dispatcher.GetCluster(); foreach (StorageType t in targetTypes) { foreach (Dispatcher.DDatanode.StorageGroup target in this._enclosing.storages.GetTargetStorages (t)) { if (matcher.Match(cluster, source.GetDatanodeInfo(), target.GetDatanodeInfo())) { Dispatcher.PendingMove pm = source.AddPendingMove(db, target); if (pm != null) { this._enclosing.dispatcher.ExecutePendingMove(pm); return(true); } } } } return(false); }
internal virtual bool ScheduleMoveReplica(Dispatcher.DBlock db, Dispatcher.Source source, IList <StorageType> targetTypes) { // Match storage on the same node if (this.ChooseTargetInSameNode(db, source, targetTypes)) { return(true); } if (this._enclosing.dispatcher.GetCluster().IsNodeGroupAware()) { if (this.ChooseTarget(db, source, targetTypes, Matcher.SameNodeGroup)) { return(true); } } // Then, match nodes on the same rack if (this.ChooseTarget(db, source, targetTypes, Matcher.SameRack)) { return(true); } // At last, match all remaining nodes return(this.ChooseTarget(db, source, targetTypes, Matcher.AnyOther)); }
internal virtual bool ScheduleMoveReplica(Dispatcher.DBlock db, Mover.MLocation ml , IList <StorageType> targetTypes) { Dispatcher.Source source = this._enclosing.storages.GetSource(ml); return(source == null ? false : this.ScheduleMoveReplica(db, source, targetTypes)); }
/// <summary> /// Given a datanode storage set, build a network topology and decide /// over-utilized storages, above average utilized storages, /// below average utilized storages, and underutilized storages. /// </summary> /// <remarks> /// Given a datanode storage set, build a network topology and decide /// over-utilized storages, above average utilized storages, /// below average utilized storages, and underutilized storages. /// The input datanode storage set is shuffled in order to randomize /// to the storage matching later on. /// </remarks> /// <returns>the number of bytes needed to move in order to balance the cluster.</returns> private long Init(IList <DatanodeStorageReport> reports) { // compute average utilization foreach (DatanodeStorageReport r in reports) { policy.AccumulateSpaces(r); } policy.InitAvgUtilization(); // create network topology and classify utilization collections: // over-utilized, above-average, below-average and under-utilized. long overLoadedBytes = 0L; long underLoadedBytes = 0L; foreach (DatanodeStorageReport r_1 in reports) { Dispatcher.DDatanode dn = dispatcher.NewDatanode(r_1.GetDatanodeInfo()); foreach (StorageType t in StorageType.GetMovableTypes()) { double utilization = policy.GetUtilization(r_1, t); if (utilization == null) { // datanode does not have such storage type continue; } long capacity = GetCapacity(r_1, t); double utilizationDiff = utilization - policy.GetAvgUtilization(t); double thresholdDiff = Math.Abs(utilizationDiff) - threshold; long maxSize2Move = ComputeMaxSize2Move(capacity, GetRemaining(r_1, t), utilizationDiff , threshold); Dispatcher.DDatanode.StorageGroup g; if (utilizationDiff > 0) { Dispatcher.Source s = dn.AddSource(t, maxSize2Move, dispatcher); if (thresholdDiff <= 0) { // within threshold aboveAvgUtilized.AddItem(s); } else { overLoadedBytes += Precentage2bytes(thresholdDiff, capacity); overUtilized.AddItem(s); } g = s; } else { g = dn.AddTarget(t, maxSize2Move); if (thresholdDiff <= 0) { // within threshold belowAvgUtilized.AddItem(g); } else { underLoadedBytes += Precentage2bytes(thresholdDiff, capacity); underUtilized.AddItem(g); } } dispatcher.GetStorageGroupMap().Put(g); } } LogUtilizationCollections(); Preconditions.CheckState(dispatcher.GetStorageGroupMap().Size() == overUtilized.Count + underUtilized.Count + aboveAvgUtilized.Count + belowAvgUtilized.Count, "Mismatched number of storage groups" ); // return number of bytes to be moved in order to make the cluster balanced return(Math.Max(overLoadedBytes, underLoadedBytes)); }