Redis知识点(未完待续)

一. Redis的介绍

1.1 引言
  1. 由于用户量增大, 请求数量也增大, 数据库压力过大
  2. 多台服务器之间, 数据不同步
  3. 多台服务器之间的锁, 已经不存在互斥性了

1.2 NoSql

Redis就是一款NoSql

NoSql -> 非关系型数据库 -> Not Only Sql

  1. Key - Value : Redis…
  2. 文档型 : ElasticSearch, Solr, Mongodb…
  3. 面向列 : Hbase, Cassandra…
  4. 图像化 : Neo4j…

除了关系型数据库都是非关系型数据库

NoSql只是一个概念, 泛指非关系型数据库, 目的是为了和关系型数据库做一个区分

1.3 Redis介绍

有一位意大利人, Salvatore, 在开发一款LLOOGG的统计页面时, 因为MySQL的性能不好, 自己研发了一款非关系型数据库, 命名为Redis.

Redis ( Remote Dictionary Server ) 即远程字典服务

  1. Redis由c语言编写, 是基于Key - Value的NoSql
  2. Redis基于内存存储数据, 还提供了多种持久化机制, 性能可以达到110000次/s读取数据以及81000次/s写入数据
  3. Redis提供了主从, 哨兵以及集群的搭建方式, 可以更加方便的进行横向扩展和垂直扩展

二. Redis的安装

2.1 安装Redis

docker-compose.yml

version: '3.1'
services:
  redis:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis
    environment: 
      - TZ=Asia/Shanghai
    ports:
      - 6379:6379

使用docker命令启动容器: docker-compose up -d

2.2 使用redis-cli连接Redis

使用docker命令进入容器内部: docker exec -it 容器id bash

在容器内部使用Redis客户端连接命令: redis-cli

2.3 使用图形化界面连接Redis

使用Redis可视化软件Redis desktop manager连接

三. Redis的常用命令(Redis命令参考文档)

3.1 Redis存储数据的结构

常用的5种数据结构

  • key - value : 一个key对应一个值
  • key - hash : 一个key对应一个map
  • key - list : 一个key对应一个列表
  • key - set : 一个key对应一个集合
  • key - zset : 一个key对应一个有序的集合

另外的3中数据结构

HyperLogLog : 计算近似值

GEO : 地理位置

BIT : 一般存储的也是一个字符串, 存储的是一个byte[]


常用的5种数据结构图:

在这里插入图片描述


常用的5种数据结构使用场景:

key - value : 最常用的, 一般用于存储一个值

key - hash : 存储一个对象数据

key - list : 实现队列和栈结构

key - set : 交集, 差集和并集的操作

key - zset : 排行榜, 积分存储等操作

3.2 string常用命令
#1. 添加值(如果key存在, 为更新操作)
set key value

#2. 取值
get key value

#3. 删除(可以同时删除多个key)
del key1 [key2 key3 ...]

#4. 批量操作
mset key1 value [key2 value key3 value ...]
mget key1 key2 key3 ... 

#5. 自增命令(自增1)
incr key

#6. 自减命令(自减1)
decr key

#7. 自增或自减指定数量
incrby key increment
decrby key increment

#8. 设置值的同时, 指定生存时间(每次向Redis中添加数据时, 尽量都设置上)
setex key second value

#9. 设置值, 如果当前key不存在的话(如果这个key存在, 那么什么都不做, 如果key不存在, 和set命令一样)
setnx key value

#10. 在key对应的value后, 追加内容
append key value

#11. 查看value字符串的长度
strlen key
3.3 hash常用命令
#1. 添加数据(如果field存在, 则为更新操作)
hset key field value

#2. 获取数据
hget key field

#3. 删除数据
hdel key field1 [field2 field3 ...]

#4. 批量操作
hmset key field1 value1 [field2 value2 ...]
hmget key field1 [field2 ...]

#5. 自增自减(根据increment正负)
hincrby key field increment

#6. 获取key中全部的field和value
hgetall key

#7. 获取key中所有的field
hkeys key

#8. 获取key中所有的value
hvals key

#9. 判断key中是否含有某个field字段
hexists key field

#10. 获取key中field数量
hlen key
3.4 list常用命令
#1. 添加数据(从左侧添加数据, 从右侧添加数据)
lpush key value1 [value2 value3 ...]
rpush key value1 [value2 value3 ...]

#2. 追加数据(如果key不存在或者key的数据类型不是list, 则什么也不做)
lpushx key value
rpushx key value

#3. 修改数据(将某个索引位置的数据更新)
lset key index value

#4. 弹栈方式获取数据(从左侧弹出, 从右侧弹出, 弹出后删除)
lpop key
rpop key

#5. 获取指定范围内的数据(start从0开始, stop输入-1代表最后一个, -2代表倒数第二个)
lrange key start stop

#6. 获取指定索引位置的数据
lindex key index

#7. 获取整个列表的长度
llen key

#8. 删除列表中某个value(删除当前列表中count个value值, count > 0 从左侧删除, count < 0 从右侧删除, count == 0 删除列表中全部数据)
lrem key count value

#9. 保留列表中的数据
ltrim key start stop

3.5 set常用命令
#1. 添加数据
sadd key member1 [member2 member3 ...]

#2. 获取数据
smembers key

#3. 随机获取数据(获取的同时, 移除数据, count默认值为1, 代表弹出数据的数量)
spop key [count]


#4. 删除数据
srem key member1 [member2 ...]

#5. 判断集合中是否包含某个值
sismember key member
#6. 交集
sinter set1 set2

#7. 并集
sunion set1 set2

#8. 差集
sdiff set1 set2
3.6 zset常用命令
#1. 添加数据
zadd key score member1 [score member2 score member3 ... ]

#2. 修改分数(如果member存在与key中, 正常增加分数, 如果不存在, 这个命令就相当于zadd)
zincrby key increment member

#3. 查看指定的member的分数
zscore key member

#4. 删除zset中的成员
zrem key member1 [member2 member3 ...]

#5. 获取zset中数据的数量
zcard key

#6. 根据score的范围查询member的数量
zcount key min max

#7. 根据分数从小到大排序, 获取指定范围内的数据(withscores 如果添加这个参数, 那么会返回member对应的分数)
zrange key start stop [withscores]

#8. 根据分数从大到小排序, 获取指定范围内的数据(withscores 如果添加这个参数, 那么会返回member对应的分数)
zrevrange key start stop [withscores]

#9. 根据分数的范围从小到大获取member(withscores 代表同时返回score, 添加limit, 就跟mysql中一样. 支持 '(分数' 相当于 '<' 但是不等于, 最大值和最小值分别用 +inf 和 -inf 来表示)
zrangebyscore key min max [limit offset count]

#10. 根据分数的范围从大到小获取member(withscores 代表同时返回score, 添加limit, 就跟mysql中一样. 支持 '(分数' 相当于 '<' 但是不等于, 最大值和最小值分别用 +inf 和 -inf 来表示)
zrevrangebyscore key max min [limit offset count]

3.7 key常用命令
#1. 查找所有符合给定模式 pattern 的 key
keys pattern
  • KEYS * 匹配数据库中所有 key 。

  • KEYS h?llo 匹配 hello , hallo 和 hxllo 等。

  • KEYS h*llo 匹配 hllo 和 heeeeello 等。

  • KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。

#2. 检查给定 key 是否存在( 1 - 存在, 0 - 不存在 )
exists key

#3. 查看key所存储的值的类型
type key
  • none (key不存在)
  • string (字符串)
  • list (列表)
  • set (集合)
  • zset (有序集)
  • hash (哈希表)
  • stream (流)
#4. 删除一个或者多个key
del key1 [key2 key3 ...]
3.8 库的常用命令
#1. 切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值
select index

#2. 返回当前数据库的 key 的数量
dbsize

#3. 清空当前数据库中的所有数据
flushdb

#4. 清空Redis服务器中所有数据
flushall
3.9 过期时间命令
#1. 为指定的key设置过期时间, 还能活多久(秒, 毫秒)
expire key seconds
pexpire key milliseconds
#2. 设置key到 某个时间点 过期, 能活到哪个时间点(秒单位, 毫秒单位)
expireat key timestamp
pexpireat key milliseconds-timestamp
#3. 移除指定key的过期时间, 使其变为永不过期
persist key
#4. 查询某个key的过期时间(秒, 毫秒)
ttl key
pttl key

四. Java连接Redis

Jedis连接Redis, lettuce连接Redis

4.1 Jedis连接Redis

创建maven项目

引入依赖

<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

测试

public class Demo1 {

    @Test
    public void set() {
        Jedis jedis = new Jedis("192.168.153.129", 6379);
        jedis.set("name", "张三");
        jedis.close();
    }

    @Test
    public void get() {
        Jedis jedis = new Jedis("192.168.153.129", 6379);
        String name = jedis.get("name");
        System.out.println(name);
        jedis.close();
    }

}
4.2 Jedis如何存储一个对象到Redis, 以byte[]的方式

引入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.16.RELEASE</version>
</dependency>

新建User类

public class User implements Serializable {

    private static final long serialVersionUID = -9066097709281121769L;
    private String name;
    private Integer age;

    public User() {
    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试

@Test
    public void setByteArray() {
        // 1. 建立连接
        Jedis jedis = new Jedis("192.168.153.129", 6379);

        // 2.1 准备key - value(User)
        String key = "user";
        User user = new User("王五", 25);
        // 2.2 将key和value转化为byte[]
        byte[] keyByte = SerializationUtils.serialize(key);
        byte[] userByte = SerializationUtils.serialize(user);
        // 2.3 将byte[]存储到Redis中
        jedis.set(keyByte, userByte);

        // 3. 关闭连接
        jedis.close();
    }


    @Test
    public void getByteArray() {
        // 1. 建立连接
        Jedis jedis = new Jedis("192.168.153.129", 6379);

        // 2. 执行操作
        byte[] key = SerializationUtils.serialize("user");
        byte[] value = jedis.get(key);
        System.out.println(SerializationUtils.deserialize(value));

        // 3. 关闭连接
        jedis.close();
    }
4.3 Jedis如何存储一个对象到Redis, 以String的方式

引入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>

测试

@Test
    public void setString() {
        // 1. 建立连接
        Jedis jedis = new Jedis("192.168.153.129", 6379);

        // 2.1 准备key - value
        String key = "userString";
        User user = new User("赵六", 88);
        // 2.2 将对象转换为json字符串
        String value = JSON.toJSONString(user);
        // 2.3 执行存储操作

        jedis.set(key, value);

        // 3. 关闭连接
        jedis.close();
    }


    @Test
    public void getString() {
        // 1. 建立连接
        Jedis jedis = new Jedis("192.168.153.129", 6379);

        // 2.1 准备key
        String key = "userString";
        // 2.2 获取value
        String value = jedis.get(key);
        // 2.3 value转化为对象并输出
        User user = JSON.parseObject(value, User.class);
        System.out.println(user);

        // 3. 关闭连接
        jedis.close();
    }
4.4 Jedis连接池操作
 @Test
    public void pool() {
        // 1. 创建连接池配置
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        // 连接池中最大活跃数
        config.setMaxTotal(100);
        // 最大空闲数
        config.setMaxIdle(10);
        // 最小空闲数
        config.setMinIdle(5);
        // 当线程池空了以后, 多久没有获取到Jedis对象, 就超时
        config.setMaxWaitMillis(3000);

        // 2. 创建连接池
        JedisPool jedisPool = new JedisPool(config, "192.168.153.129", 6379);
        // 3. 获取Redis对象
        Jedis jedis = jedisPool.getResource();
        // 4. 执行操作
        String userString = jedis.get("userString");
        System.out.println(userString);

        // 5. 释放资源
        jedis.close();
    }
4.5 Redis的管道操作
@Test
    public void pipelineTest1() {
        long startTime = System.currentTimeMillis();

        // 1. 创建连接池对象
        JedisPool jedisPool = new JedisPool("192.168.153.129", 6379);

        // 2. 获取Jedis对象
        Jedis jedis = jedisPool.getResource();

        // 3. 执行操作
        for (int i = 0; i < 100000; i++) {
            jedis.incr("yy");
        }
        // 4. 释放资源
        jedis.close();

        long endTime = System.currentTimeMillis();
        System.out.println(endTime - startTime);
    }


    @Test
    public void pipelineTest2() {
        long startTime = System.currentTimeMillis();

        // 1. 创建连接池对象
        JedisPool jedisPool = new JedisPool("192.168.153.129", 6379);

        // 2. 获取Jedis对象
        Jedis jedis = jedisPool.getResource();

        // 3. 将命令放进管道
        Pipeline pipelined = jedis.pipelined();
        for (int i = 0; i < 100000; i++) {
            pipelined.incr("xx");
        }

        // 4.执行命令
        pipelined.sync();

        // 5. 释放资源
        jedis.close();

        long endTime = System.currentTimeMillis();
        System.out.println(endTime - startTime);
    }

五. Redis其他配置和集群

修改yml文件, 以方便修改Redis配置文件

version: '3.1'
services:
  redis:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 6379:6379
    volumes:
      - ./conf/redis.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
5.1 Redis的Auth配置

方式一: 通过修改Redis配置文件, 实现Redis的密码校验

# redis.conf
requirepass 密码

三种客户端的连接方式

  1. redis-cli : 在输入正常命令之前, 先输入auth 密码 即可

  2. 图形化界面 : 在连接redis的信息中添加上验证的密码

  3. Jedis客户端:

    第一种 : jedis.auth(password)

    第二种 :

public JedisPool(GenericObjectPoolConfig poolConfig, String host, int port, int timeout, String password) {

}

方式二 : 在不修改redis.conf文件的前提下, 在第一次链接redis时, 输入命令 : config set requirepass 密码, 后续向再次操作redis时,

需要先auth做一下校验

5.2 Redis的事务

Redis的事务 : 一次事务操作, 该成功的成功, 该失败的失败

先开启事务, 执行一系列的命令, 但是密码不会立即执行, 而是把这些命令放到一个队列中, 如果执行事务, 那么这个队列中的命令全部执行,

如果取消了事务, 一个队列中的命令全部作废

  1. 开启事务 : multi
  2. 输入要执行的命令 : 被放到一个队列中
  3. 执行事务 : exec
  4. 取消事务 : discard

Redis的事务想要发挥功能, 需要配置watch监听机制

在开启事务之前, 先通过watch命令去监听一个或多个key, 在开启事务之后, 如果有其他客户端修改了我监听的key, 事务会自动取消

如果执行了事务, 或者取消了事务, watch监听自动消除, 所以一般不需要执行unwatch

5.3 Redis的持久化机制-RDB

RDB是Redis的默认持久化机制

  1. RDB持久化文件, 速度比较快, 而且存储的是二进制文件, 传输起来很方便

  2. RDB持久化的时机:

    save 900 1 : 在900秒内, 有1个key改变了, 就执行RDB持久化

    save 300 10 : 在300秒内, 有10个key改变了, 就执行RDB持久化

    save 60 10000 : 在60秒内, 有10000个key改变了, 就执行RDB持久化

  3. RDB无法保证数据的绝对安全

5.4 Redis的持久化机制-AOF

AOF持久化机制默认是关闭的, Redis官方推荐同事开启RDB和AOF持久化, 更安全, 避免数据丢失

appendonly no ==> appendonly yes

appendfilename “appendonly.aof” : AOF持久化文件名称

  1. AOF持久化的速度, 相对RDB较慢, 存储的是一个文本文件, 到了后期文件会比较大, 传输困难

  2. AOF持久化的时机:

    appendfsync always : 每执行一个写操作, 立即持久化到AOF文件中, 性能比较低

    appendfsync everysec : 每秒执行一次持久化

    appendfsync no : 会根据操作系统的不同, 环境的不同, 在一定时间内执行一次持久化

  3. AOF相对RDB更安全, 推荐同时开启RDB和AOF


同时开启RDB和AOF的注意事项 :

如果同时开启RDB和AOF持久化, 那么在Redis宕机之后, 需要加载一个持久化文件, 优先选择AOF文件

如果先开启了RDB, 执行了持久化以后, 再开启AOF, 那么RDB文件中的内容会被AOF覆盖掉

5.5 Redis的主从架构

单机版Redis存在读写瓶颈问题

主从架构:

  1. 主从复制(步骤)
  2. 单点故障

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zF28MiXa-1641458309854)(C:\Users\123\AppData\Roaming\Typora\typora-user-images\image-20210616102833987.png)]

version: "3.1"
services:
  redis1:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis1
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7001:6379
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis2:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis2
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7002:6379
    volumes:
      - ./conf/redis2.conf:/usr/local/redis/redis.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis3:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis3
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7003:6379
    volumes:
      - ./conf/redis3.conf:/usr/local/redis/redis.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]
  
# redis2和redis3从节点配置
replicaof master 6379
5.6 Redis的哨兵

哨兵模式能够解决Redis主从架构中的单点故障问题

  1. 哨兵之间相互通信
  2. master节点宕机后, 哨兵能够将一个从节点变为主节点, 解决单点故障


为了在容器内容使用哨兵的配置, 需要修改docker-compose.yml

version: "3.1"
services:
  redis1:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis1
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7001:6379
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
      - ./conf/sentinel1.conf:/data/sentinel.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis2:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis2
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7002:6379
    volumes:
      - ./conf/redis2.conf:/usr/local/redis/redis.conf
      - ./conf/sentinel2.conf:/data/sentinel.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis3:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis3
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7003:6379
    volumes:
      - ./conf/redis3.conf:/usr/local/redis/redis.conf
      - ./conf/sentinel3.conf:/data/sentinel.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]

准备哨兵的配置文件, 并且在容器中启动哨兵即可

# 哨兵需要后台启动
daemonize yes
# 指定master节点的IP和端口(主节点配置行, 需要把下面的从节点配置行注释掉)
sentinel monitor master localhost 6379 2
# 指定master节点的IP和端口(从节点配置行, 需要把上面的主节点配置行注释掉)
sentinel monitor master master 6379 2
# 哨兵每隔多久监听一次Redis架构
sentinel down-after-milliseconds master 10000

启动哨兵命令:

redis-sentinel sentinel.conf

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CcSgF9ai-1641458309855)(C:\Users\123\AppData\Roaming\Typora\typora-user-images\image-20210618143400905.png)]

5.7 Redis的集群

Redis集群在保证主从加哨兵的基本功能之外, 还能够提升Redis存储数据的能力

Redis集群架构图


# docker-compose.yml
version: "3.1"
services: 
  redis1:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis1
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7001:7001
      - 17001:17001
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis2:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis2
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7002:7002
      - 17002:17002
    volumes:
      - ./conf/redis2.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis3:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis3
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7003:7003
      - 17003:17003
    volumes:
      - ./conf/redis3.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis4:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis4
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7004:7004
      - 17004:17004
    volumes:
      - ./conf/redis4.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis5:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis5
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7005:7005
      - 17005:17005
    volumes:
      - ./conf/redis5.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis6:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis6
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7006:7006
      - 17006:17006
    volumes:
      - ./conf/redis6.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
# redis.conf
# 指定redis的端口号
port 7001
# 开启Redis集群
cluster-enabled yes
# 集群信息的文件
cluster-config-file nodes-7001.conf
# 集群对外的IP地址
cluster-announce-ip 192.168.153.129
# 集群对外的port
cluster-announce-port 7001
# 集群的总线端口
cluster-announce-bus-port 17001

启动了6个redis的节点

随便跳转到一个容器内部, 使用redis-cli管理集群

# 创建集群
redis-cli --cluster create 192.168.153.129:7001 192.168.153.129:7002 192.168.153.129:7003 192.168.153.129:7004 192.168.153.129:7005 192.168.153.129:7006 --cluster-replicas 1
# 注意: 如果出现Could not connect to Redis No route to host问题, 基本上都是防火墙的问题, 这时有两种解决办法
# 第一种: 关闭防火墙即可(不推荐): systemctl stop firewalld.service
# 第二种: 开放所需要的的端口

# 显示服务的状态
$ systemctl status firewalld.service
# 启动防火墙
$ systemctl start firewalld.service

# 开放7001...7006和17001...17006端口(如果不把总线端口开放, 会出现Waiting for the cluster to join 一直等待的问题)
firewall-cmd --add-port=7001/tcp --permanent
firewall-cmd --add-port=7002/tcp --permanent
firewall-cmd --add-port=7003/tcp --permanent
firewall-cmd --add-port=7004/tcp --permanent
firewall-cmd --add-port=7005/tcp --permanent
firewall-cmd --add-port=7006/tcp --permanent
firewall-cmd --add-port=17001/tcp --permanent
firewall-cmd --add-port=17002/tcp --permanent
firewall-cmd --add-port=17003/tcp --permanent
firewall-cmd --add-port=17004/tcp --permanent
firewall-cmd --add-port=17005/tcp --permanent
firewall-cmd --add-port=17006/tcp --permanent
firewall-cmd --reload

参数解释

1、firwall-cmd:是Linux提供的操作firewall的一个工具;

2、–permanent:表示设置为持久;

3、–add-port:标识添加的端口;

# 查看开放的端口
$ firewall-cmd --list-ports
# 查询7001端口是否开放
$ firewall-cmd --query-port=7001/tcp
# 移除7001端口
firewall-cmd --permanent --remove-port=7001/tcp

集群的连接
# 使用远程连接命令
redis-cli -h 192.168.153.129 -p 7001 -c
# 注意, 如果不加 -c 在执行命令时, 无法进行节点间的自动切换
5.8 java连接Redis集群
@Test
    public void test() {
        Set<HostAndPort> nodes = new HashSet<>();
        nodes.add(new HostAndPort("192.168.153.129", 7001));
        nodes.add(new HostAndPort("192.168.153.129", 7002));
        nodes.add(new HostAndPort("192.168.153.129", 7003));
        nodes.add(new HostAndPort("192.168.153.129", 7004));
        nodes.add(new HostAndPort("192.168.153.129", 7005));
        nodes.add(new HostAndPort("192.168.153.129", 7006));

        JedisCluster jedisCluster = new JedisCluster(nodes);

        String a = jedisCluster.get("c");

        System.out.println(a);
    }

六. Redis常见问题

6.1 Redis的删除策略
# 如果key的生存时间到了, Redis会立即删除掉它吗?
不会立即删除
1. 定期删除:
	Redis每隔一段时间就会去查看设置了过期时间的key, 会在100ms的间隔默认查看3个key
2. 惰性删除:
	如果当你去查询一个key时, Redis会先查看当前key的过期时间, 如果已经过期, 就执行删除当前key, 并且给用户返回一个空值
6.2 Redis的内存淘汰机制

Redis的删除策略导致内存会被填满, 需要设置一个有效的内存淘汰机制

6.3 缓存穿透
6.4 缓存击穿
6.5 缓存雪崩
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值