facebook/mcrouter

repository·main·Indexed 25 days ago

https://github.com/facebook/mcrouter

A high-performance memcached protocol router used to scale memcached deployments. It handles complex routing, replication, and failover logic. Key features include support for the memcached ASCII protocol, IPv6, SSL, connection pooling, multiple hashing schemes, prefix routing, and destination health monitoring. The project includes the mcpiper CLI tool for searching debug FIFOs and provides libraries for compression codec management and JSONC configuration preprocessing.

Tokens
3.3K
Snippets
6
Records
20
Agent score
86%

What's inside mcrouter

  1. Overview of Mcrouter features

    main

    Mcrouter is a memcached protocol router designed for scaling memcached deployments. Key features include:

    • Protocol & Connectivity: Memcached ASCII protocol, IPv6 support, SSL support, and Connection pooling.
    • Routing & Scaling: Multiple hashing schemes, Prefix routing, Replicated pools, Flexible routing, and Multi-cluster support.
    • Reliability & Performance: Destination health monitoring/automatic failover, Cold cache warm up, Reliable delete stream, and Quality of service.
    • Operations: Production traffic shadowing, Online reconfiguration, Broadcast operations, Multi-level caches, and Large values support.
    • Observability: Rich stats and debug commands.
  2. Install Mcrouter via Ubuntu package

    main

    Mcrouter provides an Ubuntu package for Bionic (18.04) amd64. Follow these steps to install it using apt:

    1. Add the repository key: wget -O - https://facebook.github.io/mcrouter/debrepo/bionic/PUBLIC.KEY | sudo apt-key add
    2. Add the repository to your /etc/apt/sources.list: deb https://facebook.github.io/mcrouter/debrepo/bionic bionic contrib
    3. Update the local repo cache: sudo apt-get update
    4. Install mcrouter: sudo apt-get install mcrouter
    $ wget -O - https://facebook.github.io/mcrouter/debrepo/bionic/PUBLIC.KEY | sudo apt-key add
    $ echo "deb https://facebook.github.io/mcrouter/debrepo/bionic bionic contrib" | sudo tee -a /etc/apt/sources.list
    $ sudo apt-get update
    $ sudo apt-get install mcrouter
  3. Run a simple Mcrouter setup with configuration string

    main

    You can run Mcrouter using a --config-str JSON string to define pools and routing. The following example sets up a single pool named 'A' containing a local memcached instance on port 5001, and routes all traffic to that pool. The router itself listens on port 5000.

    $ mcrouter \
        --config-str='{"pools":{"A":{"servers":["127.0.0.1:5001"]}},
                      "route":"PoolRoute|A"}' \
        -p 5000
    
    # To test the connection (assuming memcached is on 5001):
    $ echo -ne "get key\r\n" | nc 0 5000
  4. Configure compression codecs using CodecConfig

    main

    When defining compression settings in Mcrouter, use the CodecConfig struct to specify the properties of a compression codec.

    Fields:

    • id: A unique uint32_t identifier for the codec.
    • codecType: The CompressionCodecType used by the codec.
    • dictionary: A std::string containing the dictionary for the codec.
    • filteringOptions: FilteringOptions used to determine if the codec should be applied.
    • compressionLevel: A uint32_t representing the compression intensity (defaults to 1).
  5. Configure JsonClient Options

    main

    The carbon::JsonClient::Options struct is used to configure a JSON client for interacting with Carbon servers. Note that JsonClient is intended for testing and debugging purposes and is not recommended for production use due to slow JSON parsing/serialization.

    Available configuration fields:

    • host: Hostname of the carbon server (default: "localhost").
    • port: Port of the carbon server.
    • serverTimeoutMs: Server timeout in milliseconds (default: 200).
    • ignoreParsingErrors: Whether parsing errors should be ignored (they will still be displayed) (default: true).
    • useSsl: Whether or not to use SSL.
    • pemCertPath: Path to the SSL certificate.
    • pemKeyPath: Path to the SSL key.
    • pemCaPath: Path to the SSL CA.
    • sslServiceIdentity: The SSL service identity.
  6. Create a Compression Codec with a Dictionary

    main

    Use createCompressionCodec to instantiate a codec, optionally providing a pre-defined dictionary for dictionary-based compression. This is useful for optimizing compression on specific data types.

    std::unique_ptr<CompressionCodec> createCompressionCodec(
        CompressionCodecType type,
        std::unique_ptr<folly::IOBuf> dictionary,
        uint32_t id,
        FilteringOptions codecFilteringOptions = FilteringOptions(),
        uint32_t codecCompressionLevel = 1);
  7. Manage $children_list$ placeholders with pushChildrenList and popChildrenList

    main

    The RouteHandleFactory supports a mechanism to replace the $children_list$ placeholder in configuration files with a specific list of route handles.

    • pushChildrenList(std::vector<RouteHandlePtr> children): Pushes a list of route handles onto a stack. These handles will be used the next time the factory encounters $children_list$ in the configuration.
    • popChildrenList(): Removes the last list of children pushed.

    Important: Callers must explicitly call popChildrenList() once the configuration segment using the children list has been processed to avoid leaking the stack state.

  8. Retrieve codecs from CompressionCodecMap

    main

    A CompressionCodecMap provides access to specific CompressionCodec instances based on IDs or matching criteria.

    Methods:

    • get(uint32_t id): Returns the CompressionCodec* associated with the given ID, or nullptr if not found.
    • getBest(const CodecIdRange& codecRange, const size_t bodySize, const size_t typeId): Returns the CompressionCodec* that best matches the provided filters (body size and type ID) within the specified codecRange.
    • getBestByTypeId(const CodecIdRange& codecRange, const size_t bodySize, const size_t typeId): Similar to getBest, but restricts the search to codecs where the typeId matches the provided typeId of the reply.
    • getIdRange(): Returns a CodecIdRange representing the contiguous range of codec IDs present in the map.
  9. Send requests using JsonClient::sendRequests

    main

    Use sendRequests to send one or more requests synchronously to a Carbon server.

    • requestName: The name of the request.
    • requests: A folly::dynamic object containing either a single request or a list of requests.
    • replies: An output argument (folly::dynamic) that will contain the replies. If multiple requests were sent, the replies will be a JSON object where the reply index matches the corresponding request index.

    Returns true if no errors are found, false otherwise.

  10. Run a standalone Mcrouter server with runServer()

    main

    To spawn a standalone Mcrouter server that blocks until shutdown, use the runServer template function. This function requires Mcrouter configuration options and standalone-specific options. You can optionally provide a StandalonePreRunCb callback to perform setup tasks on the router instance before the server starts running.

    Returns true if the server shut down cleanly, or false if errors occurred.

  11. Use RouteHandleFactory to parse RouteHandle trees from JSON

    main

    The RouteHandleFactory class is used to parse JSON objects into RouteHandle trees. It is typically initialized with a RouteHandleProviderIf and a threadId to specify where the created handles will run.

    Key methods for end-users/integrators include:

    • create(const folly::dynamic& json): Creates a single RouteHandle from a JSON object.
    • createList(const folly::dynamic& json): Creates multiple subtrees (a list of RouteHandles) from a JSON array, object, or string.
    • addNamed(const folly::StringPiece name, const folly::dynamic& json): Registers a named route handle for later use. Note: The provided JSON object must outlive the factory instance.
    • parsePool(const folly::dynamic& json): Loads a pool from a ConfigApi, handling inherit expansion and returning the final JSON blob.