• Redis 2 - 高级


    一. Linux 安装 redis

    首先说明一下,windows 可以按照 Ubuntu 子系统,本节内容就是基于 windows 下的 Ubuntu 子系统完成的。

    1. 安装 redis

    ## 下载redis包
    wget http://download.redis.io/releases/redis-xxxx.tar.gz
    ## 解压
    tar -zxvf xxx.tar.gz
    ## 编译
    make
    ## 安装
    make install
    ## 启动
    cd src
    redis-server
    ## 客户端登录
    redis-cli
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2. 指定端口启动

    注意不同端口启动的 redis 客户端数据不相通

    ## 服务器启动
    redis-server --port 8081
    ## 客户端连接
    redis-cli -p 8081
    
    • 1
    • 2
    • 3
    • 4

    3. 配置文件启动

    一般开发时我们不会通过命令行启动redis,而是通过配置文件启动。在redis安装目录下,有个redis.conf 配置文件,我们可以修改其中的默认项:

    ## 启动端口
    port 6379
    ## 以守护进程的方式启动(后台启动)
    daemonize yes
    ## 打印的日志文件名称
    logfile "log.log"
    ## 日志文件所在位置
    dir /redis-4.0.0/logs
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    启动时只需带上配置文件即可:

    reids-server redis.conf
    
    • 1

    多服务器公共配置,导入指定文件的配置:

    include /path/xxx.conf
    
    • 1

    二. Redis 持久化

    持久化指将 redis 中的数据备份在硬盘中,防止因为断电等原因导致数据丢失。

    持久化的方式有数据快照(RDB)及过程日志(AOF)两种。

    • RDB 是指每隔一定时间将当前数据状态备份下来;
    • AOF 是存储数据操作日志。

    1. RDB 持久化

    同样在 redis.conf 文件中进行配置:

    ## 设置持久化文件名称(路径与日志文件一致,在dir设置)
    dbfilename dump-6379.rdb
    ## 压缩持久化文件
    rdbcompression yes
    ## 校验持久化文件是否损坏
    rdbchecksum yes
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    手动执行持久化命令:

    1. save
    2. bgsave
    
    • 1
    • 2

    可以看到在设置的存储路径下生成了一个 dump-6379.rdb 持久化文件。
    当 redis 因为断电或其他原因导致数据丢失时,在 redis 再次启动时会自动通过 rdb 文件恢复数据。

    注意:save 指令会阻塞整个 redis 服务器,风险较大,因此线上环境不建议使用 save 命令。而 bgsave 是针对 save的阻塞问题做的优化,在后台开启子进程执行,推荐使用。

    一般在实际生产中,我们不可能自己每次执行 bgsave 命令来保存数据,还是通过配置文件配置的方式由 redis 执行自动保存。修改 redis.conf 文件,添加:

    ## 如 save 100 10,表示在100s之内,如果有10次key的变化,则bgsave保存一次
    save time changes
    
    • 1
    • 2

    2. AOF 持久化

    RDB 的方式当数据量很大时性能较低,且不能做到实时地数据备份。Redis 通过 AOF 记录数据操作步骤来实现实时地高效数据备份。
    通过配置文件 redis.conf 开启 AOF 持久化:

    #默认关闭
    appendonly yes
    #设置aof备份文件的名称
    appendfilename appendonly-6379.aof
    #设置备份方式
    appendfsync always|everysec|no
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三种AOF备份方式,always 是每次操作都备份,everysec 每秒备份一次,no 交于系统管理。

    AOF 重写 可以将一些冗余的备份步骤进行优化,仅保留最后的有效操作,从而大大减小 aof 文件的大小。

    • 手动重写:
    bgrewriteaof
    
    • 1
    • 配置文件配置:
    ## 自动重写的最小大小
    auto-aof-rewrite-min-size size
    ## 自动重写的最小百分比
    auto-aof-rewrite-percentage percent
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3. RDB 与 AOF 对比

    在这里插入图片描述

    • 如果对数据丢失比较敏感,选择 AOF;
    • 如果追求的是大数据的快速恢复,或者是灾备数据恢复,选择 RDB;
    • 可以双保险同时开启,重启时 Redis 优先使用 AOF 恢复数据。

    三. Redis 事务

    首先弄清楚一个问题,Redis 服务端是能识别不同客户端的状态和指令的。本节的 Redis 事务是指一个客户端内的事务。如A客户端开启事务,B客户端此时发起的指令是不会添加到A客户端的事务中的。

    Redis 事务的概念是指将一批指令按照顺序排入队列,指令按照顺序执行,期间不会出现插队、顺序错乱的情况。一个事务中的指令作为一个整体,要么全部执行,要么全部取消。

    1. 基本命令

    开启事务。后续该客户端下所有的指令都不会立即执行,而是加入队列,形成一个事务:

    multi
    
    • 1

    执行事务。队列中的指令按照顺序执行:

    exec
    
    • 1

    取消事务。队列中的指令全部取消执行:

    discard 
    
    • 1

    2. 事务的工作流程

    在这里插入图片描述

    • 注意当处于事务状态时,是没办法再开启事务的;(但是多个客户端可以同时开启事务,相当于同时开启多个队列)
    • 当事务中出现语法错误的指令时,整个事务会被自动销毁,全部指令都无法执行;
    • 当事务中出现执行错误的指令时,其他指令仍然会正常执行,错误指令报错。

    3. watch 锁

    当不希望一个对象被他人修改后自己再做修改,可以对该对象加锁。(如商品补货问题)

    watch 锁必须配合事务一起使用。当对某个对象加锁时,如果该对象中间被修改过,则下一个事务不执行。等执行完 exec 命令后,锁自动释放。

    对某个对象加锁:

    watch key
    
    • 1

    取消所有对象的锁:

    unwatch
    
    • 1

    如下图所示,我们首先对 name 加锁(可以对不存在的对象加锁),然后修改了name(一般情况下是另一个客户端执行了修改),再开启事务,最后执行事务时发现事务未执行:
    在这里插入图片描述

    • watch 只会在数据被其他客户端抢先修改了的情况下通知执行命令的这个客户端(通过 WatchError 异常)但不会阻止其他客户端对数据的修改。
    • watch 只对当前执行该 watch 命令的客户端有效,即只有执行该 watch 命令的客户端会受到锁的影响不执行事务。

    4. 分布式锁

    如果不希望一个对象同时被多个客户端修改导致数据修改错误,可以添加分布式锁。(如商品抢购)

    加锁:

    setnx key value ## key为锁的名称,value值随便
    
    • 1

    释放锁:

    del key
    
    • 1

    每次执行操作之前,必须先获得锁。当同一把锁被客户端A拿到后,在释放之前,该锁不能被客户端B拿到(实现了跨客户端的分布式)。因此保障了数据不被并发修改。
    在这里插入图片描述
    注意,Redis 的分布式锁是一种设计概念,即操作时必须先获得锁再执行命令,如果不按照此项规范执行,是无法起到锁的作用的。

    另外,为防止加锁后发生意外情况导致锁一直未被释放,可以对锁添加过期时间,到期后自动释放锁:

    expire key
    
    • 1

    redis 的分布式锁经常被用在分布式系统中解决并发问题。因为分布式系统,本地锁不起作用,必须依靠分布式锁实现。

    四. 删除策略

    redis 中的过期数据是指时效性已到,但是还没有彻底删除释放内存空间的数据。删除策略有以下三种,定时删除、惰性删除、定期删除。redis 内部一般采用惰性删除和定期删除策略。
    在这里插入图片描述

    1. 定时删除

    数据一到达过期时间就立即删除。能节省内存空间,但是对CPU造成的性能压力大。

    2. 惰性删除

    数据过期时不立即删除,等到下次有指令访问该数据时才进行删除。节约CPU性能,但是对内存造成压力大。

    3. 定期删除

    随机抽查,重点抽查。
    在这里插入图片描述

    4. 驱逐策略

    上述三种删除策略都是针对已过期数据的删除策略。如果内存空间不足时,redis 对未过期的数据也会采用一种驱逐策略释放内存空间,尽量避免 OOM。
    在这里插入图片描述

    五. 高级数据结构

    1. bitmaps

    应用于 redis 中数据的状态统计。按位统计,支持统计 1 的个数、并、或等位操作。(实际应用中该怎么将数据与编号位置对应呢?用哈希算法把对应的数据哈希成一个数字id)

    设置bitmap数据:

    setbit key xx xxx
    
    • 1

    位操作:

    //按位与
    bitop and destKey key1 key2 ...
    //按位或
    bitop or destKey key1 key2 ...
    //按位异或
    bitop xor destKey key1 key2 ...
    //按位取反
    bitop not destKey key1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    统计 1 的个数:

    bitcount key [start end]
    
    • 1

    2. HyperLogLog

    用于统计不重复数据的个数。去重的效果与 set 相似,但是set存储了实际数据,它只存储个数,效率更高。

    pfadd 过滤数据,将不重复数据的个数存储在key中,pfcount 统计个数:

    pfadd key xxx
    
    • 1
    pfcount key
    
    • 1

    将 key2 中的值合并到 key1 中,最终 key1 存储的是 key1 和 key2 不重复数据的个数:

    pfmerge key1 key2
    
    • 1

    注意一点HyperLogLog是估计值,数量大的时候会存在 0.81% 的误差。

    3. GEO

    用于 redis 中的地理位置计算

    geoadd key xxx xxx member
    
    • 1
  • 相关阅读:
    stm32_标准库_2
    Mybatis如何实现一个高效的批量插入操作呢?
    力扣(LeetCode)18. 四数之和(C++)
    acwing算法基础之数学知识--中国剩余定理
    C 练习实例10 打印楼梯,同时在楼梯上方打印两个笑脸。
    雪花算法的使用
    入行IC验证工程师需要提前学习哪些内容?
    2022年下半年信息系统项目管理师上午真题及答案解析
    【概率论与数理统计(研究生课程)】知识点总结1(概率论基础)
    【牛客-剑指offer-数据结构篇】JZ32 从上往下打印二叉树 Java实现
  • 原文地址:https://blog.csdn.net/weixin_39505091/article/details/124643881