百万用户时尚分享网站feed系统扩展实践

朋友圈微博feed流,推拉实践 feed流业务的推拉模式小结: • 拉模式,读扩散,feed存一份,存储小,用户集中访问数据,性能差 • 推模式,写扩散,feed存多份,用冗余存储换锁冲突,性能高 立即下载
摘要:Fashiolista作为一个以社交、分享为主的在线时尚交流网站,其feed系统占据了网站的核心架构,其扩展性至关重要。网站创始人兼CTO撰写博客,分享了自家网站feed系统扩展的经验。

Fashiolista是一个在线的时尚交流网站,用户可以在上面建立自己的档案,和他人分享自己的以及在浏览网页时看到的时尚物品。目前,Fashiolista的用户来自于全球100多个国家,用户达百万级,每日分享的时尚物品超过500万。作为一个以社交、分享的网站,feed系统占据了网站的核心架构,Fashiolista的创始人兼CTO Thierry Schellenbach撰写了一篇博客,分享了自家网站feed系统建设的经验,译文如下:

Fashiolista最初是我们作为兴趣在业余时间开发的一个项目,当初完全没有想到它会成长为规模如此大的在线时尚交流网站。最早的版本开发用了大概两周的时间,当时feed信息流推送系统相当简单。在这里分享一些我们扩展feed系统的经验。


对于许多大型的创业公司,如Pinterest、Instagram、Wanelo和Fashiolista来说,feed是一个核心组件。在Fashiolista网上的 flat feed、aggregated feed和notification系统功能都是靠feed系统来支撑的。本文中将介绍我们在扩展feed系统中遇到的问题,以及你自己方案中的设计决策。随着越来越多的应用依赖于feed系统,理解feed系统的基本工作原理变得至关重要了。

另外,Fashiolista的feed系统Python版本——Feedly已经开源了。

Feed简介

feed系统的扩展问题曾引起过广泛关注,这个解决方案是为了在网络拥挤的情况下,构建一个类似于Facebook新鲜事feed、Twitter流或Fashiolista的feed页面。这些系统的共同点在于向用户展示其关注的人的动态,我们就是基于这个标准来构建动态数据流的,诸如“Thierry在Fashiolista列表中添加了一件服饰”或“Tommaso发布了一条twitter”。

构建这个feed系统用到了两个策略:

  1. 拉取(Pull),读取的过程中收集feed。
  2. 推送(Push),写的过程中提前计算好feed。

大多数实时在线应用程序会使用这两种方法的组合,将动态推送给你的粉丝的过程被称为消息分发(fanout)。

历史和背景

Fashiolista的feed系统经过了三次重大改进。第一个版本基于PostgreSQL数据库,第二个版本使用Redis数据库,目前的版本采用Cassandra数据库。为了便于读者更好的理解这些版本更替的时间和原因,笔者会首先介绍一些背景知识。

第一部分——数据库

第一版本的数据库查询语句很简单,类似于这种:

select * from love where user_id in (...)

令人惊讶的是这个系统的强健性还不错。当love(类似于“赞”了某件服饰)的数量达到百万时,它运行得很好,超过500万时,依然没有问题。我们还打赌说这个系统不能支持千万的数量级,但是当love到达千万时,它依然运行得很好。这个简单的系统支撑着我们的系统达到了百万的用户和过亿的love,期间只进行了一些小改动。之后随着用户的增多,这个系统开始出现波动,部分用户的延时长达数秒,在参考了很多关于feed系统的架构设计之后,我们开发了第一个基于Redis的Feedly。

第二阶段——Redis和Feedly

我们为每个用户建立一个用Redis存储的feed,当你love了一件服饰时,这个动态会分发给你所有的粉丝。我们尝试了一些小技巧来减少内存的消耗(笔者会在下面具体介绍),Redis的启动和保持确实比较简单。我们使用Twemproxy在几台Redis机器上进行共享,使用Sentinel做自动备份。

Redis是一个好的解决方案,但是几个原因迫使我们不得不寻找新的方案。首先,我们希望支持多文档类型,而Redis返回数据库查询更困难,并且提高了存储需求。另外,随着业务的增大,数据库回滚也变得越来越慢。这些问题只能靠在Redis上存储更多的数据来解决,但是这样做的成本太高了。

第三阶段——Cassandra和Feedly

通过比较HBase、DynamoDB和Cassandra2.0,我们最终选择了Cassandra,因为它拥有几个移动部件,Instagram使用的数据库就是Cassandra,并且Datastax为它提供支持。Fashiolista目前在flat feed中完全采取推送流,聚合feed采用推送和拉取混合的技术。我们在每个用户的feed中最多保存3600条动态,目前占用了2.12TB的存储空间。由明星用户带来的系统波动我们也采取了一些方式进行缓解,包括:优先队列、扩大容量和自动扩展等。


Feed设计

笔者认为Fashiolista设计的改进过程非常有代表性,在构建一个feed系统时(尤其是使用Feedly)有几个重要的设计问题需要考虑。

1.非规范化Vs规范化

规范化的方法是,你关注的人的feed列表中是每条动态的ID,非规范的存储是动态的所有信息。

仅存储ID可以大幅度减少内存消耗,然而这意味着每次加载feed都要重新访问数据库。如何选择取决于你在进行非规范化存储时,复制数据的频率。比如构建一个消息通知系统和一个feed系统有很大的区别:通知系统中每个动作的发生只需要被发送给几个用户,而feed系统中每个动态的数据可能要被复制给成千上万的粉丝。

另外,如何选择取决于你的存储架构,使用Redis时,内存是需要特别注意的问题;而使用Cassandra要占用大量的存储空间,但是对于规范化数据来说使用并不简单。

对于feed通知和基于Cassandra构建的feed,笔者建议将你的数据非规范化。而基于Redis的feed你需要最小化内存消耗,并保持数据规范化。采用Feedly可以轻松实现两种方案。

2.基于生产者的选择性分发

Yahoo的Adam Silberstein等人所著的论文中,提出了一种选择性推送用户feed的方法,Twitter目前也在使用类似的方法。明星用户的消息分发会给系统带来突然和巨大的负载压力,这意味着必须要预留出额外的空间来保持实时性。这篇论文中建议通过选择性地分发消息,来减少这些明星用户带来的负载。Twitter采用了这个方法后,在用户读取时才加载这些明星用户的tweet,性能得到了大幅度提升。

3.基于消费者的选择性分发

另外一种选择性分发方式是指对那些活跃用户(比如过去一周登录过的用户)分发消息。我们对这个方法进行了修改,为活跃用户存储最近的3600条动态,为非活跃用户存储180条,读取180条之后的数据需要重新访问数据库,这种方式对于非活跃用户的体验不太好,但是能有效降低内存消耗。

Silberstein等人认为最适合选择性推送模式的情境是:

  1. 生产者偶尔生产动态信息
  2. 消费者经常请求feed

遗憾的是Fashiolista还不需要如此复杂的系统,很好奇业务要达到多少数量级才会需要这种解决方案。

4.优先级

 一个替代的策略是在分发任务时采取不同的优先级,将给活跃用户的分发任务设为高优先级,向非活跃用户的分发任务设为低优先级。Fashiolista为高优先级的用户预留了一个较大的缓存空间,来处理随时的峰值。对于低优先级用户,我们靠自动扩展和点实例。在实践中,这意味着非活跃用户的feed会有一定的延时。使用优先级降低了明星用户对系统的负载压力,虽然没有解决根本问题,但大幅度降低了系统负载峰值的量级。

5.Redis Vs Cassandra

Fashiolista和Instagram都经历了从Redis开始,然后转战Cassandra的过程。笔者之所以会推荐从Redis开始是因为Redis更容易启动和维持。

然而Redis存在一定的限制,所有的数据需要被存储在RAM中,成本很高。另外,Redis不支持分片,这意味着你必须在结点间分片(Twemproxy是一个不错的选择),这种分片很容易,但是添加和删除节点时的数据处理很复杂。当然你可以将Redis作为缓存,然后重新访问数据库,来克服这个限制。但是随着访问数据库的成本越来越高,笔者建议还是用Cassandra代替Redis。

Cassandra Python的生态系统正在发生巨变,CQLEngine和Python-Driver都是很优秀的项目,但是它们需要投入一定的时间去学习。

结论

在构建自己的feed解决方案时,有很多因素需要在节点分片时考虑:选择何种存储架构?如何处理明星用户带来的负载峰值?非规范化数据到何种程度?笔者希望借助这篇文章能够为你提供一些建议。

Feedly不会为你做任何选择,这仅是一个构建feed系统的框架,你可以自己决定内部的技术细节。可以看Feedly的介绍进行了解或参看操作手册构建一个Pinterestsque应用程序。

请注意只有数据库中的用户达到百万时,你才会需要解决这个问题。在Fashiolista简单的数据库解决方案就支撑我们达到了百万用户和过亿的love。

更多关于feed系统的设计,笔者强烈建议看一下这些文章:

原文链接:Design Decisions For Scaling Your High Traffic Feeds(编译/周小璐 审校/仲浩)

模糊高清修复真王炸!ComfyUI-SeedVR2-Kontext(画质修复+P图)本地部署教程 SeedVR2_comfyUI 是由字节跳动 Seed 实验室与南洋理工大学 S-Lab 联合开源的,专为 ComfyUI 用户开发的插件版本,官方项目名为。它主打,在图像超分上表现尤其亮眼,被多位实测者称为“目前模糊图像修复最强模型“。SeedVR2 在图像超分任务中表现突出,尤其擅长恢复模糊图像的细节,被称为“模糊高清修复真王炸”。特别的,也适合用于文字密集图像(如截图、扫描文档、老照片字幕)修复。模型通过对抗训练 + 特征匹配损失提升细节真实感,理论上对文字边缘锐化也有帮助。 阅读详情

相关推荐

MySQL下载和安装教程

1.下载MySQL数据库可以访问官方网站:https://www.mysql.com/ 2.点击DOWNLOADS模块下的Community模块下的MySQL Community Server进行下载。 由于目前最新版本是:MySQL Community Server 5.7.21 建议博友下载历史版本,本博下载的是5.6.39 下载步骤: 进入,选择MySQL的版本及主机 根据自己的电脑选择相应的位数进行下载,本机是64位,点击download。 进入下.

残雪的剑的博客 4万+

使用 Redis 实现 Feed 流

背景 最近接到一个需求,用一句话来说就是:展示关注人发布的动态,这个涉及到 feed 流系统的设计。本文主要介绍一个一般企业可用的 Feed 流解决方案。 相关概念 下面先介绍一下关于 Feed 流的简单概念。 什么是 feed 流 Feed:Feed 流中的每一条状态或者消息都是 Feed,比如微博中的一条微博就是一个 Feed。 Feed流:持续更新并呈现给用户内容的信息流。每个人的朋友圈,...

dearKundy的博客 4560

开放词汇目标检测(Open-Vocabulary Object Detection, OVOD)综述

综上,大多数工作均基于CLIP预训练的图像编码器和文本编码器。GlIP为解决目标检测任务提供了先例,后续很多工作常与目前较为广泛使用的目标检测网络结构相结合,从而构建新的开放词汇目标检测器。如ViLD基于Mask R-CNN、RegionCLIP基于R-CNN、VLDet和BARON基于Faster R-CNN。更具有创新性的工作是Detic,提出了使用图像分类的数据集来对目标检测器的分类头进行训练。

yangsn0719的博客 4400

Redis——实现关注与取关等功能

目录 实现关注与取关 实现共同关注功能 关注推送 Feed流的模式 拉模式 推模式 推拉结合模式 总结 基于推模式实现关注推送功能 Feed流的分页问题 实现关注推送页面的分页查询 实现关注与取关 实现 Controller层 @RestController @RequestMapping("/follow") public class FollowController { @Resource private IFollowService follow

study_maker的博客 1984

AU混响终极指南:从‘干声’到‘空间感’,用总音轨和发送技巧打造专业人声

本文详细介绍了如何在Adobe Audition(AU)中使用混响效果器,通过总音轨和发送技巧将‘干声’转化为具有专业‘空间感’的人声。从混响基础原理到总线架构设置,再到精细控制和自动化调整,全面解析了提升音频质量的实用技巧,适用于音乐制作、播客和内容创作。

weixin_30512089的博客 331

Simeck算法流程

算法流程 paper在此:https://eprint.iacr.org/2015/612.pdf x ⋘\lll⋘ c denotes the cyclic shift of x to the left by c bits. x & y is the bitwise AND of x and y. x⊕yx \oplus yx⊕y is the exclusive-or (XOR) of x and y. github代码在此:https://github.com/bozhu/Simeck

Simp123 1074

基于Redis实现Feed流消息推送

feed流即持续更新并呈现给用户内容的信息流。feed是将用户主动订阅的若干消息源组合在一起形成内容聚合器,帮助用户持续地获取最新的订阅源内容。feed直接翻译是饲料的意思,其实是把用户都比喻成爱吃东西得某种动物,不断的给他喂食,满足他的需求,wiki百科上定义是一种数据格式,网站可通过它将最新信息传播给用户,用户能够订阅网站的先决条件是网站可提供持续更新的信息。流,就是他的呈现形式,就是这个信息怎么呈现的,大多数的都是根据时间排列的形式呈现的。

weixin_64161454的博客 726

ROS专栏—基于STM32F103的INA219电源数据采集

文章主要记录了stm32f103对ina219的数据采集

热爱生活、奋斗前行 2351

设计一个feed流系统

移动互联网时代,Feed流产品是非常常见的,如朋友圈、微博、抖音等,除此之外,很多App的都会有一个模块,要么叫动态,要么叫消息广场,这些也是Feed流产品。只要大拇指不停地往下划手机屏幕,就有一条条的信息不断涌现出来。就像给宠物喂食一样,只要它吃光了就要不断再往里加,故此得名Feed(饲养)。

zhongzhh8的博客 1989

Transformer 时间序列预测实战

Transformer 时间序列预测实战

机器学习深度学习业余选手 743

TriCore架构-基于TC397在SOTA过程中AB-SWAP切换底层原理

TC397的SOTA升级机制通过硬件地址重映射实现,利用MMU将逻辑地址动态映射到不同物理地址。其PFlash支持标准/备用地址映射,通常使用PF0+PF1+PF4空间以便于OTA处理。升级时,新固件自动写入非活动分区(A/B分区切换),由地址转换函数完成逻辑地址到物理地址的转换。系统重启后根据寄存器选择启动区域,实现安全无缝的固件更新。

xiandang8023的博客 490

Feedly-Fashiolista的feed系统框架学习

django的feed第三方包,有个feedly,是时尚分享网站Fashiolista

AllenLing的专栏 1895

基于FFT的轴承故障诊断 - MATLAB代码和详细解释

最后,我们可以根据异常特征的位置和特征分析来确定轴承故障的类型。最后,我们可以根据异常特征的位置和特征分析来确定轴承故障的类型。因此,通过分析频谱图,我们可以识别轴承故障的特征。因此,通过分析频谱图,我们可以识别轴承故障的特征。我们可以选择适当的阈值,并在频谱图上标记异常特征。通过这种基于FFT的轴承故障诊断方法,我们可以快速、准确地检测和诊断轴承故障。接下来,我们将应用FFT来获取振动信号的频谱信息,频谱显示了信号在不同频率上的能量分布。通过将异常特征标记在频谱图上,我们可以直观地识别轴承故障的存在。

COWizard的博客 613

Feed系统架构资料收集

完全用nosql轻松打造千万级数据量的微博系统 微博feed系统的push和pull模式和时间分区拉模式架构探讨 关于如何构建一个微博型广播 关于如何构建一个微博型广播2 用 mongodb 储存多态消息/提醒类数据 构建高性能的微博系统-再谈新浪微博架构 人人网技术经理张铁安-Feed系统结构浅析 新浪微博Cache设计@TimYang.pdf新浪微博Cache设计@Tim

张兆坤 9959

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

上一篇: OpenFire简介
下一篇: IaaS, PaaS和SaaS公司都做些什么
dodott
博客等级 码龄22年 60粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值