首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Redis和Booksleeve存储论坛消息

使用Redis和Booksleeve存储论坛消息
EN

Stack Overflow用户
提问于 2014-03-17 23:41:42
回答 1查看 214关注 0票数 1

我有下面的职业女巫在一个论坛里存储一条信息

代码语言:javascript
复制
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,当然是在Redis):

代码语言:javascript
复制
            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条时,该解决方案比我现在使用的解决方案更合适?

实际上,您能提供一些关于堆栈溢出如何处理这种情况的指导吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-18 08:29:54

哈希将是这里的自然匹配,主要是因为该数据结构针对多个共享总体标识(包括过期等)的命名值。如果您目前正在使用MGET,那么性能没有太大的差别--对于散列,您可以简单地使用HMGETHGETALLHMSET

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

我也不承认这段代码会慢一点--实际上,它基本上是一样的。实际上,在实现级别上,对.Hashes.Set的单个调用涉及较少的Task等开销,因为它是一个单一的可等待/awaitable操作。

目前,论坛在高峰时间收到约12条信息/分钟和20票/分钟(不包括每条信息的总票数)。

这种吞吐量不应出现问题。Redis在每秒数千条消息的10 s(或100多)下愉快地工作。

您认为是否值得使用散列来重新实现消息存储/检索过程,或者当消息插入速度增加到每分钟30条时,该解决方案比我现在使用的解决方案更合适?

这一信息率不应成为问题。如果你看到问题,请详细说明。然而,最简单和最合适的下一步将是模拟一些高得多的负载-看看什么工作。

实际上,您能提供一些关于堆栈溢出如何处理这种情况的指导吗?

我们通常使用SQL数据库作为我们的主要数据存储区(尽管有些东西只保存在redis中)。我们广泛使用redis将处理过的项存储为缓存,但由于它们不受更改,所以不按字段存储它们:相反,我们对DTO类型使用protobuf,并存储数据块(使用字符串类型,即GET/SET)。此外,如果大小超过阈值(并且只要它没有进入一个集合/排序集),我们就快速进行"gzip“测试,看看如果压缩它(不是所有的东西),它是否会变小:如果是这样的话,我们就存储它--所以我们有绝对最小的带宽和存储开销,并且在存储/提取时非常快地处理。为了清晰起见,我们不使用sets/sorted-set压缩的原因是gzip不保证每次都有完全相同的输出,这会扰乱散列。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22467649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档