《Redis实战》学习笔记

news2025/1/19 20:40:08

特点 :1、是一个高性能的key/value内存型数据库

2、支持丰富的数据类型(string,List,Set,ZSet,Hash)

3、支持持久化 内存数据, 可以持久化到硬盘中

4、单进程,单线程 效率高 redis实现分布式锁

一、redis的相关指令

1、flushDB 清空当前库

2、flushAll 清空所有库

3、查看redis服务进程是否已经启动(redis服务状态)

1.ps -ef | grep redis

2.ps -aux | grep redis

3.netstat -tunple | grep 6379

4.lsof -i :6379

二、redis 操作的key的相关指令

1、删除: del key(名字) ……

2、exists : 检查指定key是否存在 EXISTS key(名字)

3、expire: 给key设置生存时间,当key过期时(生存时间为0),它会被自动删除 EXPIRE key 时间

4、keys * 查询所有key

三、数据类型相关操作指令

3.1、String类型

1. 内存存储模型

img

2. 常用操作命令

命令说明
set设置一个key/value
get根据key获得对应的value
mset一次设置多个key value
mget一次获得多个key的value
getset获得原始key的值,同时设置新值
strlen获得对应key存储value的长度
append为对应key的value追加内容
getrange 索引0开始截取value的内容
setex设置一个key存活的有效期(秒)
psetex设置一个key存活的有效期(毫秒)
setnx存在不做任何操作,不存在添加
msetnx原子操作(只要有一个存在不做任何操作)可以同时设置多个key,只有有一个存在都不保存
decr进行数值类型的-1操作
decrby根据提供的数据进行减法操作
Incr进行数值类型的+1操作
incrby根据提供的数据进行加法操作
Incrbyfloat根据提供的数据加入浮点数

3.2 List类型

list 列表 相当于java中list 集合 特点 元素有序 且 可以重复

1.内存存储模型

img

2.常用操作指令

命令说明
lpush将某个值加入到一个key列表头部
lpushx同lpush,但是必须要保证这个key存在
rpush将某个值加入到一个key列表末尾
rpushx同rpush,但是必须要保证这个key存在
lpop返回和移除列表左边的第一个元素
rpop返回和移除列表右边的第一个元素
lrange获取某一个下标区间内的元素
llen获取列表元素个数
lset设置某一个指定索引的值(索引必须存在)
lindex获取某一个指定索引位置的元素
lrem删除重复元素
ltrim保留列表中特定区间内的元素
linsert在某一个元素之前,之后插入新元素

3.3 Set类型

特点: Set类型 Set集合 元素无序 不可以重复

1.内存存储模型

img

2.常用命令

命令说明
sadd为集合添加元素
smembers显示集合中所有元素 无序
scard返回集合中元素的个数
spop随机返回一个元素 并将元素在集合中删除
smove从一个集合中向另一个集合移动元素 必须是同一种类型
srem从集合中删除一个元素
sismember判断一个集合中是否含有这个元素
srandmember随机返回元素
sdiff去掉第一个集合中其它集合含有的相同元素
sinter求交集
sunion求和集

3.4 ZSet类型

特点: 可排序的set集合 排序 不可重复

ZSET 官方 可排序SET sortSet

1.内存模型

img

2.常用命令

命令说明
zadd添加一个有序集合元素
zcard返回集合的元素个数
zrange 升序 zrevrange 降序返回一个范围内的元素
zrangebyscore按照分数查找一个范围内的元素
zrank返回排名
zrevrank倒序排名
zscore显示某一个元素的分数
zrem移除某一个元素
zincrby给某个特定元素加分

3.5 hash类型

特点: value 是一个map结构 存在key value key 无序的

1.内存模型

img

2.常用命令

命令说明
hset设置一个key/value对
hget获得一个key对应的value
hgetall获得所有的key/value对
hdel删除某一个key/value对
hexists判断一个key是否存在
hkeys获得所有的key
hvals获得所有的value
hmset设置多个key/value
hmget获得多个key的value
hsetnx设置一个不存在的key的值
hincrby为value进行加法运算
hincrbyfloat为value加入浮点值

四、Linux 安装Redis 时执行 make install报错

原因:

目前Redis官网下载的版本为 6.0版本 make安装

会报错是因为gcc版本过低,yum安装的gcc是4.8.5的。因此需要升级gcc,升级过程如下:

  1. yum -y install centos-release-scl
  2. yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
  3. scl enable devtoolset-9 bash
  4. echo “source /opt/rh/devtoolset-9/enable” >> /etc/profile
  5. gcc -v

五、redis持久化机制

当2种持久化同时开启的时候以AOF为主。

redis官方提供了两种不同的持久化方法来将数据存储待硬盘里面分别是:

1、快照(Snapshot)

​ (1)、特点:这种方式可以将某一时刻的数据都写入到磁盘中,当然这也是redis的默认开启持久化方式,保存文件形式是以rdb结尾的文件因此这方式也称之为rdb方式

(2)、生成方式:

●客户端方式:BGSAVE 和 SAVE指令

BGSAVE:当接受到客户端的BGSAVE命令时,redis会调用frok来创建一个子进程,然后子进程负责将快照写入磁盘中,儿父进程继续处理命令请求。

●服务器配置自动触发

2、AOF(Append Only File)只追加日志文件

开启AOF持久化

​ 1、在redis 配置文件里redis.conf 修改appendonly yes 开启持久化

​ 2、修改 appendonlyname “appendonlyname.aof” 指定生成文件名

img

3、日志追加频率

​ 1、always 谨慎使用 每个redis写命令都要同步写入磁盘,严重降低redis的速度

​ 2、everysec 推荐 redis默认使用的方式。 每秒执行一次同步显示的将多个写命令同步到磁盘

​ 3、no 不推荐 由操作系统决定何时同步,有可能会导致数据丢失

4、修改日志同步频率

修改appendfsync everysec | always |no 指定

img

六、AOF文件的重写

1、AOF带来的问题

AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩aof的持久化文件Redis提供了AOF重写(ReWriter)机制。

2、AOF重写

用来在一定程度上减小AOF文件的体积

1. 触发重写方式

# 1.客户端方式触发重写
- 执行BGREWRITEAOF命令  不会阻塞redis的服务

# 2.服务器配置方式自动触发
- 配置redis.conf中的auto-aof-rewrite-percentage选项 参加下图↓↓↓
- 如果设置auto-aof-rewrite-percentage值为100和auto-aof-rewrite-min-size 64mb,并且启用的AOF持久化时,那么当AOF文件体积大于64M,并且AOF文件的体积比上一次重写之后体积大了至少一倍(100%)时,会自动触发,如果重写过于频繁,用户可以考虑将auto-aof-rewrite-percentage设置为更大

img

2、重写原理

注意:重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,替换原有的文件这点和快照有点类似。 进行文件的替换

3、重写流程

  1. redis调用fork ,现在有父子两个进程 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
  2. 父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
  3. 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。

4.现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。

img

七、持久化总结

两种持久化方案既可以同时使用(aof),又可以单独使用,在某种情况下也可以都不使用,具体使用那种持久化方案取决于用户的数据和应用决定。

无论使用AOF还是快照机制持久化,将数据持久化到硬盘都是有必要的,除了持久化外,用户还应该对持久化的文件进行备份(最好备份在多个不同地方)。

1、redis的持久化方式RDB和AOF的区别

RDB:将redis内存的中数据存库记录定时写入磁盘上的RDB持久化

AOF:将redis的操作日志以追加的方式写入文件

2、二者的区别

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

img

AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

img

3、二者优缺点

RDB存在哪些优势呢?
  1. 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
  2. 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
  3. 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
  4. 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
RDB又存在哪些劣势呢?
  1. 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
  2. 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
AOF的优势有哪些呢?
  1. 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。
  2. 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
  3. 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
  4. AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。
AOF的劣势有哪些呢?
  1. 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
  2. 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。
  3. 二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 eventually consistent的意思了。不过生产环境其实更多都是二者结合使用的。

4、常用配置

RDB持久化配置

Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开6379.conf文件之后,我们搜索save,可以看到下面的配置信息:

  • save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。
  • save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。
  • save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。
AOF持久化配置

在Redis的配置文件中存在三种同步方式,它们分别是:

  • appendfsync always #每次有数据修改发生时都会写入AOF文件。
  • appendfsync everysec #每秒钟同步一次,该策略为AOF的缺省策略。
  • appendfsync no #从不同步。高效但是数据不会被持久化。

八、 java操作Redis

8.1 环境准备

1. 引入依赖

<!--引入jedis连接依赖-->
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.9.0</version>
</dependency>

2.创建jedis对象

 public static void main(String[] args) {
   //1.创建jedis对象
   Jedis jedis = new Jedis("192.168.40.4", 6379);//1.redis服务必须关闭防火墙  2.redis服务必须开启远程连接
   jedis.select(0);//选择操作的库默认0号库
   //2.执行相关操作
   //....
   //3.释放资源
   jedis.close();
 }

8.2 操作key相关API

public class TestKey {
    private Jedis jedis;
    @Before
    public void  before(){
        jedis = new Jedis("192.168.3.176",7000);
    }
    @After
    public void after(){
        jedis.close();
    }
    //测试key相关
    @Test
    public void testKey(){
        //删除一个key
        jedis.del("name");
        //删除多个key
       // jedis.del("name","age");
        //判断一个key是否存在
        System.out.println(jedis.exists("name"));
        //设置一个key的超时时间
        //Long age = jedis.expire("age", 100);
        //System.out.println(age);
        //查看一个key的超时时间
       /* Long age1 = jedis.ttl("newAge");
        System.out.println(age1);*/
        //随机获取一个key
        System.out.println(jedis.randomKey());
        //修改key的名称
        //System.out.println(jedis.rename("age","newAge"));
        //查看key对应值的类型
        System.out.println(jedis.type("zsts"));
    }
}

8.3操作String相关API

public class TestString {
    private Jedis jedis;
    @Before
    public void  before(){
        jedis = new Jedis("192.168.3.176",7000);
    }

    @After
    public void after(){
        jedis.close();
    }

    //测试String相关
    @Test
    public void testString(){
        //set
         jedis.set("name", "小陈");
         //get
        System.out.println(jedis.get("name"));
        //设置多个 mset
        jedis.mset("sex","20","bir","2020-12-23");

        //获取多个 mget
        jedis.mget("name","sex","bir").forEach(mget-> System.out.println("mget="+mget));

        //getset
         System.out.println(jedis.getSet("name","小红"));
       // System.out.println(jedis.get("name"));

    }
}

8.4操作List相关API

public class TestList {
    private Jedis jedis;
    @Before
    public void  before(){
        jedis = new Jedis("192.168.3.176",7000);
    }

    @After
    public void after(){
        jedis.close();
    }

    //测试List相关
    @Test
    public void testString(){
        //lpush 将某个值加入到一个key列表头部
      /*  jedis.lpush("names1","张三","王五","赵六","win7");

        //rpush  将某个值加入到一个key列表末尾
        jedis.rpush("names1","xiaomingming");

        //遍历
       //jedis.lrange("names1",0,-1).forEach(list-> System.out.println("list="+list));

        //lpop 从左边移除  rpop 从右边移除
        //System.out.println(jedis.lpop("names1"));

        System.out.println(jedis.rpop("names1"));*/

        //linsert  在某一个元素之前,之后插入新元素
        jedis.linsert("lists", BinaryClient.LIST_POSITION.BEFORE,"xiaohei","xiaobai");


        //linsert  在某一个元素之后插入新元素
        jedis.linsert("lists", BinaryClient.LIST_POSITION.AFTER,"xiaohei","xiaolang");

    }
}

8.5操作Set的相关API

//测试SET相关
@Test
public void testSet(){

  //sadd
  jedis.sadd("names","zhangsan","lisi");

  //smembers
  jedis.smembers("names");

  //sismember
  jedis.sismember("names","xiaochen");

  //...
}

8.6 操作ZSet相关API

//测试ZSET相关
@Test
public void testZset(){

  //zadd
  jedis.zadd("names",10,"张三");

  //zrange
  jedis.zrange("names",0,-1);

  //zcard
  jedis.zcard("names");

  //zrangeByScore
  jedis.zrangeByScore("names","0","100",0,5);

  //..

}

8.7 操作Hash相关API

//测试HASH相关
@Test
public void testHash(){
  //hset
  jedis.hset("maps","name","zhangsan");
  //hget
  jedis.hget("maps","name");
  //hgetall
  jedis.hgetAll("mps");
  //hkeys
  jedis.hkeys("maps");
  //hvals
  jedis.hvals("maps");
  //....
}

九.SpringBoot整合Redis

Spring Boot Data(数据) Redis 中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。

注意: 使用RedisTemplate默认是将对象序列化到Redis中,所以放入的对象必须实现对象序列化接口

9.1 环境准备

1.引入依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.配置application.propertie

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.database=0

9.2 使用StringRedisTemplate和RedisTemplate

		@Autowired
    private StringRedisTemplate stringRedisTemplate;  //对字符串支持比较友好,不能存储对象
    @Autowired
    private RedisTemplate redisTemplate;  //存储对象

    @Test
    public void testRedisTemplate(){
        System.out.println(redisTemplate);
        //设置redistemplate值使用对象序列化策略
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());//指定值使用对象序列化
        //redisTemplate.opsForValue().set("user",new User("21","小黑",23,new Date()));
        User user = (User) redisTemplate.opsForValue().get("user");
        System.out.println(user);
//      Set keys = redisTemplate.keys("*");
//      keys.forEach(key -> System.out.println(key));
        /*Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);*/

        //Object xiaohei = redisTemplate.opsForValue().get("xiaohei");
        //System.out.println(xiaohei);
        /*redisTemplate.opsForValue().set("name","xxxx");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);*/
        /*redisTemplate.opsForList().leftPushAll("lists","xxxx","1111");
        List lists = redisTemplate.opsForList().range("lists", 0, -1);
        lists.forEach(list-> System.out.println(list));*/
    }


    //key的绑定操作 如果日后对某一个key的操作及其频繁,可以将这个key绑定到对应redistemplate中,日后基于绑定操作都是操作这个key
    //boundValueOps 用来对String值绑定key
    //boundListOps 用来对List值绑定key
    //boundSetOps 用来对Set值绑定key
    //boundZsetOps 用来对Zset值绑定key
    //boundHashOps 用来对Hash值绑定key

    @Test
    public void testBoundKey(){
        BoundValueOperations<String, String> nameValueOperations = stringRedisTemplate.boundValueOps("name");
        nameValueOperations.set("1");
        //yuew
        nameValueOperations.set("2");
        String s = nameValueOperations.get();
        System.out.println(s);

    }


    //hash相关操作 opsForHash
    @Test
    public void testHash(){
        stringRedisTemplate.opsForHash().put("maps","name","小黑");
        Object o = stringRedisTemplate.opsForHash().get("maps", "name");
        System.out.println(o);
    }

    //zset相关操作 opsForZSet
    @Test
    public void testZSet(){
        stringRedisTemplate.opsForZSet().add("zsets","小黑",10);
        Set<String> zsets = stringRedisTemplate.opsForZSet().range("zsets", 0, -1);
        zsets.forEach(value-> System.out.println(value));
    }

    //set相关操作 opsForSet
    @Test
    public void testSet(){
        stringRedisTemplate.opsForSet().add("sets","xiaosan","xiaosi","xiaowu");
        Set<String> sets = stringRedisTemplate.opsForSet().members("sets");
        sets.forEach(value-> System.out.println(value));
    }

    //list相关的操作opsForList
    @Test
    public void testList(){
        // stringRedisTemplate.opsForList().leftPushAll("lists","张三","李四","王五");
        List<String> lists = stringRedisTemplate.opsForList().range("lists", 0, -1);
        lists.forEach(key -> System.out.println(key));
    }


    //String相关的操作 opsForValue
    @Test
    public void testString(){
        //stringRedisTemplate.opsForValue().set("166","好同学");
        String s = stringRedisTemplate.opsForValue().get("166");
        System.out.println(s);
        Long size = stringRedisTemplate.opsForValue().size("166");
        System.out.println(size);
    }


    //key相关的操作
    @Test
    public void test(){
        Set<String> keys = stringRedisTemplate.keys("*");//查看所有key
        Boolean name = stringRedisTemplate.hasKey("name");//判断某个key是否存在
        stringRedisTemplate.delete("age");//根据指定key删除
        stringRedisTemplate.rename("","");//修改key的名称
        stringRedisTemplate.expire("key",10, TimeUnit.HOURS);
      	//设置key超时时间 参数1:设置key名 参数2:时间 参数3:时间的单位
        stringRedisTemplate.move("",1);//移动key
    }

十. Redis 主从复制

10.1 主从复制

主从复制架构仅仅用来解决数据的冗余备份,从节点仅仅用来同步数据

无法解决: 1.master节点出现故障的自动故障转移

10.2 主从复制架构图

img

10.3 搭建主从复制

# 1.准备3台机器并修改配置
- master
	port 6379
	bind 0.0.0.0
	
- slave1
	port 6380
	bind 0.0.0.0
	slaveof masterip masterport

- slave2
	port 6381
	bind 0.0.0.0
	slaveof masterip masterport

img

# 2.启动3台机器进行测试
- cd /usr/redis/bin
- ./redis-server /root/master/redis.conf
- ./redis-server /root/slave1/redis.conf
- ./redis-server /root/slave2/redis.conf

十一. Redis哨兵机制

11.1 哨兵Sentinel机制

Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。简单的说哨兵就是带有自动故障转移功能的主从架构

无法解决: 1.单节点并发压力问题 2.单节点内存和磁盘物理上限

11.2 哨兵架构原理

img

11.3 搭建哨兵架构

# 1.在主节点上创建哨兵配置
- 在Master对应redis.conf同目录下新建sentinel.conf文件,名字绝对不能错;

# 2.配置哨兵,在sentinel.conf文件中填入内容:
- sentinel monitor 被监控数据库名字(自己起名字) ip port 1

# 3.启动哨兵模式进行测试
- redis-sentinel  /root/sentinel/sentinel.conf
	说明:这个后面的数字2,是指当有两个及以上的sentinel服务检测到master宕机,才会去执行主从切换的功能。

11.4 通过springboot操作哨兵

# redis sentinel 配置
# master书写是使用哨兵监听的那个名称
spring.redis.sentinel.master=mymaster
# 连接的不再是一个具体redis主机,书写的是多个哨兵节点
spring.redis.sentinel.nodes=192.168.202.206:26379
  • 注意:如果连接过程中出现如下错误:RedisConnectionException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command ‘CONFIG SET protected-mode no’ from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2)
  • 解决方案:在哨兵的配置文件中加入bind 0.0.0.0 开启远程连接权限

img

十二. Redis集群

12.1 集群

Redis在3.0后开始支持Cluster(模式)模式,目前redis的集群支持节点的自动发现,支持slave-master选举和容错,支持在线分片(sharding shard )等特性。reshard

12.2 集群架构图

img

12.3 集群细节

- 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
- 节点的fail是通过集群中超过半数的节点检测失效时才生效. 
- 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
- redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value

img

12.4 集群搭建

判断一个是集群中的节点是否可用,是集群中的所用主节点选举过程,如果半数以上的节点认为当前节点挂掉,那么当前节点就是挂掉了,所以搭建redis集群时建议节点数最好为奇数,搭建集群至少需要三个主节点,三个从节点,至少需要6个节点

# 1.准备环境安装ruby以及redis集群依赖
- yum install -y ruby rubygems
- gem install redis-xxx.gem

imgimg

# 2.在一台机器创建7个目录

img

# 3.每个目录复制一份配置文件
[root@localhost ~]# cp redis-4.0.10/redis.conf 7000/
[root@localhost ~]# cp redis-4.0.10/redis.conf 7001/
[root@localhost ~]# cp redis-4.0.10/redis.conf 7002/
[root@localhost ~]# cp redis-4.0.10/redis.conf 7003/
[root@localhost ~]# cp redis-4.0.10/redis.conf 7004/
[root@localhost ~]# cp redis-4.0.10/redis.conf 7005/
[root@localhost ~]# cp redis-4.0.10/redis.conf 7006/

img

# 4.修改不同目录配置文件
- port 	6379 .....                		 //修改端口
- bind  0.0.0.0                   		 //开启远程连接
- cluster-enabled  yes 	        			 //开启集群模式
- cluster-config-file  nodes-port.conf //集群节点配置文件
- cluster-node-timeout  5000      	   //集群节点超时时间
- appendonly  yes   		               //开启AOF持久化

# 5.指定不同目录配置文件启动七个节点
- [root@localhost bin]# ./redis-server  /root/7000/redis.conf
- [root@localhost bin]# ./redis-server  /root/7001/redis.conf
- [root@localhost bin]# ./redis-server  /root/7002/redis.conf
- [root@localhost bin]# ./redis-server  /root/7003/redis.conf
- [root@localhost bin]# ./redis-server  /root/7004/redis.conf
- [root@localhost bin]# ./redis-server  /root/7005/redis.conf
- [root@localhost bin]# ./redis-server  /root/7006/redis.conf

img

# 6.查看进程
- [root@localhost bin]# ps aux|grep redis

img

1.创建集群

# 1.复制集群操作脚本到bin目录中
- [root@localhost bin]# cp /root/redis-4.0.10/src/redis-trib.rb .

# 2.创建集群
- ./redis-trib.rb create --replicas 1 192.168.202.205:7000 192.168.202.205:7001 192.168.202.205:7002 192.168.202.205:7003 192.168.202.205:7004 192.168.202.205:7005

img

# 3.集群创建成功出现如下提示

img

2.查看集群状态

# 1.查看集群状态 check [原始集群中任意节点] [无]
- ./redis-trib.rb check 192.168.202.205:7000

# 2.集群节点状态说明
- 主节点 
	主节点存在hash slots,且主节点的hash slots 没有交叉
	主节点不能删除
	一个主节点可以有多个从节点
	主节点宕机时多个副本之间自动选举主节点

- 从节点
	从节点没有hash slots
	从节点可以删除
	从节点不负责数据的写,只负责数据的同步

3.添加主节点

# 1.添加主节点 add-node [新加入节点] [原始集群中任意节点]
- ./redis-trib.rb  add-node 192.168.1.158:7006  192.168.1.158:7005
- 注意:
	1.该节点必须以集群模式启动
	2.默认情况下该节点就是以master节点形式添加

4.添加从节点

# 1.添加从节点 add-node --slave [新加入节点] [集群中任意节点]
- ./redis-trib.rb  add-node --slave 192.168.1.158:7006 192.168.1.158:7000
- 注意:
	当添加副本节点时没有指定主节点,redis会随机给副本节点较少的主节点添加当前副本节点
	
# 2.为确定的master节点添加主节点 add-node --slave --master-id master节点id [新加入节点] [集群任意节点]
- ./redis-trib.rb  add-node --slave --master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7006  127.0.0.1:7000

5.删除副本节点

# 1.删除节点 del-node [集群中任意节点] [删除节点id]
- ./redis-trib.rb  del-node 127.0.0.1:7002 0ca3f102ecf0c888fc7a7ce43a13e9be9f6d3dd1
- 注意:
 1.被删除的节点必须是从节点或没有被分配hash slots的节点

6.集群在线分片

# 1.在线分片 reshard [集群中任意节点] [无]
- ./redis-trib.rb  reshard  192.168.1.158:7000

十三.Redis实现分布式Session管理

13.1 管理机制

redis的session管理是利用spring提供的session管理解决方案,将一个应用session交给Redis存储,整个应用中所有session的请求都会去redis中获取对应的session数据。

img

13.2 开发Session管理

1. 引入依赖

<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
</dependency>

2. 开发Session管理配置类

@Configuration
@EnableRedisHttpSession
public class RedisSessionManager {
   
}

3.打包测试即可


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一起学量化之ATR指标

1. ATR指标定义 ATR,全称Average True Range,即均幅指标,是一个衡量市场波动性的技术分析工具。它通过计算一定周期内的平均真实波幅,来反映市场波动的程度。ATR指标由J. Welles Wilder Jr开发,主要用于研判买卖时机和管理交易风险。下图中蓝色的线即为ATR。 2. ATR指标应…

【PTA-C语言】实验七-函数与指针I

如果代码存在问题&#xff0c;麻烦大家指正 ~ ~有帮助麻烦点个赞 ~ ~ 目录——实验七-函数与指针I 6-1 弹球距离&#xff08;分数 10&#xff09;6-2 使用函数输出一个整数的逆序数&#xff08;分数 10&#xff09;6-3 使用函数求最大公约数&#xff08;分数 10&#xff09;6-4…

Wi-Fi 7用到的一些技术术语汇总

文章目录 low-complexity ap coordinationMulti-AP coordinationHARQ&#xff08;Hybrid Automatic Repeat Request&#xff09;multiple resource units per STAFCC open 6GhzU-NII-5,U-NII-6&#xff1f;4096-QAM&#xff08;Quadrature Amplitude Modulation&#xff0c;正交…

在FC中手工创建虚拟机模板

1、Linux去除个性化信息 &#xff08;1&#xff09;编辑网卡配置文件&#xff0c;只保留以下内容&#xff08;以RHEL 7为例&#xff09; &#xff08;2&#xff09;清除主机密钥信息&#xff08;开机会自动生成&#xff09; &#xff08;3&#xff09;清除Machine ID&#xff…

数据统计的一些专业术语学习

数据统计的一些专业术语学习 1. 极差2. 方差3. 标准差4. 均值绝对差 1. 极差 数据统计的极差&#xff0c;又称全距&#xff0c;是指一组数据中最大值和最小值之差。 举个例子&#xff0c;如果我们有一组数据&#xff1a;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c…

【动态规划】【字符串】C++算法:正则表达式匹配

作者推荐 视频算法专题 涉及知识点 动态规划 字符串 LeetCode10:正则表达式匹配 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 ‘.’ 和 ‘’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 ’ 匹配零个或多个前面的那一个元素 所谓匹配&#xff0c;是…

【SD】一致性角色 - 同一人物 不同姿势 - 2

首先生成4张不同姿势的图片 masterpiece,high quality,(white background:1.6),(simple background:1.4),1gril,solo,black footwear,black hair,brown eyes,closed mouth,full body,glasses,jacket,long hair,long sleeves,lookig at viewer,plaid,plaid skirt,pleated shirt,…

人是需要被肯定和认可的,赞美也是一种动力

前几天转发了一些网上的文章&#xff0c;突然有了10个关注我的人&#xff0c;赞美数和收藏量也上去了一些。 这是一种很意外的惊喜。 看了一下主题是&#xff1a; 1,如何将.NET8创建的控制台程序部署成WINDOWS服务。 2,.NET进阶篇06-async异步、thread多线程 3,易语言启动线程传…

病理HE学习贴(自备)

目录 正常结构 癌症HE 在线学习 以胃癌的学习为例 正常结构 1&#xff1a;胃粘膜正常结构和细胞分化 ●表面覆盖小凹上皮细胞(主要标志物&#xff1a;MUC5AC)以保护黏膜。 ●胃底腺固有腺体由黏液颈细胞(MUC6)、主细胞(Pepsinogen l)和壁细胞(Proton pump α-subunit)组…

css动态传参,attr的妙用

今天再做一个编辑器的功能的时候&#xff0c;发现有一段非常奇妙的代码&#xff0c;使用attr获取div标签的data-label值。 css的attr?What fuck?这又是什么鬼东西&#xff0c;emmm。 查询后官方是这么回答的&#xff1a; CSS 表达式 attr() 用来获取选择到的元素的某一 HTM…

Windows 10启用Hyper-V

Windows 10启用Hyper-V 官网教程PowerShell 启用 Hyper-V启用 Hyper-V 角色 我们知道VMware是创建虚拟机的好工具&#xff0c;那Windows平台上有没有虚拟工具呢&#xff1f; 今天我们要讲解的就是Windows才入局的虚拟工具&#xff1a;Hyper-V 官网教程 https://learn.microsof…

VMware安装RHEL9.0版本Linux系统

最近在学习Linux&#xff0c;安装了Red Hat Enterprise Linux 的 9.0版本&#xff0c;简称RHEL9.0。RHEL9.0是Red Hat公司发布的面向企业用户的Linux操作系统的最新版本。我把它安装在虚拟机VMware里来减少电脑性能占用&#xff0c;也防止系统炸搞得我后面要重装。安装RHEL9.0还…

vu3-14

第一个需求是在用户登录成功之后&#xff0c;在主页显示用户的真实姓名和性别&#xff0c;这些信息要调用后端API获取数据库里面的信息&#xff0c;第二个需求是点击菜单1&#xff0c;在表单中修改用户信息之后&#xff0c;更新到后端数据库&#xff0c;然后在主页同步更新用户…

24. 二维数组

二维数组的创建和初始化 #include<stdio.h> int main() {//二维数组的创建int arr[3][4]; //三行四列char ch[3][10]; //三行十列return 0; } 创建&#xff1a; 完全初始化 int arr[3][4] { 1,2,3,4,5,6,7,8,9,10,11,12 }; 不完全初始化 int arr1[3][4] { 1,2,3…

【兔子王赠书第14期】《YOLO目标检测》涵盖众多目标检测框架,附赠源代码和全书彩图!

文章目录 写在前面YOLO目标检测推荐图书本书特色内容简介作者简介 推荐理由粉丝福利写在后面 写在前面 小伙伴们好久不见吖&#xff0c;本期博主给大家推荐一本关于YOLO目标检测的图书&#xff0c;该书侧重目标检测的基础知识&#xff0c;包含丰富的实践内容&#xff0c;是目标…

微服务篇之Nacos快速入门

Nacos 简介 Nacos 起源 Nacos 起源于阿里巴巴 2008 年的五彩石项目&#xff08;完成微服务拆分和业务中台建设&#xff09;&#xff0c;经历了阿里十年双十⼀的洪峰流量的考验&#xff0c;沉淀了简单易用、稳定可靠、性能卓越等核心特性。随着云计算的兴起和受到开源软件行业…

Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题

Java项目调试实战&#xff1a;如何高效调试Spring Boot项目中的GET请求&#xff0c;并通过equalsIgnoreCase解决大小写不一致问题 写在最前面全部过程Java equalsIgnoreCase() 方法idea中如何调试SpringBoot项目在IntelliJ IDEA中使用内置HTTP客户端设置断点和调试 补充&#x…

【阅读笔记】Semi-supervised Domain Adaptation in Graph Transfer Learning

Background 真实世界的图上节点的标签数据是很难拿到的。 因此图转移学习被提出将知识从标记的源图转移出来&#xff0c;以帮助预测域变化的目标图中节点的标签。 尽管图迁移学习算法取得了重大进展&#xff0c;但它们通常假定源图中的所有节点都被标记出来了。 因此文章定义…

C#调用(python通过excel坐标生成的曲面地形图)案例

效果图: 文件图: 详解一:环境和python库问题 1.python 中只需要下载 matplotlib3.8.2和scipy1.11.4 2.我安装的python版本 详解二:解释器问题 python解释器这里有两种形式 第一种形式 1.调用 pycharm项目下的解释器,需要安装python必须的包(命令安装或者搜索安装)。 2.修改…

2022年全球软件质量效能大会(QECon上海站)-核心PPT资料下载

一、峰会简介 近年来&#xff0c;以云计算、移动互联网、物联网、工业互联网、人工智能、大数据及区块链等新一代信息技术构建的智能化应用和产品出现爆发式增长&#xff0c;突破了对于软件形态的传统认知&#xff0c;正以各种展现方式诠释着对新型智能软件的定义。这也使得对…