【问题标题】:Caching large objects for HA with C# asp.net / Net 4.7使用 C# asp.net / Net 4.7 为 HA 缓存大型对象
【发布时间】:2018-09-12 13:30:38
【问题描述】:

我正在尝试缓存一个需要供用户使用 15 分钟的大对象(大约 25MB)。

一开始,我使用的是 MemoryCache(单服务器),但现在我们要走 HA 路线,我们需要它对所有服务器都可用。

我们尝试用 Redis 替换它,但在序列化和反序列化对象以及往返(newtonsoft.json 序列化)之间大约需要 2 分钟(在 localhost 上)。

所以,问题是:如何在 HA 中的服务器之间共享生命周期较短的大型对象?

感谢阅读:)

【问题讨论】:

    标签: c# asp.net redis high-availability


    【解决方案1】:

    使用Protobuf-net package 从 JSON 切换到 Protobuf ser/de 时我很幸运。但是,听起来即使将其减少到经常重复的 6 倍更快的执行时间,在这种情况下,20 秒的反序列化时间可能仍然不会减少它 - 因为整个目标是为特定用户缓存它一段“短”的时间。

    这听起来像是急切与延迟加载的经典案例。由于您已经在使用 Redis,您是否考虑过将对象的每个属性单独缓存为单独的键?属性越多,因此每个属性越小,这种策略就越有利。当然,我假设对象上有一组相当正交的属性——如果它们中的许多都相互依赖,那么这可能会表现得更糟。但是,如果访问模式往往不需要整个水合对象,则可以通过获取所需的单个属性而不是整个对象来大大提高响应能力。

    我对您的对象做了很多假设 - 但最简单的步骤是实现每个属性的 get 访问器以执行 Redis Get 调用。这在依赖管理和多线程访问方面还有很多其他缺点,但可能是实现概念验证的一种简单方法。

    请记住,这会使缓存失效要求变得非常复杂。即使您可以将每个属性单独存储在 Redis 中,但如果您在获取后将该值存储在每台机器上的变量中,您很快就会遇到非托管缓存情况,您无法保证同步数据,具体取决于哪台机器为下一个请求提供服务。

    【讨论】:

    • 嗨!感谢您的回答。我会试试 protobuf-net。每个毫秒都很重要 :) 关于单独缓存每个属性的想法,这是我的第一个想法,但是尝试将它在一个属性中的 10k 项分别缓存为列表(这是 25MB 的大部分),需要双倍的时间做整个对象。
    • 谢谢@Pablius - 我现在更了解你的对象了。您是否可以将这 10k 项左右的项目存储在 Redis 列表中,然后使用索引器访问它们,这样您就不需要一次检索整个列表?如果这是一个以用户为中心的操作,我想这些会被分页。 Redis 列表支持许多有用的操作...例如在 LPUSH 中的一个连接中添加多个值,在 LLEN 中以 O(1) 操作获取长度,以及使用 LRANGE 检索多个值。
    猜你喜欢
    • 2012-04-08
    • 2014-03-25
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2018-05-25
    • 1970-01-01
    • 2014-12-23
    相关资源
    最近更新 更多