Python Azure Function全局变量缓存正确实现方法咨询
基础环境信息
- Python版本: 3.7
- 云平台: Azure
- 使用资源: Azure Function
- 实现目标: 通过全局变量缓存提升函数运行速度
问题背景
使用Python开发Azure Function时,参考官方给出的全局变量缓存示例实现缓存能力,示例代码如下:
CACHED_DATA = None def main(req): global CACHED_DATA if CACHED_DATA is None: CACHED_DATA = load_json() # ... 代码中使用CACHED_DATA
针对该示例逻辑和自行编写的多变量缓存代码,共有3个疑问。
问题解答
1. 缓存用的全局变量必须固定命名为CACHED_DATA吗?
完全不需要。CACHED_DATA只是官方示例里用的占位变量名,没有任何强制命名要求,你可以根据缓存的实际内容自定义名称,只要变量是定义在入口函数外层的全局作用域即可,平台不会对缓存变量名做校验。
2. 全局变量初始赋值为None,会不会每次函数调用都重置导致缓存失效?
绝对不会。Azure Function Python运行时的执行逻辑是:单个函数实例启动后会拉起一个常驻Python进程,所有写在函数外层、不属于任何函数/类内部的代码,只会在进程第一次加载代码时执行一次。
你在外层把缓存变量赋值为None的操作,仅会在实例冷启动、进程重启的时候执行,后续同实例接收的所有函数调用,都会直接复用内存中已经赋值的全局变量,不会重复执行外层赋值逻辑把缓存重置为None。只有当实例闲置过久被回收、代码更新触发实例重建时,全局变量才会重新初始化,此时缓存失效属于正常现象。
3. 多全局变量缓存的代码实现是否正确?
核心缓存思路是对的,但你贴的代码存在致命缩进错误,不修正的话根本跑不起来:你写的两个if缓存加载块没有缩进在main函数内部,和上方的global变量声明不在同一个作用域,不仅缓存逻辑不生效,还会触发变量作用域报错。
修正缩进后的可用实现如下:
# 提前导入所有依赖、定义全局常量(比如ROOT_DIR) import os from os import path as os_path import joblib import azure.functions as func # 其他依赖:比如pandas的read_csv、自定义的cfp模块等 # 全局缓存变量初始化,仅在进程加载时执行一次 stop_words = None vocabulary = None vectorizer_parameters = None def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse: # 声明要修改的全局变量 global stop_words global vocabulary global vectorizer_parameters # 懒加载停用词缓存 if stop_words is None: stop_words_file_path = os_path.join(ROOT_DIR,'azure_function_app_sortierer','parameters','CustomStopWords.csv') df_stop_words = read_csv(stop_words_file_path) stop_words = df_stop_words['Stopwords'].tolist() # 懒加载词典和向量化参数缓存 if vocabulary is None or vectorizer_parameters is None: vocabulary = {} vectorizer_parameters = {} for v in ['clean_noCompound-tfidf_stopWords_unigrams', 'clean_noCompound-tfidf_stopWords_bigrams']: vocabulary_file_path = os_path.join(ROOT_DIR, 'azure_function_app_sortierer', 'model' , '00_' + v + '_Vocabulary.pkl') vocabulary[v] = joblib.load(vocabulary_file_path) vectorizer_parameters[v] = cfp.set_vectorizer_parameters(vectorizer_name=v,stopWords=stop_words,vocabulary=vocabulary[v]) # 后续直接使用三个缓存好的变量写业务逻辑即可
补充两个实践注意点:
- 你现在用的懒加载逻辑是合理的,不要图省事把读文件、加载模型的逻辑直接写在全局变量初始化的位置,那样会大幅拉长函数冷启动时间,甚至触发启动超时。
- 这种全局变量缓存是单实例级别的,如果函数并发过高触发横向扩容,每个新启动的实例都会独立加载一份自己的缓存,不会跨实例共享。如果需要跨实例共享的全局缓存,需要对接Redis这类外部缓存服务;如果只是为了减少同实例下重复读文件、加载模型的开销,当前写法完全够用。
内容的提问来源于stack exchange,提问作者sergioMoreno
相关产品推荐
相关产品推荐

