背景
内容点赞业务在得物社区中是一个非常高频的业务场景,功能本身复杂度不高,但是业务场景多、QPS高、而且由于社区的用户体量,整体点赞的数据量非常大。其中最核心、对响应性能要求最高的主要是“ 用户是否点赞内容 ”和“ 内容点赞数 ”场景。
在得物社区中凡是有内容消费的场景,都会有上面两个点赞场景的处理,所以整体点赞业务的QPS在社区都是非常高的。
当我们在刷各种Feed流时,每一次下滑,都需要对数十篇内容进行登录用户是否点赞状态的判断。
作为基础业务,内容点赞业务的高性能响应,对上游内容场景的消费体验有极大的影响。
本文对得物社区的点赞业务如何做到高性能响应以及历史上在缓存使用上关于高性能、稳定性、低成本上的优化探索过程进行讲述,希望能给读者带来一些收获。
v1.0版本
功能需求
社区各种Feed流及内容详情页“登录用户是否已点赞内容” “内容被赞总数” “内容最新点赞用户列表”几个场景消费展示。
实现方案
点赞业务整体的高性能是基于Redis+MySQL架构。MySQL做数据存储和查询支持,Redis撑起业务的高性能响应。
在1.0版本中,服务架构还是单体PHP服务,技术方案上将动态下所有的点赞用户查询出来放到PHP数组里,然后序列化为Json字符串以Key/Value的方式存储到Redis中,当用户浏览内容时,取出缓存数据,反序列化Json为PHP数组,然后通过in_array和count方法判断是否已点赞及内容点赞数。
在缓存的维护上,则是每一次有新用户点赞或取消赞则直接清除Redis。
缓存结构如下:
cId => '[uid1,uid2,uid3...]'
流程图如下:
主要问题
这个版本的方案存在比较多待优化点。
第一、缓存构造时要查询动态下所有点赞用户数据,数据量大,容易产生慢SQL,对DB和带宽都可能有比较大的压力。
第二、缓存存储数据结构上为Key/Value结构,每次使用时需先从Redis查询,再反序列化成PHP数组,in_array()和count()方法都有比较大的开销,尤其是查询热门动态时,对服务器的CPU和MEM资源都有一定浪费,对Redis也产生了比较大的网络带宽开销。
第三、缓存维护上