当前位置: 首页 > news >正文

通用点赞设计思路

点赞作为一个高频率的操作,如果每次操作都读写数据库会增加数据库的压力,所以采用缓存+定时任务来实现。点赞数据是在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.点赞接口实现 这里使用策略设计模式来实现,方便以后的扩展,对这个设计模式不了解的请点击

juejin.im/post/5bdc1e…

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

4.改进点

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

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

相关文章:

  • MVVM模块化架构
  • EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery
  • 随手记统一监控平台Focus设计解析
  • Centos7 系统启动docker报错 inotify add watch failed
  • 以OpenGL/ES视角介绍gfx-hal(Vulkan) Texture接口使用
  • 阿里云应用高可用服务公测发布
  • JAVA入门到精通-第57讲-SQLserver数据类型
  • 利用keepalived实现高可用nginx(修改正)
  • iPhone XS JavaScript性能飙升背后的秘密
  • Java 基础语法
  • 变频电源是什么,变频电源的基础知识的认识
  • springboot配置Druid数据源
  • 红帽高级总监谈OpenJDK的未来:Java的未来从未如此光明
  • 如何设置计算机IP地址
  • expect接收命令行传递的参数并设置为变量和打印变量的值
  • [NodeJS] 关于Buffer
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • echarts花样作死的坑
  • ES6简单总结(搭配简单的讲解和小案例)
  • HTTP中GET与POST的区别 99%的错误认识
  • JavaScript类型识别
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • js如何打印object对象
  • mac修复ab及siege安装
  • Making An Indicator With Pure CSS
  • rc-form之最单纯情况
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • Zepto.js源码学习之二
  • 彻底搞懂浏览器Event-loop
  • 初识 webpack
  • 初识MongoDB分片
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 汉诺塔算法
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 前端性能优化——回流与重绘
  • 新版博客前端前瞻
  • # Panda3d 碰撞检测系统介绍
  • #define,static,const,三种常量的区别
  • #大学#套接字
  • (39)STM32——FLASH闪存
  • (c语言)strcpy函数用法
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (一)VirtualBox安装增强功能
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET Core中的去虚
  • .NET 中 GetProcess 相关方法的性能
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .Net6使用WebSocket与前端进行通信
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • .NET学习全景图
  • ::前边啥也没有