使用Redis&存储论坛消息Booksleeve

时间:2014-03-17 23:41:42

标签: c# redis booksleeve

我有以下类巫婆在论坛中存储消息

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 获取获取消息,更新所需的字段/字段(主要是一个或两个字段),然后通过 conn.store booksleeve方法存储更新

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

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

您是否认为使用哈希或解决方案重新实现消息存储/检索过程比我现在使用的那样能够扩展正常,例如消息插入率增加30条消息/分钟?

从本质上讲,您可以提供一些有关stackoverflow如何处理这种情况的指南吗?

1 个答案:

答案 0 :(得分:1)

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

我不认为这会使其变得更复杂:您只需将预期的更改填充到HMSET并使用Dictionary<string,byte[]>。一次而不是多次调用.Hashes.Set(...)。同样地,使用varadic形式的.Strings.Set与调用.Strings.Get(...)或varadic形式的.Hashes.GetAll(...)没有什么不同。

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

  

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

吞吐量不应该成为问题。 Redis在每秒10秒(或100秒)的数千个消息中工作愉快。

  

你认为通过使用哈希或解决方案重新实现消息存储/检索过程是否值得我现在正在使用将能够在例如消息插入率增加30条消息时进行缩放分钟?

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

  

从本质上讲,您可以提供一些有关stackoverflow如何处理这种情况的指南吗?

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