Redis

82 阅读6分钟

特点

图片.png

图片.png

图片.png 单线程+多路IO复用技术 图片.png

键操作

图片.png

图片.png

常用数据类型 string

图片.png 图片.png 图片.png

数据结构

图片.png

图片.png

常用数据类型 list

图片.png

图片.png

图片.png

图片.png

数据结构

图片.png

图片.png

常见数据类型 set

图片.png

图片.png

图片.png

图片.png

数据结构

图片.png

图片.png

常见数据类型 hash

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

常见数据结构Zset

图片.png

图片.png

图片.png

数据结构

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

Redis 发送和订阅(一种消息的通讯模式)

图片.png 图片.png

图片.png

发布订阅命令

图片.png

图片.png

新数据类型

Bitmaps

图片.png

图片.png

操作命令

图片.png

图片.png

图片.png

图片.png

bitop

图片.png

图片.png

bitmaps和set比较

图片.png

图片.png

图片.png

HyperLogLog

图片.png

图片.png

图片.png

命令

图片.png

图片.png

图片.png

Geospatial

图片.png

命令

图片.png

图片.png 图片.png

Jedis操作redis6

使用java操作redis(注意修改redis配置文件)

图片.png

jedis实战

图片.png

图片.png

springboot整合redis

添加依赖

图片.png

配置redis

图片.png

添加redis配置类

图片.png

事务-基本操作

定义

图片.png 图片.png 图片.png

事务错误处理

组队中有语法错误,执行时 都会回滚 图片.png

图片.png 组队中无语法错误,但有逻辑错误,有逻辑错误的那一条会失败,其他的正常执行 图片.png

事务冲突

悲观锁

图片.png

乐观锁 (redis使用的机制)

场景:抢票 图片.png

watch()

图片.png 图片.png

watch使用实例

假设有一个计数器,需要多个客户端同时对其进行读取和修改。如果不采取任何措施,可能会导致并发修改问题。例如,假设计数器的当前值为10,现在有三个客户端 A、B 和 C,都要对计数器进行加1操作:

  1. 客户端 A 从 Redis 读取计数器的当前值,得到 10。
  2. 在客户端 A 对计数器进行修改之前,客户端 B 也读取了计数器的值,得到 10。
  3. 客户端 A 将计数器的值加1,得到 11,并将结果写回 Redis。
  4. 在客户端 A 完成修改之后,客户端 C 也读取了计数器的值,得到 11。
  5. 客户端 B 将计数器的值加1,得到 11,并将结果写回 Redis。
  6. 最后,客户端 C 也将计数器的值加1,得到 12,并将结果写回 Redis。 在这种情况下,计数器的值最终被增加了 2,而不是 3。这是因为客户端 B 和客户端 C 都读取了同一个初始值,并都将其增加了1,但是只有客户端 C 的结果得以保留。这样就会导致数据不一致的问题。 为了避免这种情况,可以使用 Redis 的事务机制和watch()方法来解决。首先,客户端 A 调用watch()方法,以监视计数器的键。然后,客户端 A 开始一个事务,并将计数器的值读取到本地变量中。接着,客户端 A 将计数器的值加1,并提交这个事务。如果在此期间有其他客户端修改了计数器的值,watch()方法就会检测到这种变化,事务将被中止。在这种情况下,客户端 A 可以通过重试事务来确保计数器的值最终增加了3,而不是2。 客户端 B 和客户端 C 可以以相同的方式访问计数器,使用事务和watch()方法来确保数据一致性。这样就可以避免并发修改问题,确保 Redis 中的数据在事务执行期间处于一致的状态。

watch的监控原理

在 Redis 中,每个键都有一个关联的版本号(version number)。当客户端调用 watch() 方法时,Redis 会记录被监视键的版本号。在事务执行期间,如果有其他客户端修改了被监视键的值,Redis 将会增加该键的版本号。当事务执行 exec() 方法时,Redis 会检查被监视键的版本号是否发生变化。如果版本号发生了变化,说明被监视键已经被其他客户端修改,事务将被中止,所有对被监视键的修改都会被回滚。 具体来说,当客户端调用 watch() 方法时,Redis 会为每个被监视键创建一个 WatchedKey 对象,并将其添加到客户端的监视列表中。WatchedKey 对象包含了键的名称和版本号。在执行事务期间,Redis 会记录所有被修改的键及其新值,但不会立即更新这些键的值。当事务执行 exec() 方法时,Redis 会检查每个被监视键的版本号是否与事务开始时记录的版本号相同。如果某个被监视键的版本号发生了变化,说明被监视键已经被其他客户端修改,Redis 将会中止事务,所有对被监视键的修改都会被回滚。 如果事务执行成功(即没有被其他客户端修改过被监视键的值),Redis 会将所有被修改的键的值更新为事务执行期间记录的新值,并将版本号增加1。 总之,watch() 方法实现了一种乐观锁机制,即在执行事务之前,先记录被监视键的版本号,如果事务执行期间发现被监视键的版本号发生了变化,就说明其他客户端已经对该键进行了修改,事务就会被中止,从而避免了并发修改导致的问题。

事务的三特性

图片.png

事务案例-秒杀

  • 超卖问题(并发问题)---使用乐观锁解决
  • 连接超时问题------使用连接池

数据库遗留问题

图片.png

解决方法使用lua脚本

图片.png

redis 持久化操作-RDB

redis是数据在内存中,将内存的数据写入硬盘就是持久化的过程

图片.png

图片.png

图片.png

图片.png

rdb的配置文件

redis默认会进行持久化操作 图片.png 图片.png

优缺点

图片.png

图片.png 图片.png

rdb备份

挂掉的redis根据rdb恢复数据

redis 持久化操作-AOF(Append only file)

图片.png AOF默认不开启

图片.png

图片.png

aof文件损坏修复

图片.png

aof配置

图片.png 压缩操作

图片.png

图片.png

aof持久化流程

图片.png

主从复制

图片.png

图片.png 图片.png

图片.png

主从复制-----搭建一主多从

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

主从复制-复制原理

常见的3个问题

一主二仆

图片.png

  • 主机死了 从机依然认主机为主
  • 从机死了 再次重启就忘掉了之前的主从关系

主从复制原理

图片.png

图片.png

薪火相传

减轻master写压力,去中心化降低风险 图片.png

反客为主 手动

图片.png

图片.png

java代码实现 主从模式


public class RedisMasterSlaveReplication {

    public static void main(String[] args) {
        // 创建 Jedis 连接到主服务器
        Jedis master = new Jedis("localhost", 6379);

        // 创建 Jedis 连接到从服务器
        Jedis slave = new Jedis("localhost", 6380);

        // 设置从服务器复制主服务器的数据
        slave.slaveof("localhost", 6379);

        // 测试复制是否成功
        master.set("test_key", "Hello, Redis!");
        System.out.println("Value from master: " + master.get("test_key"));

        // 稍等片刻,以便从服务器将数据复制到自身
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Value from slave: " + slave.get("test_key"));

        // 关闭 Jedis 连接
        master.close();
        slave.close();
    }

}

哨兵模式

图片.png

图片.png

哨兵的配置模式

图片.png

启动哨兵

图片.png

图片.png

图片.png

java代码实现

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

public class RedisSentinelMode {

    public static void main(String[] args) {
        // 哨兵地址集合
        Set<String> sentinels = new HashSet<>();
        sentinels.add("localhost:26379"); // 哨兵1地址

        // 创建 JedisSentinelPool 对象,连接到哨兵
        // "mymaster" 是哨兵配置文件中主服务器的名称
        JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", sentinels);

        // 从 JedisSentinelPool 获取 Jedis 对象
        try (Jedis jedis = sentinelPool.getResource()) {
            // 使用 Jedis 对象进行操作
            jedis.set("test_key", "Hello, Redis Sentinel!");
            System.out.println("Value: " + jedis.get("test_key"));
        }

        // 关闭 JedisSentinelPool
        sentinelPool.close();
    }
}

redis集群

图片.png

主机代理方式

图片.png

去中心化集群

图片.png

什么是集群

图片.png

搭建集群

配置文件

图片.png

图片.png

合体为集群

图片.png

连接集群服务器

图片.png

图片.png

插槽slot(主要作用平均分担压力)

图片.png

故障恢复

图片.png

图片.png

集群的jedis开发

图片.png图片.png

应用问题----缓存穿透

黑客攻击 图片.png

图片.png

应用问题----缓存击透

图片.png

图片.png

图片.png

内存雪崩

图片.png 图片.png 图片.png 图片.png

分布式锁(设置锁和过期时间)

图片.png

图片.png

图片.png 图片.png

分布式(uuid)

图片.png

图片.png

图片.png

图片.png

分布式中的原子性(lua脚本)

图片.png

图片.png

图片.png

图片.png