redis知识复习

redis知识复习

  • redis基础知识
    • 一. redis的认识
      • 1. 非关系型数据库 与 传统数据库 的区别
      • 2. 安装redis并设置自启动
      • 3. 熟悉命令行客户端
      • 4. 熟悉图形化工具RDM
    • 二. redis的命令与数据结构
      • 1. 数据结构介绍
      • 2. redis通用命令(熟练掌握)
    • 三. redis的Java客户端
      • 1. Jedis
      • 2. SpringDataRedis
      • 3. ==StringRedisTemplate(推荐)==
  • redis应用(未完结...)
    • 四. 处理登录验证
      • 1. 设计登录拦截
    • 五. 处理热点数据的查询工作
      • 1. 处理缓存穿透
      • 2. 处理缓存雪崩
      • 3. 处理缓存击穿
    • 六. 处理秒杀任务(优惠券)
      • 1. 处理优惠券全局ID的生成唯一性
      • 2. 优惠券秒杀流程(抢优惠券)
        • 2.1 单体模式下的优惠券秒杀流程
        • 2.2 集群环境下的优惠券秒杀流程(setnx分布式锁)
    • 七. ==redis分布式锁——Redisson(重要掌握)==
      • 1. 快速入门
      • 2. Redisson的重要原理
        • 2.1 可重入锁原理
        • 2.2 可重试锁,

redis基础知识

一. redis的认识

1. 非关系型数据库 与 传统数据库 的区别

背会这张表就行了

2. 安装redis并设置自启动

  1. 在Linux环境下 安装redis依赖

    yum install -y gcc tcl
    
  2. (/usr/local/src目录下) 下载对应的redis安装包(本次为v6.2.6,如果有之前下载过的redis,记得提前删除干净,以防配置环境等因素造成安装的异常)

    wget https://download.redis.io/releases/redis-6.2.6.tar.gz
    
  3. 解压压缩包获得 redis程序安装包

    tar -xvf redis-6.2.6.tar.gz
    
  4. 在该程序包目录下执行 编译安装命令(默认该步骤会将redis软件安装到/usr/local/bin目录下)

    make && make install
    
  5. 执行redis服务命令 即可启动redis,该方式为前台启动方式(不友好,不推荐使用)

    redis-server 
    
  6. 修改配置文件,完成指定配置下的启动准备(记得对redis.conf做备份,以防修改失误)

    cp redis.conf redis.conf.bck
    vi redis.conf
    

    添加任意进程可访问 守护进程开启 开启密码 日志记录

    # 文本内部的修改(供复制粘贴)
    
    # 任意ip可访问
    bind 0.0.0.0 
    # 守护进程打开,可后台运行
    daemonize yes
    # 密码设置123321
    requirepass 123321
    # 打开日志记录,并命名
    logfile "redis.log"
    
  7. 根据指令,完成指定配置文件下的启动

    redis-server redis.conf
    
  8. 查看redis进程命令,以及杀死进程命令

    ps -ef | grep redis
    
    kill -9 PID(PID为对应的进程序列号)
    
  9. 开机自启动(在 system系统文件夹中 新建一个配置类文件)

    vi /etc/systemd/system/redis.service
    

    配置类文件内容如下:

    [Unit]
    Description=redis-server
    After=network.target
    
    [Service]
    Type=forking
    # 这行配置内容要根据redis的安装目录自定义路径
    ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
    PrivateTmp=true
    
    [Install]
    WantedBy=multi-user.target
    

    重载系统服务,以便配置文件生效

    systemctl daemon-reload
    

    此时可以使用系统命令实现redis的启动、查看状态或关闭

    systemctl start redis
    
    systemctl status redis
    
    systemctl stop redis
    

    执行下面的命令,实现开机自启:

    systemctl enable redis
    

    查看此时,redis 服务的状态:

    systemctl status redis
    

3. 熟悉命令行客户端

  1. 在/usr/local/bin/目录下,使用redis-cli实现连通redis

    redis-cli -h 192.168.2.190 -p 6379 -a 123321
    
    >ping
    
  2. 存取数据set/get,换库select [index]

    set/get/select命令的输入

4. 熟悉图形化工具RDM

RDM工具

二. redis的命令与数据结构

1. 数据结构介绍

常用数据结构

2. redis通用命令(熟练掌握)

# keys:查看所有key
keys * 
# set:设置添加k-v  mset:批量添加
set k1 v1
mset k1 v1 k2 v2 k3 v3
# del:删除
del k1
# exist 查看是否存在
exist k1
# expire:设置有效期时间,单位s,没有特殊设置则为-1表示永久有效
expire k1 20
# ttl:查看有效期剩余时间(-1表示永久,-2表示过期,正数表示剩余秒数)
ttl k1

String类型(可存string,int,float)
String类型常用命令
redis的key的格式:

层级存储:[项目名]:[业务名]:[类型]:[id],这种存储的方式,有一个好处,那就是在使用gui图形界面能看到层级结构

Hash类型

Hash类型存储结构Hash类型数据常用命令
List类型(对比Java的双向链表)
List类型存储结构List类型常用命令
list的总结:可以广泛模拟 栈(同一个方向先进后出) 队列(不同方向进出) 阻塞队列(一头取,一头放,需要设置等待时间)

Set类型(对比Java的hashset,相当于底层使用hashmap实现)
Set类型数据结构
Set类型常用命令
SortedSet类型(功能上类似TreeSet,底层数据结构不同)
SortedSet类型存储数据结构SortedSet类型常用命令

三. redis的Java客户端

1. Jedis

单例使用流程

单例使用redis

测试

Jedis连接池用法

Jedis连接池使用redis

创建连接池对象,设置参数,完成连接池的创建,在使用过程中,与上述直接创建连接不同的是直接从连接池中获取一个连接,其他基本一致

// jedis = new Jedis("192.168.2.190",6379);
jedis = JedisConnectionFactory.getJedis(); //直接从连接池中获取一个

2. SpringDataRedis

SpringRedisTemplate
操作
使用流程(写pom,写yml,写测试用例,完成测试)

  1. 创建项目,引入依赖
    依赖2. 完成配置文件的设置 yml文件3. 注入装配,实施测试 装配测试
    redisTemplate的序列化操作存在的问题
    序列化造成的数据不可读
    基于可读性差的因素,可以自定义序列化方式,规避序列化造成的可读性问题

  2. 加依赖

<!--jackson序列化工具-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
  1. 自定义序列化方式(最好能理解!实际上由于该方式进行反序列化的必要操作时,会必定携带@class信息,造成占用内存产生大量冗余,并不推荐使用,后续会使用StringRedisTemplate操作key,value则手动进行序列化与反序列化操作)
/**
 * redis反序列化自定义操作工具类
 */

@Configuration
public class RedisConfig {
    /**
     * @param redisConnectionFactory 引入工厂
     * @return 返回经过处理的redisTemplate模板
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        // 创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(redisConnectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // 设置key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashKeySerializer(jsonRedisSerializer);
        // 返回RedisTemplate对象
        return template;
    }
}

3. StringRedisTemplate(推荐)

(基于内存占用问题,使用StringRedisTemplate来改善内存问题,StringRedisTemplate操作key,value则手动进行序列化与反序列化操作)
SDR
RedisTemplate与StringRedisTemplate处理后两者存取的数据对比:
对比对比1

redis应用(未完结…)

四. 处理登录验证

1. 设计登录拦截

在这里插入图片描述

五. 处理热点数据的查询工作

1. 处理缓存穿透

缓存穿透:浏览器不断发送未命中的请求,redis一直未命中,一直查询数据库,给数据库造成很大压力
穿透
实例:用户查询一个热点商铺/商品/文章信息,信息不存在,持续访问造成数据库压力
解决方案:
安排

2. 处理缓存雪崩

在这里插入图片描述
实例:用户分时段查询多个热点商铺/商品/文章信息,结果在某个时间节点该信息全部失效,导致该时间节点需要大量访问数据库造成数据库压力

解决方案:给redis中的缓存数据设置不同的TTL

3. 处理缓存击穿

实例:多名用户在一个定时活动的时间节点访问某个热点商铺/商品/文章信息,结果造成缓存失效,结果造成访问数据库造成数据库的压力过大

  1. 使用互斥锁处理缓存击穿
    在这里插入图片描述
  2. 使用【逻辑过期时间】处理缓存击穿
    在这里插入图片描述

六. 处理秒杀任务(优惠券)

1. 处理优惠券全局ID的生成唯一性

全局ID
ID生成类

@Component
public class RedisIdWorker {
    //开始时间戳
    private static final long BEGIN_TIMESTAMP = 1674086400L;

    //序列号位数
    private static final int COUNT_BITS = 32;

    private StringRedisTemplate stringRedisTemplate;

    public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public long nextId(String keyPrefix){
        //1.生成时间戳
        LocalDateTime time = LocalDateTime.now();
        long nowSecond = time.toEpochSecond(ZoneOffset.UTC);
        long timestamp = nowSecond - BEGIN_TIMESTAMP;
        //2.生成序列号,redis自增长,redis单个key自增长有上限,2的64次方
        //2.1获取当前日期,精确到天
        String date = time.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);
        //3.拼接并返回,不能使用字符串方式拼接
        return timestamp << COUNT_BITS | count;//先向左移32位,那么低32位全为0,跟序列号进行或操作
    }
    /**
     * 生成开始时间戳
     * @param args
     */
    public static void main(String[] args) {
        LocalDateTime time = LocalDateTime.of(2023, 1, 19, 0, 0, 0);
        long second = time.toEpochSecond(ZoneOffset.UTC);
        System.out.println(second);
    }
}

其他方案:
在这里插入图片描述

2. 优惠券秒杀流程(抢优惠券)

2.1 单体模式下的优惠券秒杀流程

在这里插入图片描述

2.2 集群环境下的优惠券秒杀流程(setnx分布式锁)

(在集群模式下,加锁只是该台jvm给当前这台服务器处理的请求加锁,而集群是多台服务器轮询处理请求,会造成每台服务器都有一个加锁的线程,每台服务器都会有一个新订单创建处理)
在这里插入图片描述
在这里插入图片描述
解决原子性问题,造成的锁无法及时释放的Lua脚本代码

-- 这里的 KEYS[1] 就是锁的 key,这里的 ARGV[1] 就是当前线程标识
-- 获取锁中的线程标识 get key
local id = redis.call('get', KEYS[1]);
-- 比较线程标识与锁中的标识是否一致
if (id == ARGV[1]) then
    -- 释放锁 del key
    return redis.call('del', KEYS[1])
end
return 0

七. redis分布式锁——Redisson(重要掌握)

上述集群的基于 setnx 实现的分布式锁存在下面的问题
1.不可重入:同一个线程无法多次获取同一把锁
2.不可重试:获取锁只尝试一次就返回 false,没有重试机制
3.超时释放:锁超时释放虽然可以避免死锁,但如果是业务执行耗时较长,也会导致锁释放,存在安全隐患
4.主从一致性:如果 Redis 提供了主从集群,主从延同步在延迟,当主机宕机时,如果从机同步主机中的数据,则会出现锁失效

Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格
它不仅提供了一系列的分布式的 Java 常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。

1. 快速入门

  1. 导依赖
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.13.6</version>
</dependency>
  1. 建Redisson类
@Configuration
public class RedisConfig {
    @Bean
    public RedissonClient redissionClient() {
        // 配置类
        Config config = new Config();

        // 添加 Redis 地址,此处添加了单点的地址,也可以使用 config.useClusterServers() 添加集群地址
        config.useSingleServer().setAddress("redis://192.168.2.12:6379").setPassword("123321");

        // 创建客户端
        return Redisson.create(config);
    }
}

  1. 测试基础使用
@Resource
private RedissonClient redissonClient;

@Test
void testRedisson() throws InterruptedException {
    // 获取锁(可重入),指定锁的名称
    RLock lock = redissonClient.getLock("anyLock");
    // 尝试获取锁,参数分别是:获取锁的最大等待时间(期间会重试过),锁自动释放时间,时间单位
    boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
    // 判断锁是否获取成功
    if (isLock) {
        try {
            System.out.println("执行业务");
        } finally {
            //释放锁
            lock.unlock();
        }
    }
}

2. Redisson的重要原理

2.1 可重入锁原理

在这里插入图片描述

2.2 可重试锁,

@Resource
private RedissonClient redissonClient;

@Test
void testRedisson() throws InterruptedException {
    // 获取锁(可重入),指定锁的名称
    RLock lock = redissonClient.getLock("anyLock");
    // 尝试获取锁,参数分别是:获取锁的最大等待时间(期间会重试过),锁自动释放时间,时间单位
    boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
    // 判断锁是否获取成功
    if (isLock) {
        try {
            System.out.println("执行业务");
        } finally {
            //释放锁
            lock.unlock();
        }
    }
}

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

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

相关文章

SpringBoot整合Flyway实现数据库的初始化和版本管理

文章目录 一、Flyway1、介绍2、业务痛点3、个人理解 二、SpringBoot整合flyway1、整合2、SQL文件命名3、版本号校验算法4、工作流程5、注意事项 一、Flyway 1、介绍 Flyway 是一款开源的数据库版本管理工具。它可以很方便的在命令行中使用&#xff0c;或者在Java应用程序中引入…

【MySQL】数据表的基本操作

目录 1. 创建表 2. 创建表案例 2.1 创建一个users表 2.2 查看表结构 2.3 修改表 3. 删除表 MySQL&#x1f337; 1. 创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校验规则 engine 存储…

chatgpt赋能python:如何升级Python的pip版本

如何升级Python的pip版本 如果你使用Python来进行程序开发&#xff0c;那么你一定需要用到pip&#xff0c;它是Python的包管理器&#xff0c;用于安装和管理各种Python库。 不过&#xff0c;一旦你开始使用pip&#xff0c;你可能会遇到一个问题&#xff1a;你的pip版本可能会…

几种技巧让大模型(ChatGPT、文心一言)帮你提高写代码效率!

代码神器 自从大模型推出来之后&#xff0c;似乎没有什么工作是大模型不能做的。特别是在文本生成、文案写作、代码提示、代码生成、代码改错等方面都表现出不错的能力。下面我将介绍运用大模型写代码的几种方式&#xff0c;帮助程序员写出更好的代码&#xff01;&#xff08;…

利用AI点亮副业变现:5个变现实操案例的启示

AI变现副业实操案例 宝宝起名服务AI科技热点号头像壁纸职业头像收徒&#xff1a;萌娃头像定制头像平台挂载 小说推广号流量营销号百家号AI共创计划公众号流量主 知识付费知识星球小报童&#xff1a; 整体思维导图&#xff1a; 在这里先分享五个实操案例: 宝宝起名服务AI科技热…

cvte 前端一面 凉经

cvte 前端一面 凉经 原文面试题地址&#xff1a;https://www.nowcoder.com/discuss/353159272857018368?sourceSSRsearch 1. vuex原理 和vuerouter的原理差不多 2. vuerouter的原理 ​ 首先在main.js中&#xff0c;import router from ‘./router’ 引入在router文件夹下面…

学习WooCommerce跨境电商社交媒体营销

WooCommerce 长期以来一直为电子商务店主提供多样化的服务。大约 500 万家商店啓用安装了免费的 WooCommerce 插件。 官方 WooCommerce 插件从 WordPress.org 下载了161,908,802次&#xff0c;并且还在增加。 超过5,106,506 个网站正在使用 WooCommerce。 本文网址: https…

一文搞懂什么是Docker

一、什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署&#xff0c;环境不一定一致&#xff0c;会遇…

LVS+Keepalived 群集

目录 一、keepalived概述 1.keepalived工作原理 2.keepalived体系主要模块及其作用 3.判断服务器主备&#xff0c;及如何配置浮动IP 二、keepalived的抢占与非抢占模式 三、部署LVSkeepalived 1.配置负载调度器&#xff08;主备相同&#xff09; 1.1配置keepalived&…

NVM安装教程

我是小荣&#xff0c;给个赞鼓励下吧&#xff01; NVM安装教程 简介 nvm 是node.js的版本管理器&#xff0c;设计为按用户安装&#xff0c;并按 shell 调用。nvm适用于任何符合 POSIX 的 shell&#xff08;sh、dash、ksh、zsh、bash&#xff09;&#xff0c;特别是在这些平台…

chatgpt赋能python:Python编程:如何删除前面的代码?

Python编程&#xff1a;如何删除前面的代码&#xff1f; 在Python编程中&#xff0c;我们有时会需要删除之前写的一些代码&#xff0c;以便更好地组织我们的代码结构和逻辑。那么&#xff0c;Python中如何删除前面的代码呢&#xff1f;在本文章中&#xff0c;我们将为您详细介…

工程训练 -江苏海洋大学-mooc-最终答案

这不点赞评论一下嘛&#xff1f;&#xff1f;&#xff1f;呜呜呜 判断题&#xff08;共217道&#xff09; 1.舂实模样周围及砂箱边或狭窄部分的型砂&#xff0c;通常采用砂舂的平头端舂砂。 2.造型时&#xff0c;分型面上通常使用的是面砂&#xff0c;覆盖模样的则使用背砂。 3…

软件测试正在面试银行的可以看下这些面试题

前言 最近呢有很多的小伙伴问我有没有什么软件测试的面试题&#xff0c;由于笔者之前一直在忙工作上的事情&#xff0c;没有时间整理面试题&#xff0c;刚好最近休息了一下&#xff0c;顺便整理了一些面试题&#xff0c;现在就把整理的面试题分享给大家&#xff0c;废话就不多说…

网络层:IPv4地址

网络层&#xff1a;IPv4地址 笔记来源&#xff1a; 湖科大教书匠&#xff1a;IPv4地址概述 湖科大教书匠&#xff1a;分类编址的IPv4地址 湖科大教书匠&#xff1a;划分子网的IPv4地址 湖科大教书匠&#xff1a;无分类编址的IPv4地址 IPv4地址就是给因特网(Internet)上的每一…

利用WinDbg查看堆栈中方法入参的值4(C#)

由于作者水平有限&#xff0c;如有写得不对的地方&#xff0c;请指正。 使用WinDbg的过程中&#xff0c;坑特别的多&#xff0c;对版本要求比较严格&#xff0c;如&#xff1a; 1 32位应用程序导出的Dump文件要用32位的WinDbg打开&#xff0c;想要没有那么多的问题&#xf…

python字符串格式化通过占位符拼接

我之前写了python字符串拼接 但我们会发现 它不太好用 第一个 当变量很多的时候 会写的很长 第二个 是python中字符串不能直接和其他类型的变量拼接 字符串格式化 也属于是字符串拼接的一种方法 语法上不是使用加号 我们打开编辑器 编写代码如下 weight 8.70; age 2; name…

JVM零基础到高级实战之Java内存区域虚拟机栈

JVM零基础到高级实战之Java内存区域虚拟机栈 JVM零基础到高级实战之Java内存区域虚拟机栈 文章目录 JVM零基础到高级实战之Java内存区域虚拟机栈前言JVM内存模型之虚拟机栈总结 前言 JVM零基础到高级实战之Java内存区域虚拟机栈 JVM内存模型之虚拟机栈 虚拟机栈是什么&#x…

Python给一个exe执行文件注册持续性的快捷键(热键)的代码实例

本篇文章主要讲解通过python给一个exe文件绑定一个快捷键、并取消快捷键(热键)的实操方法。 日期:2023年6月11日 作者:任聪聪 实现按下快捷键即可启动软件的效果说明 启动软件注册热键呼出其他软件或本体的效果说明: 演示材料说明:在download文件目录下存放一个可执行的…

RabbitMQ - 死信队列,延时队列

Time-To-Live and Expiration — RabbitMQ 一、死信队列 Dead Letter Exchanges — RabbitMQ 死信队列&#xff1a; DLX 全称&#xff08;Dead-Letter-Exchange&#xff09;,称之为死信交换器&#xff0c;当消息变成一个死信之后&#xff0c;如果这个消息所在的队列存在x-d…

【C++学习】C++入门(1)

写在前面 欢迎来到C的世界&#xff0c;这是一门令人兴奋的语言。 好吧&#xff0c;每当我开始阅读C的书籍的时候&#xff0c;开头的第一句话必定是这个&#xff0c; 也不知道其他语言的编程书籍是不是这样&#xff0c;那就让这句话也作为我C分享之路上的第一句话吧。 目录 …