扩展 LMCache#

LMCache 旨在可扩展,允许在不修改核心的情况下集成自定义功能。主要的扩展机制包括:

  • 原生连接器框架 – 使用 pybind11 构建高性能 C++ 存储连接器,支持非多进程和多进程模式。提供多线程 I/O、批量切片和基于 eventfd 的完成。

  • 存储插件框架 – 通过标准化接口集成新的存储后端(自定义缓存存储模块)。

  • 外部远程连接器框架 – 通过标准化接口集成新的远程 KV 存储连接器,用于外部/分布式存储系统。该功能仍然支持,但计划在 v0.5.0 中弃用。它被 远程存储插件框架 替代。

  • 远程存储插件框架 – 集成新的远程存储连接器,用于远程/分布式 KV 存储系统。

  • 运行时插件框架 – 作为独立进程运行自定义脚本,以增强 LMCache 的功能。

        flowchart LR
   subgraph "LMCache Process"
      direction TB
      core["LMCache Core Engine (Cache Manager & APIs)"]
      runtimePluginMgr["Runtime Plugin Launcher"]
      backendMgr["Storage Backend Interface"]
      storagePluginMgr["Storage Plugin Launcher"]
   end

   runtimePluginMgr -->|"launch"| plugin1["Custom Plugin Script 1"]
   runtimePluginMgr -->|"launch"| plugin2["Custom Plugin Script 2"]

   backendMgr --> CPUBackend[["In-Memory CPU Backend"]]
   backendMgr --> DiskBackend[["Local Disk Backend"]]
   backendMgr --> NIXLBackend[["NIXL Peer Backend"]]
   backendMgr --> RemoteBackend[["Remote connectors"]]

   RemoteBackend --> RedisConnector[["Redis Connector (built-in)"]]
   RemoteBackend --> InfiniConnector[["InfiniStore Connector (built-in)"]]
   RemoteBackend --> MooncakeConnector[["Mooncake Connector (built-in)"]]
   RemoteBackend --> CustomConnector1[["Custom Remote Storage Connector 1"]]
   RemoteBackend --> CustomConnector2[["Custom Remote Storage Connector 2"]]

   storagePluginMgr --> |"StoragePluginInterface"| strplugin1["Custom Storage Backend 1"]
   storagePluginMgr --> |"StoragePluginInterface"| strplugin2["Custom Storage Backend 2"]
    

存储插件框架 使 LMCache 能够与新的存储或传输系统接口。开发者可以实现标准化的 StoragePluginInterface 来创建自定义存储后端模块。这些后端在运行时由 LMCache 加载(通过配置),除了与 LMCache 一起提供的内置后端。内置后端包括内存 CPU 缓存、本地磁盘存储、NVIDIA NIXL(GPU 点对点)以及 Redis、InfiniStore、Mooncake 等远程存储。

要添加自定义存储后端,您需要:

  1. **实现**一个继承自 LMCache StoragePluginInterface 的 Python 类,重写所有必需的方法。

  2. LMCache 环境中安装此后端包(以便 LMCache 可以导入它)。

  3. 配置 LMCache 以使用它,通过在 storage_plugins 列表中添加一个条目,并在配置的 extra_config 中指定模块路径和类名。例如:

    storage_plugins: ["my_custom_storage"]
    extra_config:
       storage_plugin.my_custom_storage.module_path: my_package.my_storage_module
       storage_plugin.my_custom_storage.class_name: MyCustomStorageClass
    

可以同时启用多个存储后端。它们在 LMCache 启动时初始化。请注意,后端的顺序可能很重要:如果使用多个后端,较早列出的后端在缓存查找中具有更高的优先级(即 LMCache 在检索 KV 条目时会首先检查这些后端)。

远程存储插件框架 允许 LMCache 的存储层连接到新的远程 KV 存储系统。LMCache 的 RemoteBackend 使用连接器实现与各种远程存储进行通信。内置的连接器支持 Redis、InfiniStore、MooncakeStore、S3 等。插件系统提供了通过动态加载添加自定义远程存储连接器的能力,从而扩展远程存储功能,而无需修改核心代码。

要添加自定义远程存储连接器,您需要:

  1. 实现 两个类:

    • 一个 ConnectorAdapter 子类,用于处理您的方案的 URL 解析和连接器实例化。

    • 一个 RemoteConnector 子类,实现实际的存储操作(获取、放置、存在等)。

  2. 作为可安装的 Python 模块(以便 LMCache 可以导入它)。

  3. 配置 LMCache 以使用它,通过将条目添加到 remote_storage_plugins 列表中,并在配置的 extra_config 中指定模块路径和类名。例如:

    remote_storage_plugins: ["mystore"]
    extra_config:
       remote_storage_plugin.mystore.module_path: my_package.my_connector_adapter
       remote_storage_plugin.mystore.class_name: MyStoreConnectorAdapter
    

    使用此配置,当 LMCache 看到与您的适配器方案匹配的 remote_url``(例如,``mystore://...)时,它将导入并使用您的连接器进行远程操作。

可以同时启用多个远程存储插件。通过实现自定义连接器并按上述方式进行配置,您可以集成新的远程后端(数据库、分布式 KV 存储等),而无需更改 LMCache 的核心代码。

运行时插件框架 允许在 LMCache 进程旁边运行自定义脚本。运行时插件由 LMCache 的运行时插件启动器作为单独的子进程启动。运行时插件可以根据其文件名针对特定的 LMCache 角色——调度器(控制器)、工作进程或所有节点。它们可以用 Python、Bash 或其他脚本语言编写,并且对于日志记录和指标、自定义缓存管理策略、健康检查或与外部系统的集成等任务非常有用。

运行时插件系统的关键点和使用方法:

  • 配置: 您可以通过环境变量和 LMCache 配置文件启用运行时插件。在您的 YAML 配置中设置 runtime_plugin_locations,指向包含插件脚本的目录。例如:

    runtime_plugin_locations: ["/path/to/plugins"]
    extra_config:
       # (optional plugin-specific settings)
    

    在运行时,LMCache 将扫描这些目录以查找插件文件。

  • 环境变量: LMCache 通过环境变量为插件提供上下文:- LMCACHE_RUNTIME_PLUGIN_ROLE:插件运行的进程角色(例如 SCHEDULERWORKER)。- LMCACHE_RUNTIME_PLUGIN_CONFIG:通过 LMCache 传递的任何插件配置的 JSON 字符串。- LMCACHE_RUNTIME_PLUGIN_WORKER_ID:当前工作进程的 ID(如果在工作进程上运行)。- LMCACHE_RUNTIME_PLUGIN_WORKER_COUNT:LMCache 集群中工作进程的总数。

  • 命名约定: 运行时插件文件名决定它们的执行位置:- 以 `scheduler_` 开头的文件仅在调度程序进程上运行。(示例:`scheduler_metrics.py` 仅在调度程序上运行。) - 以 `worker_` 开头的文件在工作进程上运行。如果包含数字工作 ID(例如 worker_0_health.sh),则插件仅在该特定工作进程上运行。如果不包含 ID(例如 worker_logcollector.py),则插件将在 所有 工作进程上运行。- 以 `all_` 开头的文件(或任何没有角色前缀的文件)在所有 LMCache 进程上运行(包括调度程序和每个工作进程)。(示例:`all_monitor.sh` 在每个 LMCache 节点上运行。) - 文件名中的角色名称不区分大小写。确保工作 ID(如果指定)为数字,并且是文件名的一部分(用下划线分隔,例如 worker_2_custom.py 有三个部分,专门针对工作 ID 2)。

  • 执行模型: 当 LMCache 启动时,RuntiumePluginLauncher 会定位并启动每个插件作为子进程:1. 解释器选择: 运行时插件启动器检查脚本的 shebang(例如 #!...)以决定使用哪个解释器。如果没有提供 shebang,它将回退到文件扩展名(.py 使用默认的 Python 解释器,.sh 使用 Bash 等)。2. 输出处理: 插件进程的 stdout 和 stderr 被 LMCache 捕获并带有前缀(插件名称)记录,因此插件输出会出现在 LMCache 日志中,便于调试/监控。3. 生命周期: 当 LMCache 进程启动时,运行时插件会被启动(如果它们的命名指示它们应该在该进程中运行)。当父 LMCache 进程退出时,它们会被自动终止,确保没有孤儿进程。

  • 最佳实践: 在编写运行时插件时,请考虑以下指南,以确保它们与 LMCache 平稳协作:- 保持插件在资源使用和启动时间方面轻量,以免减慢 LMCache 进程。- 使用清晰且描述性的文件名来反映其目的。- 在插件脚本中包含适当的错误处理,以避免未处理的异常导致问题。- 在脚本顶部使用 shebang 行以提高可移植性(以便调用正确的解释器)。- 在使用之前验证任何配置输入(来自 LMCACHE_RUNTIME_PLUGIN_CONFIG 或其他地方)。- 如果插件执行耗时操作,请实现超时或定期日志记录,以便您可以检测是否挂起,并确保它不会阻塞 LMCache 的正常操作。

这些扩展点——自定义存储后端、远程存储连接器和运行时插件脚本——使用户能够以模块化和可维护的方式定制 LMCache 的功能并与外部系统集成。