高访问量UGC系统设计总结

来源:互联网 发布:mac 终端显示文件路径 编辑:程序博客网 时间:2024/04/29 16:57

总结下来,一般UGC系统的设计方针就是通过降低系统次要环节的实时一致性,在合理的成本范围内,尽量提高系统响应性能,而提高响应性能的手段归根结底就是三板斧:队列(Queue)、缓存(Cache)和分区(Sharding)。

  • 队列:可以缓解并发写操作的压力,提高系统伸缩性,同时也是异步化系统的最常见实现手段。
  • 缓存:从文件系统到数据库再到内存的各级缓存模块,解决了数据就近读取的需求。
  • 分区:保证了系统规模扩张和长期数据积累时,频繁操作的数据集规模在合理范围。

关于数据库,区分冷热数据,按照读写操作规律合理拆分存储,一般UGC系统近期数据才是热点,历史数据是冷数据。

  • 区分索引和实体数据,索引数据是Key,易变,一般用于筛选和定位,要保证充分的拆分存储,极端情况下要把关系数据库当NoSQL用;实体数据是Value,一般是正文文本,通常不变,一般业务下只按主键查询;两者要分开。
  • 区分核心业务和附加业务数据,每一项附加的新业务数据都单独存储,与核心业务数据表分开,既可降低核心业务数据库的变更成本,还可避免新业务频繁调整上下线时影响核心业务。

目前的互联网系统大都严重依赖MySQL的Replication主从同步来实现系统横向扩展,虽然MySQL在新版本中陆续加入RBR复制和半同步等机制,但从库的单线程写操作限制还是最大的制约因素,到现在还没有看到很理想的革新性解决方案。

关于缓存,从浏览器到文件系统很多环节都有涉及,这里主要说的是应用系统自己的部分。

  • 最好的缓存方案是不用缓存,缓存带来的问题往往多于它解决的问题。
  • 只有一次更新多次读取的数据才有必要缓存,个性化的冷数据没必要缓存。
  • 缓存分为主动(Server推)和被动(Client拉)两种更新方式,各自适用于不用场景。主动更新方式一般适用于更新频率较高的热数据,可保证缓存未命中时,失控的用户行为不会引发系统连锁反应,导致雪崩。被动更新方式一般适用于更新频率相对较低的数据,也可以通过上文提到的异步更新模式,避免连锁反应和雪崩。
  • 缓存的更新操作尽量设计为覆盖方式,避免偶发数据错误的累积效应。

一个UGC系统流量刚开始上涨时,初期的表面性能瓶颈一般会表现在Web Server层面,而实际上大多是数据库的原因,但经充分优化后,最终会落在文件系统或网络通信的I/O瓶颈上。直接承载用户访问冲击的前端服务器最好尽量设计为无状态模式,降低宕机重启后的修复工作量。


图10  5.0系统流程

设计方案上的主要变化有以下几点。

  • 评论帖子ID从数据库自增整数改为UUID,提交时即可确定,消除了必须等待主库写入后才能确定评论ID的瓶颈,对各个层面的缓存逻辑优化有极大帮助。
  • 重新设计数据库结构,通过充分的数据切分,保证了所有高频业务操作都可在一个有限数据量的数据表中的一次简单读取操作完成,索引和文本数据隔离存储,在数据库中实现了原4.0系统中索引模块的功能,取消了4.0系统的索引缓存层。
  • 改用内存NoSQL缓存用户频繁读取的最新10~20页数据,取消了原4.0系统文件方式的页面缓存层。
  • 系统运行环境迁移到新浪云的内部版本:新浪动态平台,设备资源富裕度有了极大改善。
  • 改为Python语言开发,不用再像4.0系统那样每次更新时都要等待半个小时的编译过程,也不用再打包几百兆的执行文件同步到几十台服务器上,而语言层面的性能损失可以忽略不计。

0 0