github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/config/docs/resourceManager.MD (about)

     1  # libp2p Resource Manager Configuration in Flow Go
     2  ## Table of Contents
     3  1. [Overview](#overview)
     4  2. [What are These Limits?](#what-are-these-limits)
     5  3. [How to Set Limits](#how-to-set-limits)
     6      1. [In Configuration File (`default-config.yaml`)](#in-configuration-file-default-configyaml)
     7      2. [Via Runtime Flags](#via-runtime-flags)
     8  4. [Importance of Each Resource Scope](#importance-of-each-resource-scope)
     9      1. [What does each scope mean?](#what-does-each-scope-mean)
    10      2. [Scope Hierarchy](#scope-hierarchy)
    11      3. [On Transient Scope](#on-transient-scope)
    12  5. [Case Study: what does scopes mean in terms of one resource?](#case-study-what-does-scopes-mean-in-terms-of-one-resource)
    13      1. [System Scope](#system-scope)
    14      2. [Transient Scope](#transient-scope)
    15      3. [Protocol Scope](#protocol-scope)
    16      4. [Peer Scope](#peer-scope)
    17      5. [Peer-Protocol Scope](#peer-protocol-scope)
    18  6. [Troubleshooting (For Flow Node Operators)](#troubleshooting-for-flow-node-operators)
    19      1. [Observation](#observation)
    20      2. [Excessive Streams Across All Protocols and Peers](#excessive-streams-across-all-protocols-and-peers)
    21      3. [Excessive Streams in a Specific Protocol](#excessive-streams-in-a-specific-protocol)
    22      4. [Excessive Streams from Individual Peers](#excessive-streams-from-individual-peers)
    23      5. [Excessive Streams from a Specific Peer on a Specific Protocol](#excessive-streams-from-a-specific-peer-on-a-specific-protocol)
    24  7. [Wildcard: Increasing all limit overrides at scale](#wildcard-increasing-all-limit-overrides-at-scale)
    25  8. [References](#references)
    26  
    27  ## Overview
    28  In Flow Go, the libp2p Resource Manager plays a crucial role in managing network resources effectively. This document provides guidance on setting various limits through configuration files and runtime flags, helping you optimize resource usage based on specific network conditions or protocol behaviors.
    29  
    30  ### What are These Limits?
    31  The libp2p Resource Manager in Flow Go allows setting limits on different types of network resources like streams, connections, file descriptors, and memory. These limits are categorized under different scopes: `system`, `transient`, `protocol`, `peer`, and `peer-protocol`. Each scope serves a distinct purpose in resource management.
    32  
    33  ### How to Set Limits
    34  
    35  #### In Configuration File (`default-config.yaml`)
    36  You can define these limits in the `default-config.yaml` file under the `libp2p-resource-manager` section. Each limit can be set for different scopes as shown:
    37  
    38  ```yaml
    39  libp2p-resource-manager:
    40    memory-limit-ratio: <value>
    41    file-descriptors-ratio: <value>
    42    limits-override:
    43      <scope>:
    44        streams-inbound: <value>
    45        streams-outbound: <value>
    46        ...
    47  ```
    48  
    49  #### Via Runtime Flags
    50  Each limit can also be dynamically set using runtime flags in the format:
    51  `--libp2p-resource-manager-limits-override-<scope>-<limit>`
    52  
    53  For example:
    54  - To set inbound stream limits for the system scope: `--libp2p-resource-manager-limits-override-system-streams-inbound=<value>`
    55  - For outbound streams in the protocol scope: `--libp2p-resource-manager-limits-override-protocol-streams-outbound=<value>`
    56  
    57  **Exceptions:** The `memory-limit-ratio` and `file-descriptors-ratio` limits are set as the following flags and both must be **between 0 and 1**:
    58  - `--libp2p-resource-manager-memory-limit-ratio=<value>`
    59  - `--libp2p-resource-manager-file-descriptors-ratio=<value>`
    60  - For example: `--libp2p-resource-manager-memory-limit-ratio=0.5` means that the memory limit for libp2p resources is set to 50% of the available memory, i.e.,
    61      the libp2p can take up to 50% of the available memory on the system.
    62  
    63    
    64  ### Importance of Each Resource Scope
    65  In the libp2p Resource Manager, scopes are organized hierarchically; `system`, `protocol`, `peer`, and `peer-protocol` scopes are arranged in a _descending order of priority_.
    66  This means that the `system` scope has the highest priority, then `protocol` scope, `peer` scope, and `peer-protocol` scope.
    67  As we explain later in this documentation, the `transient` scope is a special case and does not strictly fit in the hierarchy of scopes.
    68  
    69  #### What does each scope mean?
    70     - **System Scope**: sets the global limits for the entire system and ensures overall stability and prevents resource hogging by any single component.
    71     - **Transient Scope**: manages resources for partially established connections or streams and prevents resource drainage during the establishment phase. 
    72         Transient resources are those that are not yet fully established, like a connection that's not yet fully established or a stream that's not yet fully opened. The transient scope is critical
    73         for guarding against resource drainage during the establishment phase.
    74     - **Protocol Scope**: sets limits for specific protocols (e.g., DHT, gossipsub) and prevents any single protocol from dominating resource usage. The protocol scope is essential for 
    75       protocol-specific resource tuning and preventing abuse by any single protocol.
    76     - **Peer Scope**: manages resources used by individual (remote) peers on the local peer and prevents a single (remote) peer from exhausting resources of the local peer. The peer scope is critical for preventing abuse by any single (remote) peer.
    77     - **Peer-Protocol Scope**: sets limits for specific (remote) peers on specific protocols at the local peer and prevents any single (remote) peer from dominating resource usage on a specific protocol at the local peer. It also prevents a single protocol 
    78        to dominate resource usage of a specific (remote) peer on the local peer among all the protocols the (remote) peer is participating in with the local peer. 
    79  
    80  #### Scope Hierarchy
    81  The higher order scopes **"override"** limits on lower scopes:
    82  1. **System Scope vs. Protocol/Peer Scopes**:
    83      - The system scope sets global limits. If the system scope has a lower limit than a protocol or peer scope, the system limit will be the effective constraint 
    84        because it's the upper bound for the entire system.
    85      - For example, if the system scope has an inbound stream limit of 10,000 and a protocol scope has a limit of 15,000, 
    86          the effective limit will be 10,000 because the system scope's limit applies globally.
    87  
    88  2. **Protocol Scope vs. Peer Scope**:
    89      - The protocol scope sets limits for specific protocols, while the peer scope sets limits for individual peers. These are independent of each other but both are under the overarching system scope.
    90      - A peer can't exceed the limits set by the protocol scope, and vice versa. They operate within their own contexts but under the maximum limits imposed by the system scope.
    91  
    92  It's essential to understand that the lowest limit in the hierarchy of applicable scopes will effectively be the operational limit. 
    93  If the system inbound stream limit is lower than the protocol inbound stream limit, the system limit will effectively cap the maximum number of inbound streams, regardless of the higher limit set at the protocol level.
    94  Also, the higher scopes limits must be configured in a way that they don't override the limits of lower scopes; rather, they add another layer of constraint. 
    95  Each scope must independently satisfy its own limits without violating the limits of the scopes above it.
    96  When configuring limits, it's crucial to consider the hierarchical nature of these scopes. 
    97  Ensure that the limits at lower scopes (like protocol or peer) are set within the bounds of higher scopes (like system) to maintain a coherent and effective resource management strategy.
    98  
    99  #### On Transient Scope
   100  The `transient` scope in the libp2p Resource Manager hierarchy has a specific and unique role. 
   101  It is placed **alongside** other scopes like `system`, `protocol`, `peer`, and `peer-protocol`, but it serves a distinct purpose. Here's how the `transient` scope fits into the hierarchy:
   102  The `transient` scope is designed to manage resources for connections and streams that are in the process of being established but haven't yet been fully negotiated or associated with a specific peer or protocol.
   103  This includes streams that are awaiting protocol negotiation or connections that are in the initial stages of establishment.
   104  
   105  In terms of hierarchy, the `transient` scope is below `system`, but is not strictly above or below other scopes like `protocol`. 
   106  Instead, it operates more as a parallel scope that specifically handles resources in a temporary, intermediate state.
   107  While the `system` scope sets the global limits, the `transient` scope sets limits on resources that are not yet fully categorized into other specific scopes (like `peer` or `protocol`).
   108  The limits set in the `transient` scope are independent of those in the `protocol`, `peer`, and `peer-protocol` scopes but still operate under the overarching constraints of the `system` scope. 
   109  Once a connection or stream transitions out of the `transient` state (i.e., when a protocol is negotiated, or a peer is identified), it then falls under the appropriate scope (such as `protocol` or `peer`) and adheres to the limits set within those scopes.
   110  The `transient` scope is critical for managing resources during the negotiation phase of connections and streams. It helps in protecting the system against resource exhaustion attacks that can occur at the initial stages of connection or stream establishment.
   111  
   112  **Example:** For example, when the limit for system-wide connections is set lower than the limit for transient-wide connections in the libp2p Resource Manager, the system-wide limit effectively becomes the constraining factor
   113  In this example, the system-wide connections limit acts as the global cap for all connections in the libp2p network, regardless of their state (established, transient, etc.).
   114  If this limit is lower than the transient-wide limit, it essentially restricts the total number of connections (including transient ones) to this lower system-wide limit.
   115  The transient-wide limit is intended to manage connections that are in the process of being fully established. 
   116  
   117  ### Case Study: what does scopes mean in terms of one resource?
   118  As an example, we study the default limits for "Streams Inbound/Outbound" at different scopes in the libp2p Resource Manager. The limtis on other resources follow a similar pattern.
   119  Here's an explanation of what these default limits mean at each scope:
   120  
   121  ### System Scope
   122  - **Streams Inbound/Outbound (e.g., 15,000)**:
   123      - **Meaning**: This limit defines the maximum number of inbound and outbound streams that can be active across the entire system, regardless of the specific protocols or peers involved.
   124      - **Implication**: It is a global cap ensuring that the total number of streams at any time does not exceed this limit, thus preventing system-wide resource exhaustion due to too many streams.
   125  
   126  ### Transient Scope
   127  - **Streams Inbound/Outbound (e.g., 15,000)**:
   128      - **Meaning**: This limit controls the number of streams in the transient state, i.e., streams that are being set up but not yet fully established or associated with a peer/protocol.
   129      - **Implication**: It provides a buffer for handling stream negotiations, ensuring the system can manage a high volume of initiating connections without overwhelming the resources during the setup phase.
   130  
   131  ### Protocol Scope
   132  - **Streams Inbound/Outbound (e.g., 5,000)**:
   133      - **Meaning**: This limit specifies the maximum number of inbound and outbound streams for each protocol. It applies to each protocol independently.
   134      - **Implication**: It ensures that no single protocol can dominate the network's resources, maintaining a balance in resource allocation among various protocols.
   135  
   136  ### Peer Scope
   137  - **Streams Inbound/Outbound (e.g., 1,000)**:
   138      - **Meaning**: This sets the maximum number of inbound and outbound streams allowed per (remote) peer on the local peer.
   139      - **Implication**: It restricts the resource usage by individual peers, ensuring no single (remote) peer can exhaust network resources with too many streams.
   140  
   141  ### Peer-Protocol Scope
   142  - **Streams Inbound/Outbound (e.g., 500)**:
   143      - **Meaning**: This limit is the most granular, applying to streams from each (remote) peer for each protocol on the local peer.
   144      - **Implication**: It offers fine-grained control, preventing any (remote) peer from using excessive resources in a specific protocol on the local peer, thus ensuring balanced resource use.
   145  
   146  ## Troubleshooting (For Flow Node Operators)
   147  This troubleshooting guide works based on the case of excessive streams in the network. Similar guidelines can be applied to other resources as well.
   148  
   149  ### Observation
   150  If you observe an excessive number of open streams (or open `goroutines` affiliated with a libp2p protocol) in your network, 
   151  the appropriate action would be to adjust the stream limits within specific scopes, depending on the nature of the issue.
   152  
   153  ### 1. Excessive Streams Across All Protocols and Peers
   154  - **Scope**: System Scope
   155  - **Limits to Adjust**:
   156      - `streams-inbound`
   157      - `streams-outbound`
   158  - **Reason**: The system scope applies globally across all peers and protocols. Adjusting these limits helps manage the overall number of streams in the network.
   159  
   160  ### 2. Excessive Streams in a Specific Protocol
   161  - **Scope**: Protocol Scope
   162  - **Limits to Adjust**:
   163      - `streams-inbound`
   164      - `streams-outbound`
   165  - **Reason**: If a particular protocol (e.g., DHT, gossipsub) is opening too many streams, tightening limits in the protocol scope can restrict the resource usage by that specific protocol.
   166  
   167  ### 3. Excessive Streams from Individual Peers
   168  - **Scope**: Peer Scope
   169  - **Limits to Adjust**:
   170      - `streams-inbound`
   171      - `streams-outbound`
   172  - **Reason**: When specific peers are opening too many streams, adjusting these limits can prevent any single peer from using an excessive number of streams.
   173  
   174  ### 4. Excessive Streams from a Specific Peer on a Specific Protocol
   175  - **Scope**: Peer-Protocol Scope
   176  - **Limits to Adjust**:
   177      - `streams-inbound`
   178      - `streams-outbound`
   179  - **Reason**: This is the most granular level of control, where you can restrict stream usage for a specific protocol used by a specific peer.
   180  
   181  ## Wildcard: Increasing all limit overrides at scale
   182  In order to preserve the hierarchy of scopes, you need to adjust the limits in each scope in a way that they don't override the limits of higher scopes.
   183  One easy way is to increase all limits by a certain factor across all scopes. For example, if you want to increase all limits by 1.5 times, you can do so by adjusting the flags for each limit within each scope.
   184  
   185  ### System Scope
   186  1. **Streams Inbound/Outbound**
   187      - `--libp2p-resource-manager-limits-override-system-streams-inbound=<1.5 * current value>`
   188      - `--libp2p-resource-manager-limits-override-system-streams-outbound=<1.5 * current value>`
   189  2. **Connections Inbound/Outbound**
   190      - `--libp2p-resource-manager-limits-override-system-connections-inbound=<1.5 * current value>`
   191      - `--libp2p-resource-manager-limits-override-system-connections-outbound=<1.5 * current value>`
   192  3. **File Descriptors**
   193      - `--libp2p-resource-manager-limits-override-system-fd=<1.5 * current value>`
   194  4. **Memory Bytes**
   195      - `--libp2p-resource-manager-limits-override-system-memory-bytes=<1.5 * current value>`
   196  
   197  ### Transient Scope
   198  1. **Streams Inbound/Outbound**
   199      - `--libp2p-resource-manager-limits-override-transient-streams-inbound=<1.5 * current value>`
   200      - `--libp2p-resource-manager-limits-override-transient-streams-outbound=<1.5 * current value>`
   201  2. **Connections Inbound/Outbound**
   202      - `--libp2p-resource-manager-limits-override-transient-connections-inbound=<1.5 * current value>`
   203      - `--libp2p-resource-manager-limits-override-transient-connections-outbound=<1.5 * current value>`
   204  3. **File Descriptors**
   205      - `--libp2p-resource-manager-limits-override-transient-fd=<1.5 * current value>`
   206  4. **Memory Bytes**
   207      - `--libp2p-resource-manager-limits-override-transient-memory-bytes=<1.5 * current value>`
   208  
   209  ### Protocol Scope
   210  1. **Streams Inbound/Outbound**
   211      - `--libp2p-resource-manager-limits-override-protocol-streams-inbound=<1.5 * current value>`
   212      - `--libp2p-resource-manager-limits-override-protocol-streams-outbound=<1.5 * current value>`
   213  
   214  ### Peer Scope
   215  1. **Streams Inbound/Outbound**
   216      - `--libp2p-resource-manager-limits-override-peer-streams-inbound=<1.5 * current value>`
   217      - `--libp2p-resource-manager-limits-override-peer-streams-outbound=<1.5 * current value>`
   218  
   219  ### Peer-Protocol Scope
   220  1. **Streams Inbound/Outbound**
   221      - `--libp2p-resource-manager-limits-override-peer-protocol-streams-inbound=<1.5 * current value>`
   222      - `--libp2p-resource-manager-limits-override-peer-protocol-streams-outbound=<1.5 * current value>`
   223  
   224  ### Notes
   225  - Replace `<1.5 * current value>` with the actual calculated value from `default-config.yaml`. For example, if the current system streams inbound limit is 10,000, the new value would be `--libp2p-resource-manager-limits-override-system-streams-inbound=15000`.
   226  
   227  
   228  # References
   229  - https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/README.md