小抖音社交关系实现方案 | 青训营笔记

364 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天

介绍

redis

Redis是一个开源的、高性能的key-value数据库,支持多种数据结构,包括字符串、哈希、列表等

  • 支持网络,基于内存,可选持久化
  • 可以用于缓存、事件发布或订阅、高速队列等场景
  • 完全开源免费,遵守BSD协议

MySQL

MySQL是一个开源的关系型数据库管理系统,由瑞典MySQL AB公司开发,后被Sun公司收购,Sun公司后来又被Oracle公司收购。

MySQL在过去由于性能高、成本低、可靠性好,已经成为最流行的开源数据库

技术选型

使用redis存储各个社交关系 通用解决方案是使用set来实现,关注和被关注,好友关系等 基于小抖音的应用场景需要分析以下几点

  • 快速判断二者是否为互相关注(set求交集)
  • 分页查询关注列表和粉丝列表(我又觉的list更优)

可以明显看到,当展示粉丝列表时,可以快速获取与他是否是共同关注,我觉得使用,对集合等操作性能很优秀的set数据结构可以完美承担。

但考虑到分页获取的问题,因为set是无序的,使用zset一方面可以保证可以有序根据交互活跃度或关注时间等因素排序且可以分页获取数据。且zet内部使用压缩列表加跳表,查找性能也十分优异,完美符合要求

具体实现方案

使用zset存储每个用户的关系数量,排序属性根据关注时间判定。

查找关注列表

根据用户id来查找分页数据,每一次分页中遍历当前页数据,拿取关注人的id,反向查取是否互相关注(怎么感觉还是不太优雅)。

共同好友获取

zset求交集,但是在大数据量下交集的计算量略显有点大,redis需要进行主从设计。

查询粉丝列表

这个功能好像不太好使用zset做,所以使用list来存储数据。list去存储粉丝列表(与关注列表分开存储,但放入同一redis事务进行),因为粉丝列表不需要进行集合计算,而且list有序,list结构存储更优。

使用事务而不使用多线程的原因。这两个信息一定是要同时成功,同时失败的。使用多线程无法保证这个问题。

另外问题,为什么在上述“查找关注列表中”不使用粉丝列表反向查询:考虑到二者数量级的关系,故查询互相关注还是需要用zset查询。

在思考的问题

持久化的时机,以及完全运用redis还是redis和mysql结合。

参考链接

[1] Redis是什么?看这一篇就够了

[2] Redis 简介 | 菜鸟教程 (runoob.com)

[3] Redis有什么作用_Redis是什么-华为云 (huaweicloud.com)

[4] Redis_百度百科 (baidu.com)

[5] Redis 简介

[6] Redis是什么?看这一篇就够了 - 葡萄城技术团队 - 博客园 (cnblogs.com)

[6] MySQL - 维基百科,自由的百科全书 (wikipedia.org)