通用点赞设计思路

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 点赞作为一个高频率的操作,如果每次操作都读写数据库会增加数据库的压力,所以采用缓存+定时任务来实现。点赞数据是在redis中缓存半小时,同时定时任务是每隔5分钟执行一次,做持久化存储,这里的缓存时间和任务执行时间可根据项目情况而定。

点赞作为一个高频率的操作,如果每次操作都读写数据库会增加数据库的压力,所以采用缓存+定时任务来实现。点赞数据是在redis中缓存半小时,同时定时任务是每隔5分钟执行一次,做持久化存储,这里的缓存时间和任务执行时间可根据项目情况而定。

优点

1.降低对数据库的影响
2.提高点赞的效率

缺点

1.如果任务挂了,会丢失点赞数据
2.持久化存储不是实时的

时序图

在这里插入图片描述

数据库设计

create table user_like(
id bigint(20) unsigned not null auto_increment comment 'id',
user_id bigint(20) not null default 0 comment '用户id',
liked_id varchar(21) not null default '' comment '被点赞的id',
liked_status int(11) not null default 0 comment '点赞状态,0未点赞,1已点赞',
liked_type int(11) not null default 0 comment '点赞的类型',
liked_time timestamp not null default '0000-00-00 00:00:00.000000' comment '点赞时间',
 is_delete tinyint not null default '0' comment '是否逻辑删除',
 create_time timestamp not null default CURRENT_TIMESTAMP comment '创建时间',
 update_time timestamp not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '更新时间',
 primary key (id),
 unique uniq_user_id_liked_id_type(user_id,liked_id,liked_type),
 key idx_liked_id (liked_id),
 key idx_create_time (create_time),
 key idx_update_time (update_time)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='用户点赞表';

create table user_like_stat(
id bigint(20) unsigned not null auto_increment comment 'id',
liked_id varchar(21) not null default '' comment '被点赞id',
liked_count int(11) not null default 0 comment '点赞总数量',
 is_delete tinyint not null default '0' comment '是否逻辑删除',
 create_time timestamp not null default CURRENT_TIMESTAMP comment '创建时间',
 update_time timestamp not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '更新时间',
 primary key (id),
 unique uniq_info_num(liked_id),
 key idx_create_time (create_time),
 key idx_update_time (update_time)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='点赞统计表';

实现步骤

1.设计缓存数据格式

整个点赞模块主要采用缓存来完成,所以要选择合适数据结构,我选择hash数据结构来实现,应为它可以添加、获取、移除单个键值对,并且可以获取所有键值对。主要缓存两种数据,一种是用户的点赞状态,一种是被点赞id的点赞数量。这两种数据分别用两个key存储,这两个key中都是存储的多个键值对。键值对格式如下:

用户的点赞状态key-value------>{"被点赞的id::用户id" :"点赞状态::点赞时间::点赞类型"}

被点赞id的点赞数量key-value------>{"被点赞id" : "点赞数量"}

2.大key拆分

点赞的数据量比较大的情况下,上面的设计会造成单个key存储的value很大,由于redis是单线程运行,如果一次操作的value很大,会对整个redis的响应时间有影响,所以我们这里在将上面的两个key做拆分。固定key的数量,每次存取时都先在本地计算出落在了哪个key上,这个操作就类似于redis分区、分片。有利于降低单次操作的压力,将压力平分到多个key上。

//点赞状态key拆分
newHashKey  =  hashKey +"_"+ (userId% 5);   
hset (newHashKey, field, value) ;  
hget(newHashKey, field)


//点赞数量key拆分
newHashKey  =  hashKey +"_"+ Math.abs((hash*(被点赞id)) % 5);   
hset (newHashKey, field, value) ;  
hget(newHashKey, field)

3.代码实现

以下值截取了部分代码,提供思路。

1.点赞状态枚举
在这里插入图片描述
2.点赞类型枚举
在这里插入图片描述
3.用户点赞类
在这里插入图片描述
4.点赞接口实现
这里使用策略设计模式来实现,方便以后的扩展,对这个设计模式不了解的请点击

https://juejin.im/post/6844903703653138445

这里进行策略的选择在这里插入图片描述在这里插入图片描述
5.逻辑
取消点赞和这个接口相同,只需要替换下点赞状态和redis增量
在这里插入图片描述
6.定时任务
定时任务采用Azkaban任务调度系统,每个5分种运行一次任务,把点赞数据从redis缓存中取出做持久化到mysql。

4.改进点

现在的读取都是用的一个key,接下来可以优化为把key做读写分离。写入和读取分别用不同的key,这样做可以减少资源的浪费,要不每次跑定时任务都会把已经持久化并且缓存未失效的数据拿出来做一遍查询。

以上就是点赞的一个实现思路,大家有什么更好的方法或者改进的点,欢迎提出来。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
9月前
|
算法 Java 编译器
C++ | 深入浅出类的封装思想【图文案例,通俗易懂】-1
C++ | 深入浅出类的封装思想【图文案例,通俗易懂】
249 3
|
9月前
|
算法 Java 编译器
C++ | 深入浅出类的封装思想【图文案例,通俗易懂】-3
C++ | 深入浅出类的封装思想【图文案例,通俗易懂】
52 0
|
存储 缓存 监控
一文读懂分布式架构知识体系(内含超全核心知识大图)
7月9日 19:00-21:30 阿里云开发者社区首场“Offer 5000”直播开启!15位团队技术大牛在线招人,更有《阿里云技术面试红宝书》助你拿下Offer!马上投递简历:https://developer.aliyun.com/special/offerday01
15487 0
|
10天前
|
SQL 安全 PHP
深入浅出PHP编程:从基础到实战
在数字化时代的浪潮中,掌握PHP编程技能成为许多开发者的必修课。本文旨在通过浅显易懂的语言,带领读者走进PHP的世界,不仅介绍PHP的基础语法和核心概念,还将通过实际案例,展示如何将理论知识应用到项目开发中。无论你是编程新手还是希望深化PHP技能的开发者,这篇文章都将为你提供有价值的指导和灵感。让我们一起探索PHP的魅力,开启编程之旅吧!
|
9月前
|
存储 编译器 程序员
C++ | 深入浅出类的封装思想【图文案例,通俗易懂】-2
C++ | 深入浅出类的封装思想【图文案例,通俗易懂】
193 0
|
3月前
|
SQL 存储 NoSQL
数据库原理速览:核心知识集萃与复习指南
数据库原理速览:核心知识集萃与复习指南
39 2
|
11月前
|
机器学习/深度学习 人工智能 算法
这篇科普让你Get所有大模型的基础核心知识点
本文介绍了AI大模型的概念和发展历程。AI大模型是指具有1亿以上参数的机器学习模型,通过在大规模数据集上进行预训练,可以直接支撑各类应用。大模型的发展经历了从萌芽期到AI1.0时期,再到AI2.0时期的飞跃,目前最新发布的大模型参数已经达到了千亿甚至万亿级别。国内外的公司都在积极研发和应用大模型,如OpenAI、Google、Facebook、Microsoft等。国内也有百度、阿里巴巴、万维、商汤科技等公司发布了自己的大模型产品。大模型的建造离不开算力资源、算法人才、数据积累等核心要素。此外,文章还列举了一些与大模型相关的专业名词,如算法、模型参数、训练数据、Token等。
|
消息中间件 设计模式 缓存
怎样更好地阅读源码?
最近,为了提高团队成员技术水平,考察了大家源码阅读情况。作为第一期任务,选择了spring框架,范围是spring-beans,spring-context,spring-core,以及spring-web。考核方式为:了解spring框架作用、核心概念,并选择感觉最重要的几个类进行详细阐述。
95 0
|
存储 JSON JavaScript
深入浅出JavaScript继承方案
大家好,我是CoderBin,想必绝大部分人一说继承就会想到类中的继承吧,但其实继承可不是 class 的专利,本文将总结📕 JavaScript 中关于继承的几种方案,其中包括原型链,盗用构造函数、组合式等等,助你力压面试官💪。
98 1
深入浅出JavaScript继承方案
|
网络协议 Java
网络编程(基础案例+速览复习)
网络编程实例 导读 Java中怎样实现网络编程:通过java.net包中 ServerSocket 和Socket这个两个核心类
110 0
网络编程(基础案例+速览复习)