关于 litestar-stores
面向需要管理临时或共享应用状态的 Litestar 开发者,介绍可互换键值存储的选择与使用,涵盖后端、TTL、命名空间、注册表和生命周期。
主要功能
- 01选择内存、文件、Redis 或 Valkey 后端
- 02配置过期时间与读取续期
- 03通过命名空间隔离键
- 04使用 StoreRegistry 查找存储
- 05规划清理与客户端生命周期
适用场景
- 01为会话或限流选择存储
- 02在应用工作进程间共享状态
- 03设置缓存值的过期策略
- 04隔离共享后端中的集成数据
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ alti3/ litestar-skills --skill litestar-stores安装后在 Claude Code 中输入/litestar-stores确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/backend-selection-and-lifecycle.mdregistry-and-namespacing.mdstore-operations-and-data.md详细介绍
存储
当问题涉及 Litestar 可互换的键值存储层,而非关系型数据建模时,请使用此技能。
执行工作流
- 判断该功能是否确实适合放在 Litestar 存储中:缓存、会话、速率限制,或其他临时/共享的键值状态。
- 根据进程模型、持久性、延迟和清理需求选择后端。
- 决定是按名称显式接入存储、通过
StoreRegistry延迟创建存储,还是从带命名空间的默认工厂派生存储。 - 定义键命名规则、命名空间边界、TTL 策略,以及读取时是否续期。
- 有意地将响应缓存、会话或速率限制等集成接入指定名称的存储。
- 规划清理和关闭行为,尤其是
FileStore的过期清理和 Redis 客户端的所有权。 - 在生产环境中依赖存储前,验证过期行为、隔离性和多工作进程行为。
核心规则
- 将存储视为可互换的键值基础设施,而非临时对象持久化方案。
- 按存储契约设计:值以字节为基础,即使后端提供了额外的便利功能也是如此。
- 使用
delete_all()等批量操作前,明确规划命名空间和存储名称。 - 根据功能匹配 TTL 策略:绝对过期、访问时续期,或不过期。
- 不要假设所有后端都会以相同方式清理过期数据。
- 相比于让无关功能共用一个扁平键空间,优先使用具名存储或带命名空间的存储。
- 任何需要在工作进程或实例之间保留的状态,都应使用分布式后端。
- 当外部客户端或文件系统路径需要生命周期管理时,明确存储的所有权。
选择指南
- 对于简单的单进程缓存或开销要求极低、风险不高的临时状态,使用
MemoryStore。 - 当磁盘持久化比速度更重要时,使用
FileStore,尤其适用于较大或生命周期较长的数据。 - 对于通用的生产级共享状态、多工作进程通信和带命名空间的批量操作,使用
RedisStore。 - 当希望在 Valkey 上使用 Redis 风格的行为时,使用
ValkeyStore;Litestar 文档指出,在这些存储场景中,它在实际使用上等同于 Redis。 - 当集成必须解析已知的存储名称时,使用显式的
stores={...}映射。 - 当未定义的存储名称应根据统一策略延迟创建时,使用
StoreRegistry(default_factory=...)。 - 当一个底层后端需要安全地承载多个相互隔离的逻辑存储时,使用
with_namespace()。 - 当主要设计问题涉及响应缓存 TTL、缓存键或缓存过滤时,请将
litestar-caching与此技能配合使用。
参考文件
只阅读所需的部分:
- 有关存储操作、字节与字符串的行为、TTL 续期和清理机制,请阅读 references/store-operations-and-data.md。
- 有关后端选择的权衡和特定后端的运维说明,请阅读 references/backend-selection-and-lifecycle.md。
- 有关
StoreRegistry、命名空间、集成接入和默认工厂模式,请阅读 references/registry-and-namespacing.md。
存储基础知识
Litestar 存储操作围绕一组精简的异步 API 展开:
set(key, value, expires_in=...)get(key, renew_for=...)delete(key)delete_all()exists(key)expires_in(key)
文档中的关键行为规则:
- 存储通常接受字节并返回字节。
- 为方便起见,
set()也接受字符串,但get()仍会返回字节。 - 写入数据时可以设置
expires_in。 - 当后端支持为该键设置过期时间时,可以向
get()传入renew_for,以便在访问时延长 TTL。 - 如果对不存在的键调用
delete(),则不会执行任何操作。
后端选择
MemoryStore
- Litestar 的默认存储。
- 开销最低。
- 不持久化。
- 不支持线程安全或多进程安全。
- 避免将其用于多工作进程或多实例共享状态。
FileStore
- 将数据持久化到磁盘。
- 比基于内存的方案慢。
- 适用于重视数据量、持久性或可备份性的场景。
- 支持通过子路径进行命名空间隔离。
- 不会主动移除过期条目;请安排调用
delete_expired()。
RedisStore
- 适用于几乎所有需要共享或具备一定持久性的键值基础设施的应用。
- 支持命名空间隔离和安全的命名空间范围内
delete_all()。 - 原生过期行为由 Redis 自身提供。
- 适用于多工作进程部署、会话、速率限制和共享缓存状态。
ValkeyStore
- 根据 Litestar 文档,实用建议与
RedisStore相同。 - 支持命名空间隔离。
- 当部署标准为 Valkey 而非 Redis 时使用。
TTL 和过期语义
- 在
set()中使用expires_in设置绝对过期时间。 - 在
get()中使用renew_for实现滑动过期或基于访问的续期,例如会话或类似 LRU 的行为。 - Redis/Valkey 使用原生过期机制。
FileStore仅在访问过期值或显式运行delete_expired()时才会删除这些值。MemoryStore和FileStore可能会保留过期数据,直到发生访问或清理;不要将这些后端上的 TTL 视为等同于立即在后台删除。
命名空间
- 命名空间用于确保共享后端适用于多个逻辑用途。
with_namespace()会创建一个子存储,其操作仅影响该命名空间及其子命名空间。- 在使用
delete_all()之前,这一点尤为重要。 RedisStore默认使用LITESTAR作为命名空间。- 传入
namespace=None会禁用 Redis 命名空间,并使delete_all()不可用。 - 基于文件的命名空间会使用父存储路径下的子路径。
存储注册表
Litestar.stores会公开应用的StoreRegistry。- 注册表可以从存储名称到存储实例的映射开始构建。
app.stores.get(name)会返回已注册的存储,或者通过注册表的default_factory创建一个存储。- 默认注册表工厂会为未知名称返回一个新的
MemoryStore。 - 你可以传入自定义
StoreRegistry,以全局更改此行为。 - 当动态创建不足以满足需求时,可通过
StoreRegistry.register(name, store, allow_override=False)显式注册。
集成配置
Litestar 集成通过注册表按名称解析存储。需要注意以下几点:
- 除非另行配置,响应缓存默认使用名为
response_cache的存储。 - 除非另行配置,会话中间件默认使用名为
sessions的存储。 - 速率限制也会按名称解析其存储。
- 这些名称是约定,并非特殊常量;你可以通过各自的配置将集成指向其他名称。
- 一个注册表可以为不同集成托管多个后端,也可以通过默认工厂让一个带命名空间的后端服务于多个集成。
数据契约和序列化边界
- 可移植的存储契约基于字节。
- 如果存储之后可能被替换,请勿依赖特定后端的对象行为。
- 由于
MemoryStore直接在内存中存储数据,因此技术上可以容纳任意 Python 对象,但 Litestar 文档中的接口并不保证这种可移植性。 - 当后端互换性很重要时,请先显式序列化结构化值,再进行存储。
清理和生命周期
- 对于
MemoryStore,尤其是条目可能不断累积的FileStore,请定期调用delete_expired()。 - 如果目录会长期保留,
FileStore.delete_expired()适合作为启动或维护任务。 - 如果直接围绕自己的 Redis 客户端创建
RedisStore,且不使用辅助生命周期管理,则需要自行关闭该客户端。 - 如果希望由 Litestar/存储管理客户端生命周期,优先使用
RedisStore.with_client(...)或显式的所有权标志。
推荐默认设置
- 仅在本地开发、单进程应用或低风险临时状态场景中使用
MemoryStore。 - 在生产环境中,共享缓存、会话和速率限制优先使用 Redis 或 Valkey。
- 如果不同后端负责不同用途,请为集成使用明确的存储名称。
- 如果希望共享基础设施,同时隔离各逻辑子项,请使用一个带根命名空间的 Redis/Valkey 存储。
- 有意将结构化数据序列化为字节或字符串,不要依赖
MemoryStore的对象存储能力。 - 将文件存储的过期清理作为一项明确的维护任务执行。
示例模式
from litestar import Litestar, get
from litestar.config.response_cache import ResponseCacheConfig
from litestar.middleware.rate_limit import RateLimitConfig
from litestar.middleware.session.server_side import ServerSideSessionConfig
from litestar.stores.redis import RedisStore
from litestar.stores.registry import StoreRegistry
root_store = RedisStore.with_client()
@get("/cached", cache=True, sync_to_thread=False)
def cached_handler() -> str:
return "hello"
app = Litestar(
[cached_handler],
stores=StoreRegistry(default_factory=root_store.with_namespace),
response_cache_config=ResponseCacheConfig(store="response_cache"),
middleware=[
ServerSideSessionConfig(store="sessions").middleware,
RateLimitConfig(rate_limit=("second", 10), store="rate_limit").middleware,
],
)
反模式
- 使用
MemoryStore存储必须在多个工作进程或进程之间共享的状态。 - 将存储视为关系型或可查询持久化方案的替代品。
- 仅仅因为
MemoryStore允许存储任意 Python 对象,就存储任意 Python 对象。 - 使用一个扁平键空间,然后在没有命名空间或隔离存储名称的情况下调用
delete_all()。 - 认为
FileStore或MemoryStore中的过期条目会立即消失。 - 忘记清理基于文件系统的过期条目。
- 向 Redis 传入
namespace=None,却期望命名空间范围内的批量删除安全可靠。 - 认为集成存储名称是固定且不可更改的,而不是由配置决定的。
- 将 Memcached 当作受支持的即插即用后端。
验证清单
- 确认所选后端符合进程拓扑和持久性要求。
- 如果需要可移植性,确认值采用了跨后端兼容的序列化方式。
- 确认 TTL 行为符合实际后端语义,包括所用的读取时续期行为。
- 如有需要,确认基于文件或内存的存储具有明确的过期条目清理策略。
- 确认命名空间或存储名称可以避免跨功能冲突和不安全的批量删除。
- 确认
app.stores.get(name)会为每个集成解析出预期的存储。 - 确认缓存、会话和速率限制指向预期的存储名称。
- 确认 Redis/Valkey 客户端的关闭责任归属明确。
- 确认多工作进程部署不依赖
MemoryStore。
跨技能交接
- 使用
litestar-caching处理响应缓存 TTL、键构建器和缓存筛选策略。 - 当会话/身份验证数据是主要关注点时,使用
litestar-authentication或litestar-security。 - 当速率限制或会话中间件行为是主要任务时,使用
litestar-middleware。 - 使用
litestar-app-setup为存储维护添加启动/关闭清理钩子。 - 使用
litestar-testing验证过期行为、集成接线和多后端行为。
Litestar 参考资料
- https://docs.litestar.dev/latest/usage/stores.html
- https://docs.litestar.dev/latest/usage/caching.html
- https://docs.litestar.dev/latest/reference/stores/base.html
- https://docs.litestar.dev/latest/reference/stores/memory.html
- https://docs.litestar.dev/latest/reference/stores/registry.html
- https://docs.litestar.dev/latest/reference/stores/file.html
- https://docs.litestar.dev/latest/reference/stores/redis.html
- https://docs.litestar.dev/latest/reference/stores/valkey.html
评论
支持 Markdown