c# - 使用 Redis 和 Booksleeve 存储论坛消息

标签 c# redis booksleeve

我有以下类(class)女巫在论坛中存储一条消息

using System;
using System.Collections.Generic;

public partial class ForumMessage
{
    public ForumMessage()
    {
        this.Votes = new HashSet<ForumMessageVote>();
        OnCreated();
    }

    partial void OnCreated();

    public long id { get; set; }
    public int forumId { get; set; }
    public Nullable<long> parentId { get; set; }
    public int memberId { get; set; }
    public int lastModifiedMemberId { get; set; }
    public Nullable<long> lastReplyId { get; set; }
    public string title { get; set; }
    public string body { get; set; }
    public string imagePath { get; set; }
    public Nullable<bool> isSticky { get; set; }
    public Nullable<bool> allowPosts { get; set; }
    public Nullable<bool> allowImages { get; set; }
    public Nullable<bool> allowYoutube { get; set; }
    public Nullable<bool> allowBbCode { get; set; }
    public Nullable<long> totalMessages { get; set; }
    public Nullable<long> totalViews { get; set; }
    public Nullable<long> totalDailyViews { get; set; }
    public Nullable<int> totalVotes { get; set; }
    public Nullable<long> totalScore { get; set; }
    public bool published { get; set; }
    public Nullable<System.DateTime> publishedDate { get; set; }
    public Nullable<System.DateTime> lastModifiedDate { get; set; }
    public Nullable<bool> isTemporary { get; set; }
    public Nullable<System.DateTime> lastReplyDate { get; set; }
    public Nullable<int> lastReplyMemberId { get; set; }
    public Nullable<long> sortByLastReplyId { get; set; }
    public Nullable<bool> containsImage { get; set; }
    public Nullable<bool> containsVideo { get; set; }
    public Nullable<bool> @private { get; set; }

    public virtual Forum Forum { get; set; }
    public virtual ICollection<ForumMessageVote> Votes { get; set; }
    public virtual Member Member { get; set; }
}

目前,我正在使用 Booksleeve 缓存这些对象,方法是使用以下代码(简化版)将它们与 Json 序列化存储在字符串键中(当然在 Redis 中):

            using (var conn = conn.CreateTransaction())
            {
                return conn.Store<ForumMessage>(db, message.id, message);
            }

在我的论坛应用程序 View 中,我使用了上述大部分字段,因为我显示了属于论坛主题的上述消息列表。

为了获取 ForumMessage 类的列表,我使用了 mget 命令。

当用户发布新消息或为消息投票时,我需要更新上面的一些字段。当我更新时,我通过 redis get 获取消息,更新所需的字段(主要是一个或两个字段),然后我通过 conn.store booksleeve 方法存储更新.

目前论坛在高峰时段收到约12条消息/分钟和20票/分钟(总票数不是每条消息)

我想知道是否有更好的解决方案是将消息存储在 Redis 哈希中,因为那样更新会更快。但是为了使用哈希,在 redis 中进行初始存储的代码将更加复杂(缓慢),并且该代码将在 web 服务器而不是 redis 服务器上运行。

您认为通过使用哈希或我现在使用的解决方案重新实现消息存储/检索过程是否值得,例如当消息插入速率以 30 条消息/分钟的速度增加时能够很好地扩展?

本质上,您能否就 stackoverflow 如何处理这种情况提供一些指南?

最佳答案

散列很适合这里,主要是因为该数据结构针对共享一个整体身份(包括过期等)的多个命名值。如果您当前使用的是 MGET,则性能不会有巨大差异。 - 对于哈希,您只需我们 HMGET , HGETALL , 和 HMSET .

我看不出这会使其变得更复杂:您只需将预期的更改填充到 Dictionary<string,byte[]> 中即可。并使用 .Hashes.Set(...) .一次而不是打电话 .Strings.Set多次。同样,使用 .Strings.Get(...) 的 varadic 形式与调用 .Hashes.GetAll(...) 没有太大区别或 .Hashes.Get(...) 的可变形式.

我也不接受这段代码会变慢——事实上,它基本上是相同的。事实上,在实现层面,一次调用 .Hashes.SetTask 方面涉及更少的开销等等,因为它是一个单一的可等待/等待操作。

Currently the forum at peak hours receives about 12 messages / minute and 20 votes / minute(total votes not per message)

吞吐量应该不会成为问题。 Redis 在每秒 数千 条消息中愉快地工作。

Do you think it worth to reimplement the message store/retrieve procedure by using hashes or the solution than I'm using right now will be able to scale fine when for example the rate of message inserts increase with 30 messages/minute?

该消息速率应该没有问题。如果您发现问题,请详细说明。然而,最简单和最合适的下一步是模拟一些更高的负载 - 看看有什么效果。

In essence can you provide some guidelines on how stackoverflow handles this situations?

我们通常使用 SQL 数据库作为我们的主要数据存储(尽管有些东西只保存在 redis 中)。我们广泛使用 Redis 将已处理的项目存储为缓存,但由于它们不受更改的影响,因此我们不会逐个字段地存储它们:相反,我们针对 DTO 类型使用 protobuf-net 并存储数据 block (使用字符串类型,即 GET/SET )。此外,如果大小超过阈值(只要它不进入集合/排序集合),我们会进行快速“gzip”测试,看看如果我们压缩它是否会变小(不是所有的东西)确实):如果是,我们存储它 - 所以我们有绝对最小的带宽和存储开销,并且在存储/获取时处理速度非常快。为清楚起见,我们不在集合/排序集合中压缩的原因是 gzip 不能保证每次输出完全相同,这会扰乱哈希。

关于c# - 使用 Redis 和 Booksleeve 存储论坛消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22467649/

相关文章:

c# - 如何检查一个对象是否包含值?

C# Math.Round 模棱两可的问题

redis - 使用 Redis 检查 IP 是否在某个范围内

python - 无法为 Flask-Limiter 设置策略 ="moving-window"

c# - Basic Booksleeve 加 Protobuf-net 加 Lists/SortedSets,实现?

c# - SortedSets.UnionAndStore 的 Redis Booksleeve 重量选项?

c# - 在 C# 中检查堆完整性和堆栈大小

node.js - Redis 'multi' 使用动机

redis - 如何从 BookSleeve 调用 BGSAVE?

c# - 搜索字典的值