redis - Windows 2008 R2 上使用 Redis 的大型数据集的缓存策略

标签 redis servicestack

我正在研究是否使用 Redis 缓存大型数据集。

最大的数据集包含大约 500 万个对象。虽然每个对象都有一个唯一的标识符,但它们从不被客户端单独使用;对整个数据集执行聚合和连接操作。

目标环境是 4 台服务器,每台服务器配备 144 Gb 内存、24 个内核和千兆网卡 - 运行 Windows 2008 R2 企业版。为此,我在每个盒子上安装了 10 个来自 Microsoft Open Technologies 的 Redis-64.2.6.12.1 实例。我正在使用 ServiceStack 的 Redis 客户端。

我已将数据分成 1000 个对象的 block (这似乎提供了最佳性能)并使用 ShardedRedisClientManager 对每个 block ID 进行哈希处理以将数据分布到 40 个缓存中。对象映射被持久化,以便客户端应用程序可以仅使用数据集 ID 继续检索所有对象。 Redis 列表用于对象和对象映射。

事务并没有提高性能,但是通过按连接对 chuck 进行分组,并行处理提高了性能。然而,性能仍然不尽如人意。设置然后获取 5m 个对象加上对象映射的最佳时间是 268055 毫秒。

那么,有没有更好的方法来使用 Redis 缓存大型数据集?缓存这样的数据集是否合理?我是否应该将序列化到磁盘并将处理转移到 ala hadoop 中?

最佳答案

问题不是 Redis 是否适合大型数据集,而是您的数据集和用例是否适合 Redis。

Redis 本质上允许您维护分布式计算机科学集合,并让您以线程安全的原子方式访问它们并与之交互,以每种数据集合类型允许的最佳 Big O 表示法性能。

网络往返和带宽延迟以及数据访问模式

Redis 可能很快,但它仍然受到网络延迟和最佳数据存储和访问模式的限制,例如您仍然需要关注所需的网络往返次数和带宽,无论您的数据访问是否需要全表扫描或可以通过自定义索引减少以及您正在使用的序列化库的性能开销。

  • 你需要全表数据扫描还是可以maintain custom indexes
  • 您需要传输整个数据集吗?
  • 您能否利用服务器端 LUA 操作来最大程度地减少往返次数并减少带宽?

您应该改用 blob 存储吗?

每次都想要传输整个数据集似乎很奇怪,这可能表明您不应该维护数据集并将其逐项归入 Redis 服务器集合。如果您只是在客户端访问和操作数据集,那么将数据存储到 Redis 集合中并没有真正的好处。

如果您的用例是我可以将 500 万个对象混合到内存中 .NET 数据结构中的最快方法,那将只是将整个数据集作为一个 blob 存储到单个 GET/SET 条目中使用像 ProtoBuf 或 MessagePack 这样的快速二进制格式。通过这种方式,Redis 仅充当快速内存中的 blob 存储。如果对数据存储的访问不需要分布式(即通过网络访问)而不是像 Level DB 这样的快速嵌入式数据存储会更优化。

跨多个复制或分片的 redis 服务器分发和分 block 化数据集

为了获得最佳性能,您可以更进一步并使用 GETRANGE/SETRANGE从多个复制的 redis 服务器读取 block ,或者只是将序列化的二进制 blob 分 block 到多个分片的 redis 服务器上——尽管这意味着如果没有它们的整个聚合, block 本身是无用的,因此损坏的 block 会使整个数据集无效。

关于redis - Windows 2008 R2 上使用 Redis 的大型数据集的缓存策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17138078/

相关文章:

c# - 通过在 c# 中使用 console.writeline 获取 byte [][] 的输出,servicestack

json - 如何将 F# Union 类型与 Servicestack JSON 序列化结合使用?

api - 在应用程序中使用 FacebookAuthProvider

redis - 在配置文件中进行身份验证?

Ruby:Resque 立即排队

node.js - 在谷歌云功能端关闭redis连接

java - 如何从 Redis 源代码创建共享库或静态库?

servicestack - 如何让 RedisMqServer 在重试消息之前等待一秒钟?

c# - ServiceStack Razor View 编译错误

php - 检查时间戳然后 Redis 发布一个事件?