是否可以将对象保留在内存中,以获得比 Redis 或 Memcached 更快的缓存存储

本文关键字:Memcached Redis 存储 缓存 对象 保留 内存 是否 | 更新日期: 2023-09-27 18:31:56

内存中缓存存储在存储复杂对象(如 C# POCO 对象)时需要序列化/反序列化。

难道不能只将数据作为对象图保存在内存中,并消除这个瓶颈吗?毕竟,缓存和序列化的数据仍在内存中,所以为什么不将原始对象保留在内存中以获得最快的缓存(也许使用命名管道来实现分布式缓存?

谢谢

是否可以将对象保留在内存中,以获得比 Redis 或 Memcached 更快的缓存存储

您提到的缓存旨在用作具有大量功能和选项的分布式缓存。将对象或特别是对象树保存在(全局)变量中以便在单个进程中使用总是比从另一台计算机加载它并对其进行反序列化等工作更快。

但这不是Redis&Co的用例。一旦你尝试使用命名管道(或任何其他技术)实现自己的分布式缓存,你就会发现 Redis 有权存在。

换句话说:一旦在计算机边界上移动对象,就必须序列化和反序列化它们。您可能只是不知道底层传输协议是否为您执行此操作。

保持对象原样 内存中有一些优点和缺点。一起来看看吧

优点:

  • 不会有序列化和反序列化成本。
  • 执行分析(节省序列化成本)将更容易。
    • 在分布式缓存中执行MapReduce函数时,对象不会存储为二进制文件,以降低分析成本。

缺点

  • 序列化实际上通过删除 .NET 元数据开销来减小数据大小(RAM 很宝贵)
  • 可以预测缓存的大小
  • 如果需要,执行加密或压缩。
  • 通过网络传输它们
  • 实现自定义序列化程序以选择要存储的内容
  • 二进制数据没有语言障碍(如果您有自己的序列化程序)

这些只是我认为正确的一些优点和缺点。我相信会有更多

了解这些优缺点,大多数或所有分布式缓存都选择序列化,即使缓存保留在进程中也是如此。当我们考虑大多数用例时,序列化成本也不是那么高。

此外,@Waescher的观点也是正确的,当涉及网络时,所有类型的数据都必须转换为字节进行传输。

Waescher是对的,如果有一台机器和单个进程,你可以将对象图存储在本地内存中。 如果有多个进程,那么它必须在共享内存中,这打开了一整罐蠕虫,这些蠕虫可能会也可能不会被第三方产品(如 Redis/memcached)解决。 例如,现在必须管理并发性(即确保一个进程不会在尝试读取图形的同时另一个进程正在修改图形,或者更雄心勃勃的无锁算法)。 事实上,这也必须在单个多线程进程中解决。

在共享内存

情况下,如果对象引用是内存指针,只要共享内存段映射到每个进程中的相同地址,它们可能仍然可用。 根据共享内存段的大小,以及进程的大小和每个进程的内存映射,这可能无法实现。 使用系统生成的对象标识符/引用(例如,按顺序递增的 4 字节或 8 字节整数)可以避免该问题。

归根结底,如果将对象图存储在任何存储库中,则必须将其序列化/反序列化为该存储库的存储/反序列化。