是否有可能将对象保存在内存中以获得比 Redis 或 Memcached 更快的缓存存储?
Is it possible to keep objects in memory for an even faster cache store than Redis or Memcached?
在存储复杂对象(例如 C# POCO 对象)时,内存缓存存储需要 serializing/deserializing。
难道不可以只把要缓存的数据作为对象图保存在内存中,消除这个瓶颈吗?毕竟,缓存和序列化的数据仍在内存中,所以为什么不将原始对象保留在内存中以获得尽可能快的缓存(并且可能使用命名管道来实现分布式缓存?)
谢谢
您提到的缓存旨在用作具有大量功能和选项的分布式缓存。在一个(全局)变量中保存一个对象,尤其是一个对象树,以便在一个进程中使用,总是比通过反序列化等努力从另一台计算机加载它要快。
但这不是 Redis & Co 的用例。一旦您尝试使用命名管道(或任何其他技术)实现自己的分布式缓存,您就会发现 Redis 有权存在。
换句话说:只要您将对象移过机器边界,就必须对它们进行序列化和反序列化。如果底层传输协议为您执行此操作,您可能只是不知道。
Waescher 是对的,如果只有一台机器和一个进程,您可以将对象图存储在本地内存中。如果有多个进程,那么它必须在共享内存中,这会打开一大堆蠕虫病毒,可能会或可能不会被第 3 方产品解决,例如 Redis/memcached。例如,现在必须管理并发性(即确保一个进程不会同时尝试读取图形,而另一个进程正在修改图形,或者更雄心勃勃的 lock-free 算法)。事实上,这也必须在单个 multi-threaded 过程中解决。
对象引用,在共享内存的情况下,如果它们是内存指针,只要共享内存段映射到每个进程中的相同地址,它们可能仍然可用。根据共享内存段的大小、进程的大小和每个进程的内存映射,这可能会也可能不会。使用 system-generated 对象 identifier/reference(例如,顺序递增的 4 或 8 字节整数)可以避免该问题。
归根结底,如果您将对象图存储在任何存储库中,它必须是该存储库存储的 serialized/deserialized into/out。
将对象保持在内存中有一些优点和缺点。一起来看看吧
优点:
- 不会有序列化和反序列化成本。
- 执行分析(节省序列化成本)会更容易。
- 在 Distributed Cache 中执行 MapReduce 函数时,对象不会存储为二进制以降低分析成本。
缺点
- 序列化实际上通过消除 .NET 元数据开销减少了数据大小(RAM 很宝贵)
- 可以预测缓存的大小
- 根据需要执行加密或压缩。
- 通过网络传输它们
- 实施自定义序列化程序以选择要存储的内容
- 二进制数据没有语言障碍(如果你有自己的序列化器)
这些只是我认为正确的一些优点和缺点。我相信会有更多
了解这些优缺点后,大多数或所有分布式缓存都会选择序列化,即使缓存保持在进程中也是如此。当我们考虑大多数用例时,序列化成本也没有那么高。
另外,@Waescher的观点也是对的,当涉及网络时,所有类型的数据都必须转换为字节才能传输。
在存储复杂对象(例如 C# POCO 对象)时,内存缓存存储需要 serializing/deserializing。
难道不可以只把要缓存的数据作为对象图保存在内存中,消除这个瓶颈吗?毕竟,缓存和序列化的数据仍在内存中,所以为什么不将原始对象保留在内存中以获得尽可能快的缓存(并且可能使用命名管道来实现分布式缓存?)
谢谢
您提到的缓存旨在用作具有大量功能和选项的分布式缓存。在一个(全局)变量中保存一个对象,尤其是一个对象树,以便在一个进程中使用,总是比通过反序列化等努力从另一台计算机加载它要快。
但这不是 Redis & Co 的用例。一旦您尝试使用命名管道(或任何其他技术)实现自己的分布式缓存,您就会发现 Redis 有权存在。
换句话说:只要您将对象移过机器边界,就必须对它们进行序列化和反序列化。如果底层传输协议为您执行此操作,您可能只是不知道。
Waescher 是对的,如果只有一台机器和一个进程,您可以将对象图存储在本地内存中。如果有多个进程,那么它必须在共享内存中,这会打开一大堆蠕虫病毒,可能会或可能不会被第 3 方产品解决,例如 Redis/memcached。例如,现在必须管理并发性(即确保一个进程不会同时尝试读取图形,而另一个进程正在修改图形,或者更雄心勃勃的 lock-free 算法)。事实上,这也必须在单个 multi-threaded 过程中解决。
对象引用,在共享内存的情况下,如果它们是内存指针,只要共享内存段映射到每个进程中的相同地址,它们可能仍然可用。根据共享内存段的大小、进程的大小和每个进程的内存映射,这可能会也可能不会。使用 system-generated 对象 identifier/reference(例如,顺序递增的 4 或 8 字节整数)可以避免该问题。
归根结底,如果您将对象图存储在任何存储库中,它必须是该存储库存储的 serialized/deserialized into/out。
将对象保持在内存中有一些优点和缺点。一起来看看吧
优点:
- 不会有序列化和反序列化成本。
- 执行分析(节省序列化成本)会更容易。
- 在 Distributed Cache 中执行 MapReduce 函数时,对象不会存储为二进制以降低分析成本。
缺点
- 序列化实际上通过消除 .NET 元数据开销减少了数据大小(RAM 很宝贵)
- 可以预测缓存的大小
- 根据需要执行加密或压缩。
- 通过网络传输它们
- 实施自定义序列化程序以选择要存储的内容
- 二进制数据没有语言障碍(如果你有自己的序列化器)
这些只是我认为正确的一些优点和缺点。我相信会有更多
了解这些优缺点后,大多数或所有分布式缓存都会选择序列化,即使缓存保持在进程中也是如此。当我们考虑大多数用例时,序列化成本也没有那么高。
另外,@Waescher的观点也是对的,当涉及网络时,所有类型的数据都必须转换为字节才能传输。