Skip to main content

FixedDest

Move Type: Fixed Complexity: O(sample_size) instead of O(objects × containers)

Move objects from hot container to a specific fixed destination. Useful when you know exactly where objects should go.

Overview

FixedDest (also known as SINGLE_FIXED_DEST) evaluates moving objects from the hot container to a single predetermined destination container. Instead of exploring all possible destinations, it only considers moves to one specific container.

Use when:

  • Know exactly where objects should move (e.g., new server, specific region)
  • Migrating workload to specific destination
  • Filling a specific underutilized container
  • Testing "what if we moved to container X"

Avoid when:

  • Don't know destination (use Single)
  • Need to explore multiple destinations
  • Destination keeps changing
  • Want solver to find best destination

Quick Example

# Move objects from hot container to specific destination
solver.addSolver(
SolverSpecs(
localSearchSolverSpec=LocalSearchSolverSpec(
moveTypeList=[
FixedDestMoveTypeSpec(
specialContainer="new_server", # Fixed destination
),
]
)
)
)

Parameters

ParameterTypeRequiredDefaultDescription
specialContainerstringYesnullFixed destination container name
sampleSizeSampleSizeNonullSample subset of objects (probabilistic)

Parameter Details

specialContainer:

  • Name of the specific destination container
  • All object moves will target this container only
  • Must be a valid container name

sampleSize:

  • Optional sampling to reduce evaluations
  • Each object sampled with probability = sampleSize / (objects in hot container)
  • Useful for very large hot containers

How It Works

Given a hot container (most broken):

  1. Select object: Pick object from hot container
  2. Sample: With probability sampleSize / N, evaluate this object (if sampling enabled)
  3. Evaluate move: Test moving object to specialContainer
  4. Repeat: Try all objects in hot container
  5. Apply best: Apply the move to specialContainer that improves objective most

Visual Example

Before move:                          After move to specialContainer:
┌──────────────┐ ┌──────────────┐
│ Hot │ │ Hot │
│ Container │ ───────────> │ Container │
│ • obj1 ────┼──┐ │ • obj2 │
│ • obj2 │ │ │ • obj3 │
│ • obj3 │ │ └──────────────┘
└──────────────┘ │
│ ┌──────────────┐
┌──────────────┐ │ │ Special │
│ Special │ │ │ Container │
│ Container │ │ │ • objA │
│ • objA │ │ │ • objB │
│ • objB <───┼──┘ │ • obj1 ←────┼── Moved here!
└──────────────┘ └──────────────┘

Only one destination considered: specialContainer

Comparison with Regular Single

AspectSingleFixedDest
Destinations exploredAll containersOne specific container
ComplexityO(N × C)O(N) or O(S) if sampled
FlexibilityFinds best destinationTests specific destination
Use caseExplore all optionsKnow where to move

Complexity

Without sampling: O(N) With sampling: O(S)

Where:

  • N = number of objects in hot container
  • S = sample size

Example - Directed migration:

  • Hot container: 10,000 objects
  • Without sampling: Evaluate 10,000 moves to special container
  • With sampleSize=100: Evaluate ~100 moves to special container

Speedup vs Single: C× (where C = number of containers in system)

Usage Patterns

Server Migration

Move objects to new server:

# Migrate tasks from overloaded servers to new server
solver.addSolver(
SolverSpecs(
localSearchSolverSpec=LocalSearchSolverSpec(
moveTypeList=[
FixedDestMoveTypeSpec(
specialContainer="new_server_01", # New server
),
SingleMoveTypeSpec(), # Then explore all moves
]
)
)
)

Fill Specific Container

Target specific underutilized container:

# Fill specific underutilized container
solver = ProblemSolver(service_name="example", service_scope="test")

solver.addSolver(
SolverSpecs(
localSearchSolverSpec=LocalSearchSolverSpec(
moveTypeList=[
FixedDestMoveTypeSpec(
specialContainer="underutilized_server",
),
]
)
)
)

With Sampling for Large Containers

Sample subset when hot container is very large:

# Large hot container: sample 100 objects
solver = ProblemSolver(service_name="example", service_scope="test")

from rebalancer.interface.thrift.v2.SolverSpecs.thrift_types import SampleSize

solver.addSolver(
SolverSpecs(
localSearchSolverSpec=LocalSearchSolverSpec(
moveTypeList=[
FixedDestMoveTypeSpec(
specialContainer="destination_server",
sampleSize=SampleSize(
defaultSampleSize=100
), # Sample ~100 objects
),
]
)
)
)

Multi-Destination Strategy

Use multiple FixedDest in sequence for different destinations:

# Try multiple specific destinations in sequence
solver = ProblemSolver(service_name="example", service_scope="test")

solver.addSolver(
SolverSpecs(
localSearchSolverSpec=LocalSearchSolverSpec(
moveTypeList=[
FixedDestMoveTypeSpec(
specialContainer="server_A"
), # Try server A first
FixedDestMoveTypeSpec(specialContainer="server_B"), # Then server B
]
)
)
)

Performance Characteristics

Speedup Analysis

ContainersObjectsFixedDestSingleSpeedup
1001K1K100K100×
1K10K10K10M1000×
10K10K10K100M10000×

When Does It Help?

FixedDest helps when:

  • Known destination: Exactly where objects should go
  • Directed migration: Moving to specific new server/region
  • Testing: "What if we moved to container X?"
  • Filling specific container: Target underutilized container
  • Avoiding exploration overhead: Don't need to search all destinations

FixedDest does NOT help when:

  • Unknown destination: Need solver to find best destination
  • Exploring options: Want to try multiple destinations
  • General optimization: Use Single instead
  • Destination changes: Different destination each iteration

Comparison with Variants

Move TypeDestinationSourceUse Case
SingleAny containerHot containerGeneral moves
FixedDestFixed specificHot containerDirected migration
FixedSourceHot containerFixed specificPull from specific source
FixedDestMultiMoveFixed specificMultiple sourcesMulti-source to one dest

Decision tree:

  1. Know destination?FixedDest
  2. Know source?FixedSource
  3. Neither fixed?Single

Troubleshooting

Problem: No improving moves found

Diagnosis: Objects can't beneficially move to special container

Solutions:

  • Verify specialContainer is correct destination
  • Check capacity constraints on special container
  • May already be optimal for this destination
  • Try different destination or use Single

Problem: Wrong objects moving

Diagnosis: Objective function or constraints issue

Solutions:

  • Verify objective function rewards correct moves
  • Check constraints (capacity, affinity, etc.)
  • May need different objective or constraints
  • Review which objects the solver is selecting

Problem: Too slow even with fixed destination

Diagnosis: Hot container too large

Solutions:

  • Enable sampling with sampleSize parameter
  • Start with small sample (e.g., 100)
  • Verify special container can accept objects
  • Check objective function efficiency

Problem: Sampling missing good moves

Diagnosis: Sample size too small, random sampling misses best objects

Solutions:

  • Increase sampleSize
  • Remove sampling (evaluate all objects)
  • Run multiple times with different random seeds
  • May need deterministic selection (use Single)

When to Use FixedDest

DO use when:

  • Know exactly where objects should move
  • Migrating to new server/container
  • Filling specific underutilized container
  • Testing specific destination scenario
  • Want to avoid destination exploration overhead

DO NOT use when:

  • Need solver to find best destination
  • Want to explore multiple destinations
  • Destination is not predetermined
  • General optimization (use Single)

Fixed variants:

General alternatives:

  • Single - Explore all destinations
  • SingleFast - Fast exploration with early exit

Use together:

  • Try FixedDest for known destinations
  • Fall back to Single for exploration

Source Code

Next Steps