gpt4 book ai didi

google-app-engine - 使用 MapReduce 时,ndb 模型不会保存在内存缓存中

转载 作者:行者123 更新时间:2023-12-02 06:33:36 25 4
gpt4 key购买 nike

我创建了两个 MapReduce 管道,用于上传 CSV 文件以批量创建类别和产品。每个产品都通过 KeyProperty 绑定(bind)到一个类别。 Category 和 Product 模型建立在 ndb.Model 之上,因此根据文档,我认为当从 Datastore 中检索它们时,它们会自动缓存在 Memcache 中。

我在服务器上运行这些脚本以上传 30 个类别,然后上传 3000 个产品。所有数据都按预期显示在数据存储区中。

但是,产品上传似乎并没有使用 Memcache 来获取类别。当我检查门户中的 Memcache 查看器时,它显示命中数大约为 180,未命中数大约为 60。如果我每次上传 3000 个产品并检索类别,我不应该有大约 3000 个吗从获取类别(即 Category.get_by_id(category_id))中命中+未命中?在创建新产品之前尝试检索现有产品可能会导致 3000 次失误(算法处理实体创建和更新)。

这是相关的产品映射函数,它从 CSV 文件中获取一行以创建或更新产品:

def product_bulk_import_map(data):
"""Product Bulk Import map function."""

result = {"status" : "CREATED"}
product_data = data

try:
# parse input parameter tuple
byteoffset, line_data = data

# parse base product data
product_data = [x for x in csv.reader([line_data])][0]
(p_id, c_id, p_type, p_description) = product_data

# process category
category = Category.get_by_id(c_id)
if category is None:
raise Exception(product_import_error_messages["category"] % c_id)

# store in datastore
product = Product.get_by_id(p_id)
if product is not None:
result["status"] = "UPDATED"
product.category = category.key
product.product_type = p_type
product.description = p_description
else:
product = Product(
id = p_id,
category = category.key,
product_type = p_type,
description = p_description
)
product.put()
result["entity"] = product.to_dict()
except Exception as e:
# catch any exceptions, and note failure in output
result["status"] = "FAILED"
result["entity"] = str(e)

# return results
yield (str(product_data), result)

最佳答案

MapReduce 有意禁用 NDB 的内存缓存。

参见 mapreduce/util.py ln 373,_set_ndb_cache_policy()(截至 2015-05-01):

def _set_ndb_cache_policy():
"""Tell NDB to never cache anything in memcache or in-process.

This ensures that entities fetched from Datastore input_readers via NDB
will not bloat up the request memory size and Datastore Puts will avoid
doing calls to memcache. Without this you get soft memory limit exits,
which hurts overall throughput.
"""
ndb_ctx = ndb.get_context()
ndb_ctx.set_cache_policy(lambda key: False)
ndb_ctx.set_memcache_policy(lambda key: False)

你可以强制get_by_id()put()使用memcache,例如:

product = Product.get_by_id(p_id, use_memcache=True)
...
product.put(use_memcache=True)

或者,如果您正在使用 mapreduce.operation 进行批处理,则可以修改 NDB 上下文。但是我不知道这是否会产生其他不良影响:

ndb_ctx = ndb.get_context()
ndb_ctx.set_memcache_policy(lambda key: True)
...
yield operation.db.Put(product)

至于关于“软内存限制退出”的文档字符串,我不明白如果启用仅内存缓存(即没有上下文缓存)为什么会发生这种情况。

实际上,您似乎希望为 put 启用内存缓存,否则在您的映射器修改了下面的数据后,您的应用程序最终会从 NDB 的内存缓存中读取陈旧数据。

关于google-app-engine - 使用 MapReduce 时,ndb 模型不会保存在内存缓存中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26223098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com