【发布时间】:2024-01-07 10:12:01
【问题描述】:
事实证明,检索存储在 memcache 中的低级数据存储实体非常缓慢。由于 objectify 将实体缓存为低级数据存储 Entity 类型,因此在使用 objectify 从 memcache 中获取许多实体时会导致性能不佳。
真正的问题是为什么从 memcache 中反序列化 Entity 类型很慢?我整理了一个示例项目来演示从 memcache 与纯字符串或简单 Map 中检索实体的差异。
代码如下:
https://github.com/aleemstreak/perftest或相关文件:https://github.com/aleemstreak/perftest/blob/master/src/com/rewardly/perftest/PerftestServlet.java
另外,我部署了它,以便您可以看到它在生产中的差异有多大:aleemsandbox.appspot.com/perftest。它是一个幼稚的分析器,但它确实表现出巨大的性能差异。刷新页面几次以查看差异。这是一些示例输出:
Storing String Data Test
-------------------------
generateData: 0ms
storeData: 10ms
fetchData: 9ms
Storing Map Data Test
-------------------------
generateData: 0ms
storeData: 21ms
fetchData: 92ms
Storing Entity Data Test
-------------------------
generateData: 69ms
storeData: 24ms
fetchData: 792ms
第一部分显示了在内存缓存中存储 1000 个字符串然后立即取回所需的时间。下一个示例对 1000 个 Map 对象执行相同的操作,最后一个示例存储和检索 1000 个低级实体类型。您可以看到检索实体类型的时间大幅增加。
知道为什么实体从 memcache 反序列化的速度会很慢吗?
更新 1
根据其中一个答案中的建议,我还记录了存储在 memcache 中的对象的累积大小,结果没有打印出来。我还添加了另一个测试用例——我没有直接存储实体,而是先自己将实体序列化为 byte[],然后将其存储在 memcache 中。结果如下:
StringBenchmark
----------------
Average Fetch Time: 40.16ms
Fetch Size: 24.41KB
MapBenchmark
----------------
Average Fetch Time: 27.36ms
Fetch Size: 102.54KB
EntityBenchmark
----------------
Average Fetch Time: 1029.88ms
Fetch Size: 463.87KB
EntityPreSerializedBenchmark
----------------
Average Fetch Time: 218.82ms
Fetch Size: 490.23KB
这里有趣的是最后两个结果。尽管它们的大小大致相同,但手动获取和反序列化 byte[] 大约需要 1/5 的时间。
github repo 中的代码已经更新,部署的示例应用程序也有最新的代码,所以请随时在那里运行此测试并查看结果。
【问题讨论】:
-
我忘记提及的一件事是,这段代码也使用 appstats 进行了分析,所有从 memcache 中获取的数据都显示为
-
您是否还可以为 EntityPreSerializedBenchmark 发布序列化需要多长时间以及获取时间?
-
抱歉,获取时间是指 appstats 列出的实际内存缓存的获取时间吗?
-
看appstats,每次RPC到memcache不到10ms
标签: java google-app-engine entity deserialization objectify