
后端前端【免费下载链接】flagsmithFlagsmith is an open-source feature flag platform with remote config, experimentation, and self-hosted or cloud deployment options.项目地址https://gitcode.com/gh_mirrors/fl/flagsmith点击查看免费下载本文以 Flagsmith 开源项目官方文档 caching-strategies.md 为骨架结合仓库源码系统讲解 Flagsmith API 的内存缓存体系涵盖环境标志缓存、项目分段缓存、GET /flags与GET /identities端点缓存以及环境文档Environment Document的两种缓存模式。读完本文你将掌握全部相关环境变量的含义、默认值与适用场景并能针对高并发 SDK 流量设计出一套可落地的自托管缓存方案。一、Flagsmith 缓存了什么四类核心缓存对象Flagsmith 的 Django API 通过内存in-memory缓存改善多个高频端点的响应性能。根据官方文档被缓存的主要对象分为以下四类环境标志Environment flags/flags接口返回的标志数据缓存秒数由环境变量CACHE_FLAGS_SECONDS控制。项目分段Project segments给定项目下所有分段Segment的集合缓存秒数由CACHE_PROJECT_SEGMENTS_SECONDS控制。标志与身份端点缓存Flags identities endpoint caching为GET /flags与GET /identities接口的完整响应提供缓存后端、位置、超时均由开发者自行选择。环境文档Environment document当环境文档即 SDK 拉取的完整环境数据快照被重度使用、给数据库造成较大压力时可借助缓存降低负载。这四类缓存对 SDK 初始化与持续评估路径的性能至关重要下面的小节分别深入讲解各自的配置方式与底层实现。二、环境标志与项目分段缓存2.1 环境标志缓存CACHE_FLAGS_SECONDSCACHE_FLAGS_SECONDS用于控制/flags接口返回的环境标志在内存中的缓存秒数。在 api/app/settings/common.py 中定义如下CACHE_FLAGS_SECONDS env.int(CACHE_FLAGS_SECONDS, default0) FLAGS_CACHE_LOCATION environment-flags默认值为0即默认不启用该层缓存。该缓存对应CACHES字典中的environment-flags后端api/app/settings/common.pyFLAGS_CACHE_LOCATION: { BACKEND: django.core.cache.backends.locmem.LocMemCache, LOCATION: FLAGS_CACHE_LOCATION, },从源码实现看SDKFeatureStates.get()在 api/features/views.py 中先判断settings.CACHE_FLAGS_SECONDS 0命中时才走_get_flags_from_cache(request.environment)的缓存读取路径否则直接查询数据库计算特征状态if settings.CACHE_FLAGS_SECONDS 0: data self._get_flags_from_cache(request.environment) else: data self.get_serializer( get_environment_feature_states( request.environment, hide_server_key_onlyself._hide_server_key_only, from_replicaTrue, ), manyTrue, ... )实际使用时将该变量设为大于 0 的秒数即可启用例如CACHE_FLAGS_SECONDS60表示/flags结果最多缓存 60 秒。2.2 项目分段缓存CACHE_PROJECT_SEGMENTS_SECONDSCACHE_PROJECT_SEGMENTS_SECONDS控制给定项目的分段集合在内存中的缓存秒数定义于 api/app/settings/common.pyCACHE_PROJECT_SEGMENTS_SECONDS env.int(CACHE_PROJECT_SEGMENTS_SECONDS, 0) PROJECT_SEGMENTS_CACHE_LOCATION project-segments默认同样为0不缓存。对应缓存后端在 api/projects/services.py 中被取出并使用project_segments_cache caches[settings.PROJECT_SEGMENTS_CACHE_LOCATION]写入时api/projects/services.py以timeoutsettings.CACHE_PROJECT_SEGMENTS_SECONDS作为过期时间。在分段数量较多、分段规则复杂的项目中开启该缓存可以显著减少每次评估时的分段查询开销。三、Flags 与 Identities 端点缓存3.1 三个配置变量官方文档指出要为GET /flags与GET /identities两个端点仅限 GET 请求启用缓存需要设置以下环境变量[FLAGS|IDENTITIES]表示分别对两个端点各配置一套环境变量说明示例值默认值GET_[FLAGS\|IDENTITIES]_ENDPOINT_CACHE_SECONDS缓存对应 GET 端点的响应的秒数600GET_[FLAGS\|IDENTITIES]_ENDPOINT_CACHE_BACKEND所选 Django 缓存后端的 Python 路径django.core.cache.backends.memcached.PyMemcacheCachedjango.core.cache.backends.dummy.DummyCacheGET_[FLAGS\|IDENTITIES]_ENDPOINT_CACHE_LOCATION缓存后端的位置如 Memcached 的地址127.0.0.1:11211get_flags_endpoint_cache各自对应的缓存名默认情况下GET_FLAGS_ENDPOINT_CACHE_BACKEND与GET_IDENTITIES_ENDPOINT_CACHE_BACKEND都指向DummyCache空操作缓存且秒数为0因此默认不启用任何端点级缓存保证行为与未配置时完全一致。相关定义见 api/app/settings/common.pyGET_FLAGS_ENDPOINT_CACHE_SECONDS env.int(GET_FLAGS_ENDPOINT_CACHE_SECONDS, default0) GET_FLAGS_ENDPOINT_CACHE_NAME get_flags_endpoint_cache GET_FLAGS_ENDPOINT_CACHE_BACKEND env.str( GET_FLAGS_ENDPOINT_CACHE_BACKEND, defaultdjango.core.cache.backends.dummy.DummyCache, ) GET_FLAGS_ENDPOINT_CACHE_LOCATION env.str( GET_FLAGS_ENDPOINT_CACHE_LOCATION, defaultGET_FLAGS_ENDPOINT_CACHE_NAME, )这两个缓存会在CACHES中注册为独立的命名缓存api/app/settings/common.py与默认缓存相互隔离GET_FLAGS_ENDPOINT_CACHE_NAME: { BACKEND: GET_FLAGS_ENDPOINT_CACHE_BACKEND, LOCATION: GET_FLAGS_ENDPOINT_CACHE_LOCATION, }, GET_IDENTITIES_ENDPOINT_CACHE_NAME: { BACKEND: GET_IDENTITIES_ENDPOINT_CACHE_BACKEND, LOCATION: GET_IDENTITIES_ENDPOINT_CACHE_LOCATION, },3.2 完整示例Memcached 缓存 30 秒官方文档给出的示例是在memcached-container:11211的 Memcached 实例上同时缓存 flags 与 identities 两个端点的响应 30 秒GET_FLAGS_ENDPOINT_CACHE_SECONDS: 30 GET_FLAGS_ENDPOINT_CACHE_BACKEND: django.core.cache.backends.memcached.PyMemcacheCache GET_FLAGS_ENDPOINT_CACHE_LOCATION: memcached-container:11211 GET_IDENTITIES_ENDPOINT_CACHE_SECONDS: 30 GET_IDENTITIES_ENDPOINT_CACHE_BACKEND: django.core.cache.backends.memcached.PyMemcacheCache GET_IDENTITIES_ENDPOINT_CACHE_LOCATION: memcached-container:112113.3 底层实现cache_page 装饰器与 Vary 头端点级缓存通过 Django 的cache_page装饰器实现。在 api/features/views.py 中SDKFeatureStates即GET /flags的get()方法被如下修饰method_decorator(vary_on_headers(SDK_ENVIRONMENT_KEY_HEADER)) method_decorator( cache_page( timeoutsettings.GET_FLAGS_ENDPOINT_CACHE_SECONDS, cachesettings.GET_FLAGS_ENDPOINT_CACHE_NAME, ) ) def get(self, request, identifierNone, *args, **kwargs):GET /identities的SDKIdentities.get()采用了完全相同的模式api/environments/identities/views.pymethod_decorator(vary_on_headers(SDK_ENVIRONMENT_KEY_HEADER)) method_decorator( cache_page( timeoutsettings.GET_IDENTITIES_ENDPOINT_CACHE_SECONDS, cachesettings.GET_IDENTITIES_ENDPOINT_CACHE_NAME, ) ) def get(self, request):两点值得注意vary_on_headers(SDK_ENVIRONMENT_KEY_HEADER)缓存键依据环境 SDK 密钥请求头区分保证不同环境之间的响应互不串扰——这是多租户场景下端点级缓存能够安全使用的前提。整页缓存 vs 标志缓存CACHE_FLAGS_SECONDS缓存的是标志评估结果本身而GET_FLAGS_ENDPOINT_CACHE_SECONDS缓存的是整个 HTTP 响应两者可以独立启用也可以同时启用。3.4 选用何种后端由于CACHE_BACKEND是任意 Django 缓存后端的 Python 路径理论上可以接入 Django 官方支持的所有后端api/app/settings/common.py 中另有注释提示使用 Redis 时应将后端设为django_redis.cache.RedisCache、位置设为 Redis URL且默认开启DJANGO_REDIS_IGNORE_EXCEPTIONS以避免 Redis 故障拖垮主链路。常见选择包括django.core.cache.backends.memcached.PyMemcacheCache示例所用适合跨进程共享的端点缓存django_redis.cache.RedisCache若基础设施已有 Redis且希望与限流、会话等共用一套缓存django.core.cache.backends.locmem.LocMemCache单进程部署可考虑但多进程/多副本部署时各进程缓存不一致不推荐用于端点缓存django.core.cache.backends.dummy.DummyCache默认值即不缓存。四、环境文档缓存Environment Document Caching环境文档是 SDK 在启动时拉取的环境级完整配置快照包含特征状态、多变量选项、分段等信息。构建它的查询较重见 api/environments/models.py 中_get_environment_document_from_db的大量select_related/prefetch_related因此在“重度使用环境文档”的场景下缓存收益非常明显。4.1 配置变量启用环境文档缓存需要设置以下环境变量环境变量说明示例值默认值CACHE_ENVIRONMENT_DOCUMENT_MODE缓存模式取值为PERSISTENT或EXPIRING。虽然默认值是EXPIRING但由于CACHE_ENVIRONMENT_DOCUMENT_SECONDS默认值为0默认实际上并不缓存PERSISTENTEXPIRINGCACHE_ENVIRONMENT_DOCUMENT_SECONDS环境文档的缓存秒数仅在CACHE_ENVIRONMENT_DOCUMENT_MODEEXPIRING时生效600即不缓存定义位于 api/app/settings/common.pyCACHE_ENVIRONMENT_DOCUMENT_LOCATION env( CACHE_ENVIRONMENT_DOCUMENT_LOCATION, defaultenvironment-documents ) CACHE_ENVIRONMENT_DOCUMENT_BACKEND env( CACHE_ENVIRONMENT_DOCUMENT_BACKEND, django.core.cache.backends.db.DatabaseCache ) CACHE_ENVIRONMENT_DOCUMENT_MODE env.enum( CACHE_ENVIRONMENT_DOCUMENT_MODE, enumEnvironmentDocumentCacheMode, defaultEnvironmentDocumentCacheMode.EXPIRING.value, ) CACHE_ENVIRONMENT_DOCUMENT_SECONDS env.int(CACHE_ENVIRONMENT_DOCUMENT_SECONDS, 0) CACHE_ENVIRONMENT_DOCUMENT_OPTIONS env.json( CACHE_ENVIRONMENT_DOCUMENT_OPTIONS, defaultNone )额外还有三个非必需变量CACHE_ENVIRONMENT_DOCUMENT_LOCATION缓存键前缀/位置默认environment-documentsCACHE_ENVIRONMENT_DOCUMENT_BACKEND缓存后端路径默认django.core.cache.backends.db.DatabaseCache数据库表缓存CACHE_ENVIRONMENT_DOCUMENT_OPTIONS透传给后端构造的额外选项JSON默认None。该缓存在CACHES中注册如下api/app/settings/common.pyTIMEOUT在PERSISTENT模式下为None永不过期在EXPIRING模式下为CACHE_ENVIRONMENT_DOCUMENT_SECONDSCACHE_ENVIRONMENT_DOCUMENT_LOCATION: { BACKEND: CACHE_ENVIRONMENT_DOCUMENT_BACKEND, LOCATION: CACHE_ENVIRONMENT_DOCUMENT_LOCATION, TIMEOUT: ( None if CACHE_ENVIRONMENT_DOCUMENT_MODE EnvironmentDocumentCacheMode.PERSISTENT else CACHE_ENVIRONMENT_DOCUMENT_SECONDS ), OPTIONS: CACHE_ENVIRONMENT_DOCUMENT_OPTIONS or {}, },4.2 PERSISTENT 与 EXPIRING 两种模式的区别EXPIRING默认文档在缓存中保存CACHE_ENVIRONMENT_DOCUMENT_SECONDS秒后过期过期后重新从数据库构建并回填。适合“允许短暂的数据延迟、希望简单可控”的场景。注意默认秒数为0不设置该变量就等于没有缓存。PERSISTENT文档写入缓存后不设置过期时间直到文档被显式失效。适合环境文档读取量极大、需要极致减少数据库压力的场景。若同时设置了CACHE_ENVIRONMENT_DOCUMENT_SECONDS系统会打印警告并忽略该变量api/app/settings/common.pyif ( CACHE_ENVIRONMENT_DOCUMENT_MODE EnvironmentDocumentCacheMode.PERSISTENT and CACHE_ENVIRONMENT_DOCUMENT_SECONDS ): warnings.warn( Ignoring CACHE_ENVIRONMENT_DOCUMENT_SECONDS variable since CACHE_ENVIRONMENT_DOCUMENT_MODE PERSISTENT )4.3 两个重要的使用警告务必阅读官方文档对持久缓存给出两条明确提示caution持久缓存只能与提供集中式缓存centralised cache的后端配合使用不应与例如LocMemCache这样的本地内存缓存一起使用。原因很直观LocMemCache是每进程独立的内存缓存多进程/多副本部署下各进程的缓存互不可见一旦通过模型钩子删除了某一个进程里的缓存条目其他进程仍会返回过期文档造成数据不一致。生产环境请使用 Memcached、Redis、或默认的数据库表缓存DatabaseCache这类集中式后端。info使用持久缓存时一次变更可能需要数秒才能反映到缓存中这也可以通过提升任务处理器task processor的性能来优化。也就是说PERSISTENT模式下的缓存更新是异步的变更生效存在数秒延迟这是需要接受的最终一致性代价。4.4 写入与读取的完整调用链环境文档缓存的读写逻辑集中在 api/environments/models.py写入Environment.write_environment_documents()api/environments/models.py在PERSISTENT模式下批量构建文档并写入缓存且特意“使用 SDK mapper 使缓存与数据库回退路径完全一致”map_environment_to_sdk_documentelif ( settings.CACHE_ENVIRONMENT_DOCUMENT_MODE EnvironmentDocumentCacheMode.PERSISTENT ): environment_document_cache.set_many( { e.api_key: map_environment_to_sdk_document(e) for e in environments } )读取Environment.get_environment_document(api_key)api/environments/models.py先判断缓存是否启用命中走_get_environment_document_from_cache后者api/environments/models.py在缓存未命中时回源数据库并回填缓存同时通过 Prometheus 指标flagsmith_environment_document_cache_queries_total记录CACHE_HIT/CACHE_MISS方便观测缓存命中率environment_document environment_document_cache.get(api_key) if not (cache_hit : environment_document is not None): environment_document cls._get_environment_document_from_db(api_key) environment_document_cache.set(api_key, environment_document) flagsmith_environment_document_cache_queries_total.labels( resultCACHE_HIT if cache_hit else CACHE_MISS, ).inc()失效模型钩子delete_environment_document_from_cacheapi/environments/models.py在环境被删除时按api_key删除对应缓存更新环境api_key时同样先删除旧键再重建update_environment_document_cacheapi/environments/models.py。这正是PERSISTENT模式能保持最终一致性的机制——变更后的文档会由后台任务批量写回缓存因此文档提到“变更可能需要几秒才生效”。五、常见部署组合建议根据上述四类缓存典型的自托管生产配置以 Redis 为例可以这样组织# 标志级缓存SDK 拉取 /flags 的结果缓存 60 秒 CACHE_FLAGS_SECONDS: 60 # 项目分段缓存分段集合缓存 300 秒 CACHE_PROJECT_SEGMENTS_SECONDS: 300 # 端点级缓存/flags 与 /identities 整页响应使用集中式后端 GET_FLAGS_ENDPOINT_CACHE_SECONDS: 30 GET_FLAGS_ENDPOINT_CACHE_BACKEND: django_redis.cache.RedisCache GET_FLAGS_ENDPOINT_CACHE_LOCATION: redis://redis:6379/1 GET_IDENTITIES_ENDPOINT_CACHE_SECONDS: 30 GET_IDENTITIES_ENDPOINT_CACHE_BACKEND: django_redis.cache.RedisCache GET_IDENTITIES_ENDPOINT_CACHE_LOCATION: redis://redis:6379/1 # 环境文档缓存持久模式文档变更异步更新 CACHE_ENVIRONMENT_DOCUMENT_MODE: PERSISTENT CACHE_ENVIRONMENT_DOCUMENT_BACKEND: django_redis.cache.RedisCache CACHE_ENVIRONMENT_DOCUMENT_LOCATION: environment-documents需要注意环境文档的持久缓存只应配合集中式缓存后端如 Redis、Memcached、数据库表缓存切勿使用LocMemCache。六、验证与观测仓库测试覆盖了这些缓存的读写行为可作为配置正确性的参考api/tests/unit/features/test_unit_features_views.py覆盖CACHE_FLAGS_SECONDS、GET_FLAGS_ENDPOINT_CACHE_*相关的标志响应缓存行为api/tests/unit/environments/test_unit_environments_models.py覆盖环境文档缓存的读写与失效api/tests/unit/projects/test_unit_projects_models.py覆盖项目分段缓存。运行层面可重点关注以下观测手段环境文档缓存命中率由flagsmith_environment_document_cache_queries_total指标按CACHE_HIT/CACHE_MISS标签统计api/environments/models.py可通过 Prometheus 监控该指标评估缓存收益端点级缓存生效与否可通过响应时间与数据库查询日志对比验证PERSISTENT模式下的异步更新延迟则可通过“修改标志后数秒再拉取文档”的时序来确认任务处理器是否及时刷新。结语Flagsmith 的缓存体系覆盖了从标志评估结果、分段集合、端点整页响应到环境文档的四条路径其中前两者由秒数变量简单开启端点级缓存通过 Djangocache_page实现并支持自由选择后端环境文档缓存则提供了EXPIRING与PERSISTENT两种模式以满足不同的延迟与一致性诉求。配置时的三条底线是端点缓存键会按环境 SDK 密钥头隔离、环境文档持久缓存必须使用集中式后端、PERSISTENT模式下的更新存在数秒延迟。合理组合这四类缓存即可在自托管部署中显著降低 SDK 高频请求对数据库的压力。赞分享后端前端【免费下载链接】flagsmithFlagsmith is an open-source feature flag platform with remote config, experimentation, and self-hosted or cloud deployment options.项目地址https://gitcode.com/gh_mirrors/fl/flagsmith点击查看免费下载相关推荐Vector缓存策略完全指南高效内存缓存与磁盘缓存配置Vector缓存策略完全指南高效内存缓存与磁盘缓存配置 Vector作为一个高性能的开源observability数据管道工具提供了强大的缓存机制来确保数据可观测性数据工程数据集成日志分析UnifoLM-WMA-0代码架构详解从模型训练到推理的完整实现UnifoLM WMA 0代码架构详解从模型训练到推理的完整实现 UnifoLM WMA 0是宇树科技开源的世界模型 动作框架专为通用机器人学习设计。这个创人工智能具身智能机器人计算机视觉媒体生成预训练终极指南如何用RxJS shareReplay解决前端数据缓存痛点与高级失效策略终极指南如何用RxJS shareReplay解决前端数据缓存痛点与高级失效策略 在现代前端开发中数据缓存是提升用户体验和应用性能的关键技术。而RxJS作为后端上一篇Beremiz开源PLC深度解析IEC-61131标准下的工业自动化架构设计与实战指南下一篇Inconsolata 字体程序员必备的终极等宽字体解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考