volcano.sh/volcano@v1.9.0/docs/design/resource-comparison.md (about)

     1  # Resource Comparison
     2  
     3  ## Motivation
     4  When review the issues about proportion plugin and preempt action bug report, I found that the root reason of most bugs
     5  are related with existing resource comparison functions `Less` `LessEqual` `LessEqualStrict`. After a tour of deep analysis,
     6  I get a better understanding of scenarios and the incoordination between these scenarios and existing functions. The bugs
     7  mainly lie at the following aspects:
     8  * Lack of consideration about missing dimensions. When deal with the comparison of two resource lists whose dimensions
     9    are not all the same, default value of missing dimensions may should be considered as **zero** or **infinity**. For example,
    10    `L = {cpu:1c, memory:1G}`,`R = {cpu:2c, memory:2G, gpu:2}`. It's obvious that `L` has no `gpu` dimension. When default value
    11    of missing dimension is `zero`, it means `L = {cpu:1c, memory:1G, gpu:0}`. It's reasonable to consider `L < R` for all
    12    dimensions in `L` are less than that of `R`. However, when default value is `infinity`, `L` can be treated as `{cpu:1c,
    13    memory:1G, gpu:max}`. It's hard to say `L < R` for `gpu` in `L` is larger than that in `R`. But we still can say `L` is
    14    Less than `R` in some dimensions. Existing resource comparison functions all regard default value of missing dimensions
    15    as `zero` by default.
    16  * Incomplete coverage of resource comparison functions. Existing resource comparison functions cannot cover all scenarios,
    17    which lead to some misuse for later developers. For example, when judge whether idle resource of a node can satisfy
    18    the request of a task, what we need is **resource amount in any dimension cannot meet the request, the node cannot meet
    19    the task**. So the code should be `if node.idle.LessPartly(task.request) {break}`.
    20  
    21  In order to fix these bugs, as well as make it clear for later developers, I organize all resource comparison scenarios
    22  and provide solution about completing existing functions as following parts.
    23  
    24  ## Recommended Functions
    25  | Name | Comment | Example | Original function | Used plugins/actions | Transformation |
    26  | :----:| :----: | :----: | :----: | :----: | :----: |
    27  | l.Less(r *api.Resource, defaultValue string) | Values in all dimensions in `l` are less than that in `r` | L{cpu:1c, memory:2G} < R{cpu:2c, memory:4G} | Less(rr *Resource) | proportion | * |
    28  | l.LessEqual(r *api.Resource, defaultValue string) | Values in all dimensions in `l` are less than or equal with that in `r` | L{cpu:1c, memory:2G} <= R{cpu:1c, memory:4G} | LessEqual(rr *Resource)/LessEqualStrict(rr *Resource) | allocate/preempt/reclaim/overcommit/proportion/reservation/topology | * |
    29  | l.LessPartly(r *api.Resource, defaultValue string) | Values in part dimensions in `l` are less than that in `r` | L{cpu:4c, memory:2G} < \| R{cpu:2c, memory:4G} | * | topology | * |
    30  | l.LessEqualPartly(r *api.Resource, defaultValue string) | Values in part dimensions in `l` are less than or equal with that in `r` | L{cpu:4c, memory:2G} <= \| R{cpu:2c, memory:2G} | * | * | * |
    31  | l.Equal(r *api.Resource, defaultValue string) | Values in all dimensions in `l` are equal with that in `r` && values in all dimensions in `r` are equal with that in `l` | L{cpu:1c, memory:2G} = R{cpu:1c, memory:2G} | * | * | * |
    32  | l.Greater(r *api.Resource, defaultValue string) | Values in all dimensions in `l` are greater than that in `r` | L{cpu:2c, memory:4G} > R{cpu:1c, memory:2G} | * | * | !l.LessEqualPartly(r *api.Resource, defaultValue string) |
    33  | l.GreaterEqual(r *api.Resource, defaultValue string) | Values in all dimensions in `l` are greater than or equal with that in `r` | L{cpu:2c, memory:4G} >= R{cpu:2c, memory:2G} | * | * | !l.LessPartly(r *api.Resource, defaultValue string) |
    34  | l.GreaterPartly(r *api.Resource, defaultValue string) | Values in part dimensions in `l` are greater than that in `r` | L{cpu:4c, memory:2G} > \| R{cpu:2c, memory:4G} | * | * | !l.LessEqual(r *api.Resource, defaultValue string) |
    35  | l.GreaterEqualPartly(r *api.Resource, defaultValue string) | Values in part dimensions in `l` are greater than or equal with that in `r` | L{cpu:2c, memory:2G} >= \| R{cpu:2c, memory:4G} | * | * | !l.Less(r *api.Resource, defaultValue string) |
    36  
    37  ## Comments
    38  * ` <| `  ` <=| `  ` >| `  ` >=| ` are self-defined mathematical symbols.
    39  * Part scenarios are overlapped in part functions, but it makes sense when deal with specific applications.
    40  * Part functions are not used in any plugins currently. But it's recommended to define them previously for later use.
    41  * Parameter `defaultValue` means what value should be given to blank dimension in either of L and R. It can only be one of `zero` or `infinity`.
    42  
    43  ## Examples
    44  * L = {cpu: 1c, memory:1G}, R = {cpu: 2c, memory:2G, gpu:2}
    45  
    46  |  | L | R |
    47  | :----: | :----: | :----: |
    48  | defaultValue = zero | {cpu: 1c, memory:1G, gpu:0} | {cpu: 2c, memory:2G, gpu:2} |
    49  | defaultValue = infinity | {cpu: 1c, memory:1G, gpu:max} | {cpu: 2c, memory:2G, gpu:2} |
    50  
    51  |  | Less | LessEqual | LessPartly | LessEqualPartly | 
    52  | :----: | :----: | :----: | :----: | :----: |
    53  | defaultValue = zero | true | true | true | true |
    54  | defaultValue = infinity | false | false | true | true |
    55  
    56  * L = {cpu: 1c, memory:1G, gpu: 1}, R = {cpu: 2c, memory:2G}
    57  
    58  |  | L | R |
    59  | :----: | :----: | :----: |
    60  | defaultValue = zero | {cpu: 1c, memory:1G, gpu:1} | {cpu: 2c, memory:2G, gpu:0} |
    61  | defaultValue = infinity | {cpu: 1c, memory:1G, gpu:1} | {cpu: 2c, memory:2G, gpu:max} |
    62  
    63  |  | Less | LessEqual | LessPartly | LessEqualPartly | 
    64  | :----: | :----: | :----: | :----: | :----: |
    65  | defaultValue = zero | false | false | true | true |
    66  | defaultValue = infinity | true | true | true | true |
    67  
    68  * L = {cpu: 1c, memory:1G}, R = {gpu: 2}
    69  
    70  |  | L | R |
    71  | :----: | :----: | :----: |
    72  | defaultValue = zero | {cpu: 1c, memory:1G, gpu:0} | {cpu: 0c, memory:0G, gpu:2} |
    73  | defaultValue = infinity | {cpu: 1c, memory:1G, gpu:max} | {cpu: max c, memory: max G, gpu:2} |
    74  
    75  |  | Less | LessEqual | LessPartly | LessEqualPartly | 
    76  | :----: | :----: | :----: | :----: | :----: |
    77  | defaultValue = zero | false | false | true | true |
    78  | defaultValue = infinity | false | false | true | true |