我正在创建一个移动应用程序,它需要一个 API 服务后端来获取/放置每个用户的信息。我将在ServiceStack上开发 Web 服务,但对存储感到疑惑。我喜欢像Redis这样的快速内存缓存系统的想法,但我有几个问题:
1 回答
设计 NoSQL Redis 应用程序时要考虑什么
1) 要在 Redis 中正确开发,您应该更多地考虑如何在 C# 程序中构建关系,即使用 C# 集合类而不是用于 RDBMS 的关系模型。更好的思维方式是更多地考虑像文档数据库这样的数据存储,而不是 RDBMS 表。基本上所有东西都通过一个键(索引)在 Redis 中被删除,所以你只需要弄清楚你的主要实体是什么(即聚合根),它将被保存在它自己的“键命名空间”中,或者它是否是非主要实体,即简单应该与其父实体一起保存的元数据。
Redis 作为主要数据存储的示例
这是一篇很好的文章,介绍了如何使用 Redis 创建一个简单的博客应用程序:
http://www.servicestack.net/docs/redis-client/designing-nosql-database
您还可以查看RedisStackOverflow 的源代码,了解另一个使用 Redis 的真实示例。
基本上,您需要分别存储和获取每种类型的项目。
var redisUsers = redis.As<User>();
var user = redisUsers.GetById(1);
var userIsWatching = redisUsers.GetRelatedEntities<Watching>(user.Id);
您存储实体之间关系的方式是利用 Redis 的集合,例如:您可以在概念上存储用户/观察者关系:
SET["ids:User>Watcher:{UserId}"] = [{watcherId1},{watcherId2},...]
Redis 是无模式和幂等的
将 id 存储到 redis 集中是幂等的,即您可以将watcherId1多次添加到同一个集中,并且它只会出现一次。这很好,因为这意味着您永远不需要检查关系的存在,并且可以自由地继续添加相关的 id,就像它们从未存在过一样。
相关:写入或读取不存在的 Redis 集合(例如列表)与写入空集合相同,即当您将项目添加到列表同时访问非现有列表将仅返回 0 个结果。这是一个无摩擦和生产力的胜利,因为您不必为了使用它们而预先定义您的模式。虽然你应该需要 Redis 提供了EXISTS操作来确定一个键是否存在或者一个TYPE操作以便你可以确定它的类型。
在您的文章中创建您的关系/索引
要记住的一件事是,由于 Redis 中没有隐式索引,因此您通常需要设置在写入期间读取自己所需的索引/关系。基本上,您需要预先考虑所有查询需求,并确保在写入时设置必要的关系。上面的 RedisStackOverflow 源代码就是一个很好的例子。
注意:ServiceStack.Redis C# 提供程序假定您有一个名为Id的唯一字段,它是它的主键。您可以将其配置为使用具有ModelConfig.Id()配置映射的不同字段。
Redis 持久化
2) Redis 支持 2 种持久化模式开箱即用的 RDB 和 Append Only File (AOF)。RDB 编写例行快照,而 Append Only File 就像一个事务日志,记录快照之间的所有更改 - 我建议添加两者,直到您对每个快照的功能和应用程序的需求感到满意为止。您可以在http://redis.io/topics/persistence阅读所有 Redis 持久性。
注意 Redis 还支持简单的复制,您可以在以下位置阅读更多信息:http ://redis.io/topics/replication
Redis 喜欢 RAM
3) 由于 Redis 主要在内存中运行,因此最重要的资源是您有足够的 RAM 将整个数据集保存在内存中 + 一个缓冲区用于快照到磁盘。Redis 非常高效,因此即使是小型 AWS 实例也能够处理大量负载——您要寻找的是有足够的 RAM。
使用 Redis Admin UI 可视化您的数据
最后,如果您使用的是ServiceStack C# Redis 客户端,我建议您安装Redis Admin UI,它可以为您的实体提供一个很好的可视化视图。您可以在以下位置看到它的现场演示: http ://servicestack.net/RedisAdminUI/AjaxClient/