存储插件#
LMCache 支持开箱即用的存储后端,如 Mooncake、S3 和 NIXL。LMCache 存储插件系统提供通过动态加载或即插即用能力添加自定义存储后端的功能。换句话说,可以在不修改核心代码的情况下扩展缓存存储能力。
后端定义要求#
继承自
StoragePluginInterface实现
StoragePluginInterface的父接口StorageBackendInterface的所有抽象方法。打包为可安装的 Python 模块
备注
接口构造函数是 LMCache 加载系统在加载自定义存储后端时使用的实例化契约。如果您希望实现一个构造函数,它应该具有相同的参数签名并调用接口构造函数。
如何将后端与 LMCache 集成#
在 LMCache 环境中安装您的后端包
将
storage_plugins及其相关的module_path和class_name添加到 LMCache 配置的extra_config部分,如下所示:
chunk_size: 64
local_cpu: False
max_local_cpu_size: 5
storage_plugins: <backend_name>
extra_config:
storage_plugin.<backend_name>.module_path: <module_path>
storage_plugin.<backend_name>.class_name: <class_name>
日志后端的示例配置如下:
chunk_size: 64
local_cpu: False
max_local_cpu_size: 5
storage_plugins: "log_backend"
extra_config:
storage_plugin.log_backend.module_path: lmc_external_log_backend.lmc_external_log_backend
storage_plugin.log_backend.class_name: ExternalLogBackend
备注
存储后端在 LMCache 启动时按顺序初始化 - 较早的后端在缓存查找中具有更高的优先级
storage_plugin.<backend_name>区分不同的动态加载后端
后端实现示例#
可以在 https://github.com/opendataio/lmc_external_log_backend/ 查看一个示例自定义后端实现。
MP-模式 L2 适配器插件 (plugin)#
上述描述的存储插件系统适用于 **非 MP 模式**(单进程)。对于 **MP 模式**(多进程),LMCache 提供了 plugin L2 适配器类型,该类型在运行时动态加载第三方 L2AdapterInterface 实现。
概述#
plugin 适配器类型允许您将完整的 L2 适配器作为 单独的、可通过 pip 安装的包 进行发布。在启动时,LMCache 导入您的模块,实例化您的适配器类,并像使用内置适配器一样使用它 -- 无需对 LMCache 源代码进行修改。
备注
如果您的存储后端是一个原生的 C++ 连接器(使用 pybind 封装),请考虑使用 native_plugin 类型(请参见 添加本地连接器)。它重用了内置的桥接逻辑,因此您只需实现 6 个连接器方法,而不是完整的 L2AdapterInterface。
配置#
{
"type": "plugin",
"module_path": "my_plugin.adapter",
"class_name": "MyL2Adapter",
"adapter_params": {
"host": "localhost",
"capacity": 1000
}
}
字段 |
类型 |
必需的 |
描述 |
|---|---|---|---|
|
|
是 |
适配器类所在模块的点分 Python 导入路径。 |
|
|
是 |
|
|
|
不 |
转发到适配器类构造函数(作为类型化配置或原始字典)。 |
|
|
不 |
显式配置类名称;当省略时,工厂会自动发现它。 |
配置类自动发现#
工厂会自动使用以下优先级链解析适配器的配置类(第一个匹配的优先):
显式
config_class_name字段在 JSON 配置中。约定:适配器类名 +
"Config"后缀(例如MyL2Adapter查找MyL2AdapterConfig)。属性:
config_class_name属性在适配器类本身上。后备: 未找到配置类 -- 传递原始
adapter_params字典。
每个候选项都会在加载的模块中查找,并验证为 L2AdapterConfigBase 子类。这意味着大多数遵循命名约定的插件将 自动 接收一个类型化的配置实例,而无需任何额外的配置。
插件合同#
插件适配器类 必须:
从
lmcache.v1.distributed.l2_adapters.base子类化L2AdapterInterface。实现所有抽象方法:
submit_store_task、pop_completed_store_tasks、submit_lookup_and_lock_task、query_lookup_and_lock_result、submit_unlock、submit_load_task、query_load_result、close,以及所有三个事件文件描述符获取器。提供 **三个不同的事件 fd**(存储 / 查找 / 加载)。控制器构建
fd -> 适配器映射;重复会导致事件错误路由。确保 线程安全:
StoreController和PrefetchController从不同线程并发调用适配器方法。在``__init__``中接受``**kwargs``以保持向前兼容。
插件适配器类 应该:
如果需要异步 I/O,则应创建自己的 asyncio 事件循环和后台线程。
使用
lmcache.v1.platform中的create_event_notifier()来处理三个事件文件描述符(跨平台:在 Linux 上使用os.eventfd,在其他地方使用os.pipe作为后备)。在
close()中清理所有资源(事件文件描述符、线程、连接)。
加载流程#
CLI / config JSON
|
v
PluginL2AdapterConfig.from_dict(d)
| validates module_path, class_name, adapter_params
|
v
_create_plugin_adapter(config, ...)
|
+-- importlib.import_module(config.module_path)
+-- getattr(module, config.class_name)
+-- issubclass check against L2AdapterInterface
|
+-- _resolve_config_class(module, config, adapter_cls)
| +-- 1. config.config_class_name (explicit)
| +-- 2. class_name + "Config" (convention)
| +-- 3. adapter_cls.config_class_name (attribute)
| +-- 4. None (fall back to raw dict)
|
+-- [if config class found]
| +-- adapter_cls(cfg_cls.from_dict(adapter_params))
|
+-- [otherwise]
+-- adapter_cls(adapter_params)
|
v
L2AdapterInterface instance (ready for use)
最小示例#
# my_plugin/adapter.py
import asyncio
import threading
from lmcache.native_storage_ops import Bitmap
from lmcache.v1.distributed.l2_adapters.base import (
L2AdapterInterface,
L2TaskId,
)
from lmcache.v1.platform import create_event_notifier
class MyL2Adapter(L2AdapterInterface):
def __init__(self, params, **_kw):
self._store_efd = create_event_notifier()
self._lookup_efd = create_event_notifier()
self._load_efd = create_event_notifier()
# ... set up connection, background thread, etc.
# implement all abstract methods ...
def close(self) -> None:
self._store_efd.close()
self._lookup_efd.close()
self._load_efd.close()
通过 CLI 启动:
--l2-adapter '{
"type": "plugin",
"module_path": "my_plugin.adapter",
"class_name": "MyL2Adapter",
"adapter_params": {"host": "localhost"}
}'
参考实现#
请参阅 examples/lmc_external_l2_adapter/ 以获取完整的、可通过 pip 安装的示例插件 (InMemoryL2Adapter),该插件演示了:
可配置容量的 FIFO 逐出。
用于现实测试的模拟带宽延迟。
后台 asyncio 事件循环及其正确关闭。
全面的测试套件,涵盖存储、查找、加载、批量操作和逐出行为。
附加资源#
插件适配器源代码:
lmcache/v1/distributed/l2_adapters/plugin_l2_adapter.py原生插件适配器:
lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py设计文档:
lmcache/v1/distributed/l2_adapters/design_docs/plugin.mdL2 适配器基础接口:
lmcache/v1/distributed/l2_adapters/base.py