redis最全基础学习--未完成

Redis

一、概念

1.概念:Redis是用C语言开发的一个开源的高性能基于内存运行的键值对NoSQL数据库

2.特点:

  • 读写性能优异
  • 持久化
  • 数据类型丰富
  • 单线程
  • 数据自动过期
  • 发布订阅
  • 分布式

二、应用场景

1.高性能适合缓存

2.丰富的数据格式性能更高,应用场景丰富

3.单线程可以作分布式锁

4.自动过期能有效提升开发效率

5.分布式和持久化有效应对海量数据和高并发

Redis常见的应用场景解析 - 知乎 (zhihu.com)

三、安装Redis

这里只讲docker-compose的安装

1.文件目录

— data

— conf

​ — redis.conf

— logs

2.redis.conf

# 端口
port 6379
# 关闭保护模式
protected-mode no
# 日志文件
pidfile /var/run/redis_6379.conf
# 密码
requirepass 你的密码

3.docker-compose.yaml

version: '3.3'
services:
      redis:
        image: redis
        restart: always
        hostname: redis
        container_name: redis
        privileged: true
        ports:
          - 本地开放端口:6379
        environment:
          TZ: Asia/Shanghai
        volumes:
          - ./data:/data
          - ./conf/redis.conf:/etc/redis/redis.conf
          - ./logs:/logs
        command: ["redis-server","/etc/redis/redis.conf"]

四、数据类型

redis是key-value形式存储的,key永远是String类型,value有五种数据类型

1.key

del key

删除key

exists key

判断key是否存在

expire key seconds

设置key的过期时间

move key db

将当前数据库的key移动到给定的数据库db当中

ttl key

以秒为单位,返回给定key的剩余生存时间(time to live)

type key

返回key所存储的值类型

2.String

一个String的value最大可支持512M

set key value

设置指定key的值

get key

获取指定key的值

getrange key start end

返回key中字符串的值

getset key value

讲指定key的值设置为value,并返回key的旧值

mget key1 [key2…]

获取所有(一个或多个)给定key的值

setex key seconds value

将value关联到key,并将key的过期时间设为seconds(以秒为单位)

setnx key value

只有key不存在时,才会设置key的值

setrange key offset value

用value参数覆盖给定key所存储的字符串值,从偏移量offset开始

strlen key

返回key的长度

mset key value [key value]

同时设置多个key-value

incr key

将key的值加一

incrby key increment

将key所存储的值加上给定的增量(increment)

decr key

将key的值减一

decrby key decrement

将key所存储的值减去给定的增量(decrement)

append key value

将在指定key的value末尾加上value

3.List(列表)

底层是一个字符串链表;可以从头到尾添加元素

(1)添加元素时:

​ 如果key不存在,创建新的链表

​ 如果key存在,添加内容

​ 如果key的所有值全部删除,则对应的key也会随之消失

(2)在链表的头尾操作时效率较高,但是对中间元素的操作效率较低

lindex key index

通过索引获取列表中的元素

linsert key before|after pivot value

在列表的元素前或后插入元素

llen key

获取列表长度

lpop key

移出并获取列表的第一个元素

lpush key value1[value2]

将一个或多个值插入列表头部

lrange key start stop

获取列表指定范围内的元素

lrem key count value

从左到右删除count个value值 count为0删除给定所有的值

lset key index value

通过索引设置列表元素的值

ltrim key start stop

对一个列表进行修剪,只保留指定区间的值

rpop key

移除列表最后一个元素,返回值为移除的值

rpoplpush source destination

移除列表最后一个元素,并将该元素添加到另一个列表头部并返回

rpush key value1[value2…]

在列表头部添加一个或多个值

4.Set(集合)

底层通过HashTable实现;是String类型的无重复值的无序集合

sadd key member1[menber2…]

向集合添加成员

scard key

获取集合数量

sdiff key1[key2…]

返回第一个集合与其他集合的差异

sinter kye1[key2…]

返回指定集合与其他集合的交集

sismember key member

判断member是否是集合key的成员

smembers key

返回集合中的所有成员

smove source destination member

将member元素从source集合移动到destination

spop key

移除并返回集合中的一个随机元素

srandmember key [count]

返回集合中一个或多个随机数

serm key member1[member2…]

移除集合中一个或多个成员

sunion key1[key2…]

返回给定集合的并集

4.ZSet(有序集合)

类似Set;

每个元素都会关联一个double类型的分数(score);

Redis通过分数自动的为集合中的 成员进行从小到大的排序;

成员不可重复,分数可以重复

zadd key score1 member1 [score2 member2…]

向有序集合一个或多个成员,或者更新已有成员的分数

zcard key

获取有序集合成员数量

zcount key min max

计算指定分数范围内成员的数量

zrange key start stop [withscores]

通过索引返回有序集合指定区间内的成员,withscores是否要带分数

zrank key member

返回有序集合中指定成员的索引

zrem key member1[member2…]

移除有序集合中一个或多个成员

zrevrange key start stop [withscores]

返回有序集合中指定区间内的成员,通过索引,分数从高到底

zrevrangebyscore key max min [withscores]

返回有序集合中指定分数区间内的成员

zrevrank key member

返回有序集合中指定成员的排名,有序集成员按分数值递减(从小到大)排序

5.Hash(哈希)

类似Java中的Map<String, Object>;是一个键值对集合;适合存储对象

hdel key field1(field2)

删除一个或多个哈希表字段

hexists key field

查看hash表key中,是否有指定的字段

hget key field

获取存储在hash表中指定字段的值

hgetall key field

获取hash表中指定key所有字段和值

hincrby key field increment

为hash表key中指定字段的整数值上增量increment

hincrbyfloat key field increment

为hash表key中指定字段的浮点数加上增量increment

hkeys key

获取所有哈希表中的字段

hlen key

获取哈希表中字段的数量

hmget key field1[field2…]

获取所有给定字段的值

hmset key field1 value1[field2 value2]

同时将多个field-value设置到哈希表中

hset key field value

将哈希表key中的字段field的值设为value

hsetnx key field value

只有在字段field不存在时,设置哈希表字段的值

hvals key

获取哈希表中所有值

6.常用查询命令

keys pattern

查询模式规则

  • 匹配任意数量的任意符号 *

  • 配合一个任意符号 ?

  • 匹配一个指定符号 []

  • 匹配一个指定符号 []

**keys ***

查询所有

keys abc*

查询以it开头的

keys * abc

查询以it结尾的

keys ??abc

查询任意两个字符开头 abc结尾的

key abc[de]z

查abc开头z结尾,中间带有d或e的

五、Spring整合redis

1.引入依赖
<!-- 版本自己选 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.填写yaml配置
spring:
    redis:
        # redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突
        database: 1
        # redis服务器地址(默认为loaclhost)
        host: localhost
        # redis端口(默认为6379)
        port: 6379
        # redis访问密码(默认为空)
        password: 123456
        # redis连接超时时间(单位毫秒)
        timeout: 0
        # redis连接池配置
        pool:
          # 最大可用连接数(默认为8,负数表示无限)
          max-active: 8
          # 最大空闲连接数(默认为8,负数表示无限)
          max-idle: 8
          # 最小空闲连接数(默认为0,该值只有为正数才有用)
          min-idle: 0
          # 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
          max-wait: -1
3.编写配置类

RedisConfig

两个bean序列化方式不同

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    @Bean("fastJsonRedis")
    @SuppressWarnings(value = {"unchecked", "rawtypes"})
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);

        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }


    @Bean("StringRedis")
    public RedisTemplate<String, Object> redisTemplate2(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(factory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        redisTemplate.setKeySerializer(stringRedisSerializer); // a
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(stringRedisSerializer); // b
        redisTemplate.setHashValueSerializer(stringRedisSerializer);

        return redisTemplate;
    }
}

fastjson的序列化

public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    public FastJson2JsonRedisSerializer(Class<T> clazz)
    {
        super();
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException
    {
        if (t == null)
        {
            return new byte[0];
        }
        return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException
    {
        if (bytes == null || bytes.length <= 0)
        {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);

        return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
    }
}

六、Redis持久化

1.RDB持久化

1.1 概念

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。快照文件称为RDB文件,默认是保存在当前运行目录。

1.2 执行时机
  • 执行save命令

    save命令会导致主进程执行RDB,这个过程中其它所有命令都会被阻塞。只有在数据迁移时可能用到。

  • 执行bgsave命令

    命令执行后会开启独立进程完成RDB,主进程可以持续处理用户请求,不受影响。

  • Redis停机时

    Redis停机时会执行一次save命令,实现RDB持久化。

  • 触发RDB条件时

    Redis内部有触发RDB的机制,可以在redis.conf文件中找到,格式如下:

    # 900秒内,如果至少有1个key被修改,则执行bgsave , 如果是save "" 则表示禁用RDB
    save 900 1  
    save 300 10  
    save 60 10000 
    
1.3 配置
# 是否压缩 ,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
rdbcompression yes

# RDB文件名称
dbfilename dump.rdb  

# 文件保存的路径目录
dir ./ 
1.4 原理

bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。

fork采用的是copy-on-write技术:

  • 当主进程执行读操作时,访问共享内存;
  • 当主进程执行写操作时,则会拷贝一份数据,执行写操作。

2.AOF持久化

2.1 概念

AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。

2.2 配置

AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:

# 是否开启AOF功能,默认是no
appendonly yes
# AOF文件的名称
appendfilename "appendonly.aof"

AOF的命令记录的频率也可以通过redis.conf文件来配:

# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always 
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec 
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no

三种策略对比:

配置项刷盘时机优点缺点
Always同步刷盘可靠性高几乎不丢数据性能影响大
everysec每秒刷盘性能适中最多丢失1秒数据
no操作系统控制性能最好可靠性差,可能丢失大量数据
2.3 AOF文件重写

AOF记录的命令文件过大,redis会通过重写功能优化,缩小文件大小;

通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果;

Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置:

# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写 
auto-aof-rewrite-min-size 64mb 

3.RDB和AOF对比

RDB和AOF各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。

RDBAOF
持久化方式定时对整个内存作快照记录一次执行的命令
数据完整性不完整,两次备份之间会丢失相对完整,取决于刷盘策略
文件大小会有压缩,体积小记录命令,文件格式大
宕机恢复速度很快
数据恢复优先级低,数据完整性不如AOF高,因为数据完整性更高
系统资源占用高,大量CPU和内存消耗低,主要是磁盘IO资源,单AOF重写时会占用大量CPU和内存资源
使用场景可以容忍数分钟的数据丢失,追求更快的启动速度对数据安全性要求较常见

七、Redis主从

1.搭建主从结构

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。

1.1 文件目录结构

这里只展开redis-1,剩下五个目录结构和redis-1一样

记得给权限 chmod 777 文件目录 -R

— docker-compose.yaml

— redis-1

​ — data

​ — conf

​ — redis.conf

​ — logs

— redis-2

— redis-3

— redis-4

— redis-5

— redis-6

1.2 配置文件

注意:

因为有六个要准备六个不同的端口;

除了上面六个redis端口,还需要准备六个redis之间进行通信的端口,;

​ 例如:redis端口6379 ,那么16379必须打开(总线端口=redis端口+10000)

# 端口
port 6379
# 关闭保护模式
protected-mode no
# 日志文件
pidfile /var/run/redis_6379.conf
# 密码
requirepass 你的密码
# 主节点密码
masterauth 你的密码
# 开启集群
cluster-enabled yes 
# 集群配置文件
cluster-config-file nodes.conf
# 集群节点多少时间未响应视为该节点丢失
cluster-node-timeout 5000
# 开启AOF持久化
appendonly yes
1.3 docker-compose.yaml
version: '3.1'
services:
  # redis1配置
  redis1:
    image: daocloud.io/library/redis:6.0.4
    container_name: redis-1
    restart: always
    network_mode: "host"
  	environment:
      - REDISCLI_AUTH=你的密码
    volumes:
      - ./redis-1/conf/redis.conf:/usr/local/etc/redis/redis.conf
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # redis2配置
  redis2:
    image: daocloud.io/library/redis:6.0.4
    container_name: redis-2
    restart: always
    network_mode: "host"
  	environment:
      - REDISCLI_AUTH=你的密码
    volumes:
      - ./redis-2/conf/redis.conf:/usr/local/etc/redis/redis.conf
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # redis3配置
  redis3:
    image: daocloud.io/library/redis:6.0.4
    container_name: redis-3
    restart: always
    network_mode: "host"
  	environment:
      - REDISCLI_AUTH=你的密码
    volumes:
      - ./redis-3/conf/redis.conf:/usr/local/etc/redis/redis.conf
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # redis4配置
  redis4:
    image: daocloud.io/library/redis:6.0.4
    container_name: redis-4
    restart: always
    network_mode: "host"
  	environment:
      - REDISCLI_AUTH=你的密码
    volumes:
      - ./redis-4/conf/redis.conf:/usr/local/etc/redis/redis.conf
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # redis5配置
  redis5:
    image: daocloud.io/library/redis:6.0.4
    container_name: redis-5
    restart: always
    network_mode: "host"
  	environment:
      - REDISCLI_AUTH=你的密码
    volumes:
      - ./redis-5/conf/redis.conf:/usr/local/etc/redis/redis.conf
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # redis6配置
  redis6:
    image: daocloud.io/library/redis:6.0.4
    container_name: redis-6
    restart: always
    network_mode: "host"
  	environment:
      - REDISCLI_AUTH=你的密码
    volumes:
      - ./redis-6/conf/redis.conf:/usr/local/etc/redis/redis.conf
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]

注意:复制的话格式要注意缩进

1.4 查看启动状态
docker ps

1668590000045

1.5 开启集群

进入其中一个集群

docker exec -it redis-1 bash

进入容器后执行下面命令

# localhost 填你的宿主机地址 端口是你的六个端口
redis-cli --cluster create localhost:6379 \
localhost:6380 \
localhost:6381 \
localhost:6382 \
localhost:6383 \
localhost:6384 \
--cluster-replicas 1

出现下面就说明成功了,

redis之间一定要能相互ping通

(没有就看看你的总线端口打开了吗)

1668590987266

1.6 测试

在有客户端的地方连接其中一个redis

有客户端的地方:随便一个容器里面就可以

redis-cli -c -h 你的端口 -p 你的端口 -a 你的密码

1668591375484

执行命令

set test 123
get test

1668591543706

注意:这里根据切片自动切换到了该数据分片所在的节点上,所以下面可以看到连接的节点变为了02端口

2.主从数据同步原理

2.1 全量同步

主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点,流程:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值