【问题标题】:Store forum messages using Redis & Booksleeve使用 Redis 和 Booksleeve 存储论坛消息
【发布时间】:2014-03-18 17:01:58
【问题描述】:

我有以下班级女巫在论坛中存储消息

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);
            }

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

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

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

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

如果上述问题的更优化解决方案是将消息存储在 redis 哈希中,我会徘徊,因为这样更新会更快。但是为了使用哈希,在 redis 上进行初始存储的代码会更复杂(慢),并且这段代码将在 web 服务器而不是 redis 服务器上运行。

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

您能否就stackoverflow 如何处理这种情况提供一些指导?

【问题讨论】:

    标签: c# redis booksleeve


    【解决方案1】:

    哈希在这里很自然,主要是因为该数据结构针对共享整体身份(包括到期等)的多个命名值。如果您当前使用的是MGET,则不会有巨大的性能差异 - 对于哈希,您只需使用HMGETHGETALLHMSET

    我认为这不会改变任何事情,使其变得更复杂:您只需将预期的更改填充到Dictionary&lt;string,byte[]&gt; 并使用.Hashes.Set(...)。一次而不是多次调用.Strings.Set。同样,使用.Strings.Get(...) 的可变参数形式与调用.Hashes.GetAll(...).Hashes.Get(...) 的可变参数形式没有太大区别。

    我也不接受这段代码会更慢 - 事实上,它基本上是相同的。实际上,在实现级别,对.Hashes.Set 的单个调用涉及Task 等方面的较少开销,因为它是单个可等待/可等待操作。

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

    吞吐量不应该成为问题。 Redis 以每秒 10 条(或 100 条)数千条消息的速度运行良好。

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

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

    您能否就stackoverflow 如何处理这种情况提供一些指导?

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

    【讨论】:

    • 谢谢 Mac,您的 cmets 非常有帮助,并引导我做出正确的决定。您正确地将存储检索方法转换为使用哈希是微不足道的。你说得对,我应该做一些压力测试(但我很懒)
    • 为了清楚起见,我们不在集合/排序集中进行压缩的原因是 gzip 不能保证每次输出完全相同,这会扰乱散列。 这是非常有用的信息!
    • @PanKak 确实...我们在 .NET 升级期间学到了这一点,当时 MS 更改了实现 - 仍然是有效的 gzip,但细节不同
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多