【问题标题】:Caching a post system with users与用户一起缓存帖子系统
【发布时间】:2016-07-16 03:41:55
【问题描述】:

背景

想象一下像 Twitter 这样的发布系统。您有帖子,每个帖子都有一个发布它的用户。我正在尝试做一些与此非常相似的事情,但我找不到正确的方法。

主要问题是缓存所有内容,例如,我不想每 30 秒下载一次所有帖子。为了解决这个问题,我简单地从服务器的最后一篇文章和本地数据库的最后一篇文章中获取日期,如果不同,请更新它。 问题是:如果有人更改了已经在用户本地数据库中的某个帖子的文本,则不会更新。我们称之为问题#1

下一个问题(也是最成问题的)是用户。每个帖子都显示了发布它的用户的头像,所以我不能简单地缓存帖子,因为如果用户更改了他的头像,缓存的版本将保留最后一个头像(也由于问题 #1)。为了解决这个问题,我使用了一个通用的头像 URL,但是如果帖子有用户名怎么办?这是问题 #2

到目前为止我的解决方案

为了解决问题 #1,我想在每个帖子中添加版本号,当有人编辑它时,版本号会增加。如果帖子的版本号与数据库不同,则重新下载帖子内容并更新。但是如果我有这么多帖子,如果有多个用户在使用该服务,请求就会变得庞大并导致服务器过载。

为了解决问题 #2,我想到了与问题 #1 类似的事情。我在每个用户配置文件上添加了一个版本号。如果用户更新它,那么版本号就会增加。加载帖子后,我向本地数据库发送请求以检索用户配置文件,然后它检查版本号,如果它与服务器匹配,则返回它,否则,更新并返回。这也会很昂贵,特别是如果用户只是更新了他的名字然后我重新下载了头像,但为此我可以有两个单独的版本号。

问题

处理这类问题的最佳方法是什么,最可扩展的解决方案,不会因请求而使服务器超载,也不会在用户的智能手机上下载大量不必要的东西?

我在用什么

我首先在 Android 上使用 SQLite 存储数据。我使用Socket.IO 与服务器快速通信并接收请求。

【问题讨论】:

    标签: android sqlite caching


    【解决方案1】:

    您应该尝试使用推送通知来更新数据,而不是检查更新,让服务器在每次数据更改时通知您。

    这可以帮助您澄清疑虑: How does GCM work ? (google cloud messaging for Android)

    GCM https://developers.google.com/cloud-messaging/android/client

    【讨论】:

    • 这正是我想要的。谢谢:D
    【解决方案2】:

    不知道我的建议是不是用来杀死蚂蚁的火箭筒,但它是这样的:

    Event Sourcing 似乎很适合您的解决方案。由于您需要将后端的所有内容缓存在客户端上,因此 E.S.将允许您从本地版本下载更改的内容。客户端就像 “嘿服务器,给我从 2016 年 3 月 27 日 19:52:28 UTC 开始的所有用户更改”(您始终可以限制您需要的内容。例如“用户 w/ID 的更改1”、“用户和帖子的变化”或“用户 {1,2,3} 和帖子 {4,5,6} 的变化”)。

    小例子:

    GET /users-events?since={timestamp}(是的,不是最好的端点名称,我知道)

    那么你的有效载荷将是这样的:

    [
        {
            id: 1,
            name: "Foo",
            avatar: "http://example.com/foo.png",
            timestamp: 1234567890123
        },
        {
            id: 1,
            name: "Bar",
            timestamp: 124680246802
        },
        {
            id: 2,
            name: "Baz",
            timestamp: 124680246803
        }
    ]
    

    如您所见,有效负载将返回的不是实体本身,而是自指定时间戳以来其中的更改。你可以这样理解:

    用户 1 在 1234567890123 将其名称更改为“Foo”并将头像更改为“http://example.com/foo.png

    用户 1 在 124680246802 将其名称更改为“Bar”

    用户 2 在 124680246803 将其名称更改为“Baz”

    事件非常好,因为考虑到您的主要目标是提高缓存能力并减少带宽使用,您可以从后端数据库中获取事件并生成一个新事件,将所有更改合二为一(以最大程度地减少冗余)。如果我们在示例中应用它,我们将完成以下操作:

    [
        {
            id: 1,
            name: "Bar",
            avatar: "http://example.com/foo.png",
            timestamp: 124680246802
        },
        {
            id: 2,
            name: "Baz",
            timestamp: 124680246803
        }
    ]
    

    由于用户 1 将其名称更改为“Foo”并在更改为“Bar”之后对客户端无关紧要。

    当然,这意味着您的后端需要进行额外的更改,因为它需要将更改存储到您需要缓存的实体中。

    【讨论】:

      猜你喜欢
      • 2017-01-24
      • 2013-02-13
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 2022-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多