4

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

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

谢谢

4

3 回答 3

2

将对象保持原样在内存中具有一些优点和缺点。让我们来看看他们

优点:

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

缺点

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

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

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

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

于 2016-02-04T06:09:45.897 回答
2

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

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

换句话说:只要将对象移动到机器边界上,就必须对它们进行序列化和反序列化。如果底层传输协议为您执行此操作,您可能只是不知道。

于 2016-01-26T19:38:26.167 回答
1

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

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

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

于 2016-01-27T18:30:59.150 回答