黑马点评项目笔记

短信登录

基于session的短信登录

  1. 发送验证码,session保存验证码。
  2. 验证验证码,session保存用户信息。
  3. 校验登录状态,判断session里是否保存用户信息。

使用ThreadLocal保存用户信息,是方便后面业务获取当前用户,避免传参和频繁从session中取对象。

基于Redis实现共享session登录

集群的session共享问题:多台tomcat不能共享session存储空间,当请求切换到不同tomcat服务器时导致数据丢失。

  1. 发送验证码,Redis保存验证码。
  2. 校验验证码,用户信息保存到Redis中,返回token给前端
  3. 前端请求首部行中携带token(请求首部中添加Authorization字段)校验登录状态,判断Redis里是否有用户信息。

验证码:key是手机号,value是string类型,验证码。

用户信息:key是token,value是Hash类型,用户。

商户查询缓存

缓存,交换数据的缓冲区,存储数据的临时地方,读写性能好。

缓存的作用,降低后端数据库负载,提高读写效率降低响应时间

添加Redis缓存

  1. 商铺请求先访问Redis,Redis命中直接返回数据。
  2. Redis未命中,查询数据库,如果数据库中存在数据,再写入Redis中,否则返回404。

缓存更新策略:

  • 内存淘汰。内存淘汰自动删除部分数据。
  • 超时剔除。给缓存增加TTL,到期自动删除缓存。
  • 主动更新。先操作数据库,再删除缓存。

一致性也就是缓存中有值时,与数据库中一致。

低一致性需求:使用Redis自带的内存淘汰机制。

高一致性需求:使用主动更新策略,并以超时剔除为兜底。

主动更新:先删缓存再写数据库、先写数据库再删缓存、先写数据库再写缓存、读写穿透、写回。

读操作:

  • 缓存命中直接返回。
  • 缓存未命中则查询数据库,并写入缓存,设置TTL。

写操作:

  • 先写数据库,再删除缓存
  • 确保数据库与缓存的操作原子性。

先删缓存再写数据库的问题?

更新操作删除缓存后还没更新数据库时,查询操作缓存未命中读数据库旧值,更新操作更新缓存,查询操作写入缓存旧值。

读写穿透:读写缓存数据库同步服务。

写回:只更新缓存,异步更新数据库。

缓存穿透

客户端请求的数据在数据库和缓存中都不存在,缓存永远无法生效,请求会打到数据库上给数据库带来压力。

常见的解决方案:缓存空对象和布隆过滤器。

缓存空对象:在查询时缓存和数据库都未没命中,在缓存中缓存空值设置TTL。在查询缓存的时候判断是否是空值(不是nil)。

布隆过滤器:所有可能请求的值存放在布隆过滤器中,请求来时先判断是否存在,不存在直接返回错误信息。

缓存雪崩

同一时间大量的缓存key同时失效或者Redis服务宕机,大量请求到达数据库带来压力。

解决方案:

  • 设置随机失效时间。
  • 缓存预热。
  • Redis集群。
  • 多级缓存。
  • 业务添加多级缓存。

缓存击穿

热点key问题,被高并发访问并且缓存重建业务复杂的key突然失效,大量请求瞬间到达数据库带来压力。

解决方案:互斥锁和逻辑过期。

互斥锁方案

查询缓存未命中获取互斥锁,查询数据库重建缓存数据,写入缓存,释放锁。其他线程查询缓存未命中获取互斥锁失败,休眠重试直到缓存命中。

逻辑过期

缓存数据中添加逻辑TTL,查询缓存发现已过期,直接返回过期数据,获取互斥锁开启新线程重建缓存,写入缓存后重置逻辑TTL释放互斥锁。其他线程查询缓存发现已过期,获取互斥锁失败返回过期数据。

优惠券秒杀

全局ID生成器

分布式系统下生成全局唯一的ID工具。

基于Redis自增策略,订单ID由Redis中整型数据4个字节64位组成,1比特为0符号位,31位时间戳,32为序列号。使用Redis整型数据自增来生成ID。

秒杀券下单

实现优惠券秒杀:

  1. 判断秒杀是否开始或者结束
  2. 库存是否充足,扣减库存,添加订单

在高并发环境下,会出现超卖的问题(在库存量为1的时候,多个线程进入判断库存充足扣减订单,超卖订单)。

悲观锁:添加互斥锁,让线程串行执行,实现简单但性能一般。

乐观锁:不加锁,在更新时判断是否有其他线程在修改,性能好但成功率低。版本号法,在更新数据之前检查版本号,更新数据时修改版本号。

// 优化乐观锁成果率低的问题,在更新时同时检查订单是否大于0
seckillVoucherService.update()
                .setSql("stock = stock - 1")
                .eq("voucher_id", voucherId)
                .gt("stock", 0)
                .update();

一人一单

在更新前判断数据库订单表中是否相同用户相同秒杀券的记录,由于没有加锁同样会出现超卖的问题。

由于不存在数据更新,所以无法使用乐观锁,使用悲观锁synchronized给创建订单上锁。

一人一单的并发安全问题:在集群模式下,同一个用户在不同服务器上的请求会获取不同的锁(不同的JVM,不同的锁监视器),会超单。

分布式锁

满足分布式系统或集群模式下多进程可见并且互斥的锁。

基于Redis分布式锁

版本1:基于Redis的setnx命令实现分布式锁,设置TTL超时自动释放锁。

版本1的问题:线程1业务阻塞,锁TTL超时释放,线程2获取锁执行业务中,线程1执行完任务释放线程2的锁。

版本2:获取锁时存入线程标识(UUID+线程ID,不能只使用线程ID,不同JVM线程ID可能相同),释放锁时核对线程标识。

版本2的问题:线程1判断锁标识和释放锁之间阻塞,锁TTL超时释放,线程2获取锁执行业务前,线程1阻塞结束后释放锁。

版本3:使用Luna脚本完成判断线程标识和锁释放的原子性。

总结:基于Redis的分布式锁实现思路,利用setnx获取锁设置过期时间,保存线程标识。释放锁先判断线程标识是否一致,一致释放锁

基于Redis分布式锁优化

基于setnx实现的分布式锁存在的问题:

  1. 不可重入。同一个线程无法多次获取同一把锁。
  2. 不可重试。获取锁尝试一次就返回。
  3. 超时释放。如果业务执行时间耗时长,导致锁提前释放。
  4. 主从一致性。Redis采用主从集群结构, 主节点宕机且锁数据未同步给从节点,导致锁失效。

Redisson分布式锁工具。

可重入锁的原理:利用Hash结构记录线程标识和重入次数。

可重试的原理:利用pubsub机制,订阅锁释放的信号尝试获取锁。

锁不过期的原理:开启watchdog定时更新TTL。

主从一致性的原理:联锁,每台Redis服务器独立,获取锁时需要半数以上的每台服务器都获取锁。

秒杀优化

业务流程:

  1. 查询优惠券,判断秒杀库存。读数据库。
  2. 查询订单, 判断一人一单。读数据库。
  3. 更新库存。写数据库。
  4. 创建订单。写数据库。

优化方式,同步下单变成异步下单,读写数据库分离。利用Redis完成库存余量、一人一单判断,完成抢单业务。再将下单业务放入阻塞队列,利用独立线程异步下单。

基于阻塞队列的异步秒杀问题:内存限制,阻塞队列使用JVM内存,高并发情况下大量订单占用JVM内存。数据安全问题,服务重启或者宕机,阻塞队列数据丢失。

基于Redis的消息队列实现异步秒杀
  • 基于List双向链表实现。LPUSH和BRPOP阻塞获取。只支持单消费者,无法避免消息丢失
  • 基于PubSub实现。发布消息,订阅频道。不支持数据持久化,无法避免消息丢失
  • 基于Stream实现。多个消费者划分到一个消费者组,监听同一个队列。

Stream消费者组消息队列的特点:

  • 消息分流。同一个消费者组的消费者之间竞争消息。
  • 消息标识。消费者组维护一个标识,最后一个被处理的消息。
  • 消息确认。消费者获取消息后,消息处于pending状态,在pending-list中,当消息处理返回ack确定后才会从list中移除。

秒杀优化券方案总结:利用lua脚本完成库存余量、一人一单判断,完成抢单业务。将下单信息放到消息队列,开启独立线程异步下单,扣减库存使用乐观锁。

达人探店

点赞

在Redis中记录以blogid为key,点赞用户为value的集合。

点赞排行榜:使用SortedSet,点赞时带时间为score。

好友关注

关注

user_idfans_id多对多关系表中添加。

共同关注

为每个用户在redis添加一个关注集合set,求两个集合的交集。

关注推送

Feed流,无限下拉刷新获取新消息。

  • 拉模式:用户从关注邮箱中拉去消息。读,延迟高。
  • 推模式:发布消息到用户的邮箱中。写,延迟低。
  • 推拉结合:粉丝多的采用拉,粉丝少的采用推。

基于推模式实现关注推送:blog保存到数据库的同时,推送到粉丝的邮件箱,收件箱使用Redis的SortedSet满足时间戳排序,查询收件箱数据时实现分页查询(滚动式分页,数据不断变化,数据的角标也在变化。维护上一次最小的时间戳和偏移量)。

附近商户

Redis GEO结构存储地理位置信息。

根据商铺类型分组,typeid作为key存入同一个GEO集合中,成员是店铺ID。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607136.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习经验分享【36】论文投稿写作(非理工科文章)

业务进一步扩展,可辅导非理工科偏文科性质的论文辅导,有需要评职称但没有时间精力研究的或者其他相关需求的朋友可咨询了解。 人工智能技术在各领域的发展和思考,类似这种主题的文章。

压缩和归档库-LZ4介绍

1.简介 LZ4是一种快速的压缩算法,提供压缩和解压缩的速度,而牺牲了压缩率。它被设计用于快速的数据压缩和解压缩,特别是用于数据存储和传输。LZ4通常用于需要高速数据处理的场景,如数据库、日志文件处理和实时数据传输。 LZ4的特…

进一步分析并彻底解决 Flink container exit 143 问题

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益: 了解大厂经验拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我! 文章目录 一…

腾讯游戏海外扩张,增持芬兰游戏开发商股份持股比例增至14.8%

易采游戏网5月8日消息,近日腾讯再次出手,大幅增持了芬兰知名游戏开发商Remedy Entertainment的股份,持股比例猛增至14.8%。这一举动引起了业界和投资者的广泛关注。 据了解,腾讯此次增持是在2024年4月24日完成的。根据芬兰法律规…

Linux网络-PXE高效批量网络装机(命令+截图详细版)

目录 一.部署PXE远程安装服务 1.PXE概述 1.1.PXE批量部署的优点 1.2.要搭建PXE网络体系的前提条件 2.搭建PXE远程安装服务器 2.1.修改相关网络配置(仅主机模式) 2.2.关闭防火墙(老规矩) 2.3.保证挂载上 2.4.准备好配置文…

<网络安全>《76 概念讲解<第十课 物联网常用协议-网络层协议>》

协议简称全称名称内容说明IPv4互联网通信协议第四版IPv4是互联网的核心IPv6互联网协议第6版TCPTransmission Control Protocol传输控制协议TCP旨在适应支持多网络应用的分层协议层次结构。连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务…

【Python】什么是皮尔森系数

我不完美的梦 你陪着我想 不完美的勇气 你说更勇敢 不完美的泪 你笑着擦干 不完美的歌 你都会唱 我不完美心事 你全放在心上 这不完美的我 你总当做宝贝 你给我的爱也许不完美 但却最美 🎵 周冬雨《不完美女孩》 皮尔森相关系数(Pe…

FinalShell连接虚拟机Linux系统连接超时

报错信息 java.net.ConnectException: Connection timed out: connect 排除是网络问题后可以尝试一下这个方法。 解决方案: 打开虚拟机终端输入:ifconfig 会出现端口信息: 看ens33这里的端口是多少,改一下重新连接就ok。

springboot+vue实现登录注册,短信注册以及微信扫描登录

说明:微信扫描登录需要微信注册--要钱,感谢尚硅谷提供的免费接口;短信注册需要阿里云的注册很麻烦并且短信费,没有接口,所以不打算实现,不过能做出效果。 目录 一、建立数据库 二、后端idea实现接口 1.…

幻兽帕鲁专用服务器怎样买省钱便宜?一个月30元

在数字娱乐的浪潮中,幻兽帕鲁Palworld以其独特的魅力吸引了无数玩家的目光。想要拥有流畅、稳定的游戏体验,一台专属的游戏服务器是必不可少的。而如何以最经济的价格购买到高品质的服务器,正是玩家们最关心的问题。腾讯云服务器性价比是很高…

每日Attention学习6——Context Aggregation Module

模块出处 [link] [code] [IJCAI 22] Boundary-Guided Camouflaged Object Detection 模块名称 Context Aggregation Module (CAM) 模块作用 增大感受野,全局特征提取 模块结构 模块代码 import torch import torch.nn as nn import torch.nn.functional as Fcla…

Anaconda安装和深度学习环境的安装(TensorFlow、Pytorch)

换了新电脑,重新装一下anaconda这些编程环境。好久没装过了,自己也需要查查资料,然后记录一下,分享给别人。 目标,三个环境:1.anaconda基础环境(包含xgboost和lightgbm)&#xff0c…

卫星通信现状与展望三 -- 分类总结及6G应用

作者:私语茶馆 卫星通信分类总结及6G应用 一、卫星轨道类型 卫星按照轨道距离地面的距离主要分为以下几种: 卫星轨道类型 卫星用途 轨道高度 VLEO(Very Low Earth Orbit) 对地观测、通信

Python中使用tkinter模块和类结构的结合使用举例——编写制作一个简单的加数GUI界面

Python中使用tkinter模块和类结构的结合使用举例——编写制作一个简单的加数GUI界面 这里写目录标题 Python中使用tkinter模块和类结构的结合使用举例——编写制作一个简单的加数GUI界面一、tkinter模块和类的简述1.1 tkinter的简要介绍1.2 类结构的简要介绍 二、基于类机构和t…

成本降低 90%,出海社交平台 Typing 基于 Databend 的大数据探

Typing(输入中科技)成立于 2022 年,是一家主要面向东南亚、拉美、中东等海外地区提供社交平台的出海企业。其社交平台类似于国内的 Soul、陌陌等,提供视频直播、语音聊天室、短视频、生活分享、文字聊天等社交功能,注册…

【C++】零钱兑换的始端---柠檬水找零

欢迎来CILMY23的博客 本篇主题为 零钱兑换的始端---柠檬水找零 个人主页:CILMY23-CSDN博客 个人专栏系列: Python | C | C语言 | 数据结构与算法 感谢观看,支持的可以给个一键三连,点赞关注收藏。 前言: 柠檬水找…

2024年最新【SpringBoot2】开发实用篇-测试_springboot2 test(1),2024年最新2024春招BAT面试真题详解

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化! 由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、…

吸血鬼崛起v rising皮革获取教程 v rising皮革机怎么获得

《V Rising》是一款由Stunlock Studios公司制作并发行的生存建造类游戏,以“吸血鬼”为题材。中文名为“吸血鬼崛起”。在游戏中,打boss可以获得许多掉落材料,有些材料需要合成,而制作皮革则需要使用皮革机。下面就为大家介绍一下…

利用大语言模型(KIMI)生成OPC UA 信息模型

在大语言模型没有出现之前,人们更倾向使用图形化工具或者基于窗口的软件来构建信息模型,图形化工具能够直观地表达信息模型中各元素之间的相互关系。但是图形化工具也有缺点,当描述一个复杂的信息模型时,图形会变得非常复杂和庞大…

如何通过OMS加快大表迁移至OceanBase

OMS,是OceanBase官方推出的数据迁移工具,能够满足众多数据迁移场景的需求,现已成为众多用户进行数据迁移同步的重要工具。OMS不仅支持多种数据源,还具备全量迁移、增量同步、数据校验等功能,并能够对分表进行聚合操作&…
最新文章