美文网首页DBA数据库学习
DBA数据库笔记之(七)Redis基础知识

DBA数据库笔记之(七)Redis基础知识

作者: Mr培 | 来源:发表于2024-01-20 13:58 被阅读0次

    Redis常见类型及常见命令

    redis应用场景

    1. 缓存
    2. 计数器
    3. 排行榜
    4. 地理位置
    5. 队列
    6. 评论和弹幕

    Redis6安装启动

    redis官网安装教程

    • 源码编译安装
    # 源码编译安装
    wget https://download.redis.io/releases/redis-6.2.13.tar.gz
    # 解压
    tar zxvf redis-6.2.13.tar.gz
    # 安装redis依赖
    yum install gcc -y
    # 进入解压包
    cd redis-6.2.13/
    # PREFIX指定软件安装的路径
    make && make install PREFIX=/usr/local/redis6
    # 创建其它目录文件
    make /data/redis7001/{conf,data,log} -p
    
    • 编辑配置文件
    vim /data/redis7001/conf/redis.conf
    # 内容
    # 启动端口
    port 7001
    # yes后台运行
    daemonize yes
    # 指定redis进程pid文件路径
    pidfile "/data/redis7001/data/redis.pid"
    # redis日志的详细程度
    loglevel notice
    # 日志文件的路径和文件名
    logfile "/data/redis7001/log/redis.log"
    # 支持的数据库数量
    databases 16
    # redis的快照条件;1800秒以内只要有一次更改就执行一次快照保存(rdb落盘)
    #save 1800 1
    # rdb文件名称
    dbfilename "dump.rdb"
    # 持久性文件的目录
    dir "/data/redis7001/data"
    
    # 运行使用的最大内存量
    maxmemory 1gb
    # 当redis内存达到上限时所使用的淘汰策略
    maxmemory-policy volatile-lru
    
    # 是否开启aof持久化
    appendonly no
    # aof日志文件的名称
    appendfilename "appendonly.aof"
    # 慢查询时间的预值 单位 微秒
    slowlog-log-slower-than 10000
    # 慢查询日志的最大长度,最多记录多少条慢查询
    slowlog-max-len 128
    
    # redis的密码;生产环境建议设置密码
    requirepass "IdfaUqTcdad82"
    
    • 启动并登录redis
    /usr/local/redis6/bin/redis-server /data/redis7001/conf/redis.conf
    # 查看是否启动
    ps -ef | grep redis 
    
    # 修改环境变量
    vim /etc/profile
    # 增加
    export PATH="/usr/local/redis6/bin:$PATH"
    source /etc/profile
    
    redis-cli -v
    
    # 登录redis
    redis-cli -p 7001 -a IdfaUqTcdad82
    
    • redis常用数据类型
    数据类型 描述
    string 字符串类型,一个key对应一个value
    hash 键值对集合
    list 字符串列表,按插入顺序排队
    set string类型的无序集合,集合中元素是唯一的
    zset 有序集合,它类似于SET,但每个元素都会关联一个分数(score),分数用来对元素进行排序
    HyperlogLog 用于估计集合基数的数据类型
    bitmap 用户存储位数据,适用于布尔值和计数值
    GEO 存储地理位置数据,支持地理位置相关操作

    常用数据类型的用法

    • string
    # 设置
    set string_test aaa
    # 获取
    get string_test
    # 删除
    del string_test
    
    # 计数
    incr count_test
    # 增加指定计数量
    incrby count_test 3
    # 减去
    decr count_test
    # 减去指定数量
    decrby count_test 2
    # 查询
    get count_test
    
    • hash
    # 设置
    hset user:01 name martin
    hset user:01 age 18
    # 获取
    hget user:01 name
    # 获取所有字段和值
    hgetall user:01
    # 获取hash表中字段数量
    hlen user:01
    # 获取hash表中所有字段
    hkeys user:01
    # 删除某个字段
    hdel user:01 age
    
    • list
    # 插入列表头部
    lpush list_test aaa
    lpush list_test bbb
    # 获取所有元素
    lrange list_test 0 -1
    # 插入到列表尾部
    rpush list_test ccc
    # 获取指定范围的元素
    lrange list_test 0 0
    # 查询前两个元素
    lrange list_test 0 1
    # 获取列表长度
    llen list_test
    # 移除并且获取列表的第一个元素
    lpop list_test
    # 移除并且获取列表的最后一个元素
    rpop list_test
    
    • set
    # 添加元素
    sadd set_test one
    # 添加多个元素2
    sadd set_test two three
    # 返回集合中所有元素
    smembers set_test
    # 判断元素是否在集合中 返回1代表存在;0不存在
    sismember set_test onne
    # 删除集合中的元素
    srem set_test two
    
    • zset
    # 添加元素
    zadd zset_test 1 zhangshan
    zadd zset_test 2 lishi
    zadd zset_test 3 wangwu
    # 查看元素
    zrange zset_test 0 -1
    # 查看元素和分数
    zrange zset_test 0 -1 withscores
    # 获取指定元素的分数
    zscore zset_test "lishi"
    # 从有序集合中移除元素
    zrem zset_test "lishi"
    # 获取有序集合元素个数
    zcard zset_test
    
    • HyperlogLog
    # 添加元素
    pfadd hll_test "apple" "banana" "cherry"
    # 获取集合中元素数量
    pfcount hll_test
    
    • bitmaps
    # 签到场景
    # 第一天有签到记录
    setbit user:1001 0 1
    # 第二天有签到记录
    setbit user:1001 1 1
    # 第三天没有签到记录
    setbit user:1001 2 0
    setbit user:1001 4 1
    # 查看某一天是否签到
    getbit user:1001 1
    getbit user:1001 2
    # 统计签到数量
    bitcount user:1001
    
    • GEO
    # 增加地理位置
    geoadd geo_test 20 30 "a"
    geoadd geo_test 40 60 "b"
    # 求a和b之前的距离 单位km
    geodist geo_test "a" "b" km
    # 查询指定范围的地点 经度 25 纬度 35 范围1000km以内的地点
    georadius geo_test 25 35 1000 km
    

    redis常用管理命令

    • 在redis中认证
    redis-cli -p 7001 -a IdfaUqTcdad82
    或者
    redis-cli -p 7001
    auth IdfaUqTcdad82
    
    • 查看服务器的各种信息
    info 
    # 查看某一块的信息
    info CPU
    

    redis info官方文档

    • 查看所有的key
    keys *
    
    • 查看某个前缀的key
    keys name*
    
    • 找到某个前缀的key并删除
    # 查找以name开头的key。--scan 扫描,--pattern 模式匹配 
    redis-cli -p 7001 -a IdfaUqTcdad82 --scan --pattern "name*" 
    # 并且删除,xargs 代表对前面的结果进行处理,-L 5000  每次处理5000条数据
    redis-cli -p 7001 -a IdfaUqTcdad82 --scan --pattern "name*" | xargs -L 5000 redis-cli -p 7001 -a IdfaUqTcdad82 del
    
    • 重命名key
    set hehe 1111
    # 改名,重复会覆盖
    rename hehe hehe_bak
    get hehe_bak
    
    或者
    set one 111
    # renamenx 新名字必须是之前不存在的
    renamenx one two
    
    • 判断key是否存在
    # 返回 1 存在,0不存在
    exists hehe
    
    • 查看key类型
    type hehe_bak
    
    • 查看key大小
    # 单位字节
    memory usage hehe_bak
    
    • 查看key的内部信息
    debug object hehe_bak
    # key存放的内存地址:引用计数:键的编码方式:key的序列化长度:key的lru值,最近最少使用的值:键自从上一次访问的空闲时间
    
    • 设置key的过期时间
    set martin 111
    # 300秒过期
    expire martin 300
    # 查看过期时间
    ttl martin
    # 移除key的过期时间
    persist martin
    
    • 发布订阅
    # 第一个窗口
    SUBSCRIBE chat
    # 第二个窗口
    PUBLISH chat "hello redis"
    # 第一个窗口就会收到对应的消息
    
    • 切换数据库
    # 默认在0数据库,切换到2
    select 2
    set aaa 111
    info keyspace
    
    • 返回当前库key的数量
    dbsize
    
    • 清空当前数据库的所有key
    flushdb
    
    • 清空redis
    flushall
    
    • 查看和修改配置
    # 查看所有配置
    config get *
    # 查看最大内存
    config get maxmemory
    # 查看包含关键字的配置
    config get *memory*
    # 修改配置
    config set maxmemory 2G
    # 将修改的配置持久化到配置文件
    config rewrite
    
    # 查看配置文件
    vim /data/redis7001/conf/redis.conf
    
    • 获取慢查询日志
    # 获取5条
    slowlog get 5
    # 查看与慢查询有关的参数
    config get slow*
    # slowlog-max-len 最多记录多少条慢查询记录;slowlog-log-slower-than 超过这个时间就会记录到慢查询,单位微秒
    
    • 查看客户端连接
    client list
    
    • 杀掉某个连接
    client kill 192.168.12.162:50732
    
    • 命令行直接执行命令
    redis-cli -p 7001 -a IdfaUqTcdad82 info
    redis-cli -p 7001 -a IdfaUqTcdad82 client list
    
    • 让redis服务崩溃
    debug segfault
    ps -ef | grep 7001
    # 启动
    /usr/local/redis6/bin/redis-server /data/redis7001/conf/redis.conf
    
    • 关闭redis服务器
    # 在redis命令里执行,建议此方式关闭redis
    shutdown
    

    详解Redis RDB

    把内存中的数据存储到磁盘中,当redis重启会读取RDB文件恢复数据

    几种RDB持久化场景

    • 手动执行RDB持久化
    # 这个命令会在主线程执行,会导致阻塞,线上环境禁止使用
    save
    # 启用子进程来持久化,避免主线程阻塞
    bgsave
    # 查看数据目录
    config get dir
    # 确定bgsave是否正确执行,查看RDB相关参数
    info persistence
    

    loading:0 ;当前是否在进行RDB文件的加载操作
    current_cow_size:0 ;写时复制技术占用的内存
    current_cow_size_age:0 ;上一次current_cow_size的时间,单位秒
    current_fork_perc:0.00 ;当前fork进程的进度百分比
    current_save_keys_processed:0 ;当前RDB操作已处理keys的数量
    current_save_keys_total:0 ;当前RDB持久化进程一共需要处理的键数量
    rdb_changes_since_last_save:0 ;从上一次执行RDB以来更改的数量
    rdb_bgsave_in_progress:0 ;是否有RDB持久化的后台进程正在进行,0表示RDB已经操作完成
    rdb_last_save_time:1694702221 ;上次执行RDB持久化的时间戳
    rdb_last_bgsave_status:ok ;上次执行RDB持久化的执行状态
    rdb_last_bgsave_time_sec:0 ;上一次执行RDB持久化所花费的时间
    rdb_current_bgsave_time_sec:-1 ;当前正在执行的RDB持久化操作花费的时间
    rdb_last_cow_size:409600 ;上一次RDB持久化操作中使用的写时复制技术的内存大小
    aof_enabled:0 ;
    aof_rewrite_in_progress:0 ;
    aof_rewrite_scheduled:0 ;
    aof_last_rewrite_time_sec:-1 ;
    aof_current_rewrite_time_sec:-1 ;
    aof_last_bgrewrite_status:ok ;
    aof_last_write_status:ok ;
    aof_last_cow_size:0 ;
    module_fork_in_progress:0 ;
    module_fork_last_cow_size:0 ;

    • 配置自动执行RDB持久化
    # 查看配置文件
    vim /data/redis7001/conf/redis.conf
    
    # 启动端口
    port 7001
    # yes后台运行
    daemonize yes
    # 指定redis进程pid文件路径
    pidfile "/data/redis7001/data/redis.pid"
    # redis日志的详细程度
    loglevel notice
    # 日志文件的路径和文件名
    logfile "/data/redis7001/log/redis.log"
    # 支持的数据库数量
    databases 16
    
    # redis的快照条件;1800秒以内只要有一次更改就执行一次快照保存(rdb落盘)
    #⚠️save 1800 1  新增下列三行参数
    save 900 1
    save 300 10
    save 60 10000
    
    # rdb文件名称
    dbfilename "dump.rdb"
    # 持久性文件的目录
    dir "/data/redis7001/data"
    
    # 运行使用的最大内存量
    maxmemory 1gb
    # 当redis内存达到上限时所使用的淘汰策略
    maxmemory-policy volatile-lru
    
    # 是否开启aof持久化
    appendonly no
    # aof日志文件的名称
    appendfilename "appendonly.aof"
    # 慢查询时间的预值 单位 微秒
    slowlog-log-slower-than 10000
    # 慢查询日志的最大长度,最多记录多少条慢查询
    slowlog-max-len 128
    
    # redis的密码;生产环境建议设置密码
    requirepass "IdfaUqTcdad82"
    
    
    # 重启 或者在redis命令行执行
    config set save "900 1"
    
    • 其他触发RDB持久化的场景

    在新建redis主从复制的时候,主节点会执行一次bgsave保存RDB文件到本地,然后再发送给从节点;
    在执行shutdown的时候,如果没有开启aof就会自动执行bgsave将内存中的数据进行落盘,保证在启动的时候数据不会丢失。

    RDB扩展

    • 备份恢复测试
    • RDB压缩
    # 查看配置参数 默认开启,建议开启
    config get rdbcompression
    
    • 临时修改RDB路径
    # 创建目录
    mkdir /data/redis7001/tem_data
    # 修改路径
    config get dir
    config set dir /data/redis7001/tem_data/
    
    # 测试
    bgsave
    

    RDB注意事项

    • bgsave对redis也是有影响的
      建议在从库落盘
    • 单机多实例的RDB备份尽量错开
    • RDB持久化并不能保证所有数据落盘

    详解Redis AOF

    AOF介绍

    • 什么是AOF?

    它会记录Redis收到的每一条写命令,如果Redis发生了崩溃,重启之后就会更具日志文件的内容将写操作重头到尾执行一次,以完成数据的恢复。

    • 开启AOF日志
    vim /data/redis7001/conf/redis.conf
    # 修改参数
    appendonly yes
    # 启动
    
    # 查看配置
    config get appendonly
    # 动态修改
    config set appendonly yes
    
    • AOF的内容
    # 默认在数据目录
    

    AOF相关配置

    • AOF持久化选项
    config get appendfsync
    

    everysec :表示每秒写回,每个写命令执行完,只是先把日志写到AOF的内存缓存区,每隔一秒把缓冲区中的内容写到磁盘
    always :表示同步写回,每个写命令执行完立马同步到磁盘
    no :表示操作系统控制写回,每个写命令执行完只是先把日志写到AOF的内存缓存区,由操作系统决定何时将缓存区的内容写回到磁盘
    配置建议: 对性能要求很高并且对数据可靠性要求不高 no;高可靠性保证always;允许数据有一点丢失,性能不受太大影响 everysec。

    • AOF重写机制

    如果实例运行比较久并且修改比较频繁那么Redis的AOF文件可能会比较大,通过AOF重写机制解决。会把AOF的内容重写只保留可以恢复数据的最小指令集。
    AOF文件为什么可以变小?

    1. 旧日志文件中的多条命令再重写后新日志中就变成了一条命令
    2. 已经过期的key就不再写入新的AOF文件中
    # 手动触发一次AOF重写
    bgrewriteaof
    
    # 配置参数让AOF自动触发重写,超过一次这个大小就会触发一次AOF重写
    config get "auto-aof-rewrite-min-size"
    # 当前AOF文件空间超过上一次重写后AOF文件空间的多少百分比就会触发重写
    config get "auto-aof-rewrite-percentage"
    
    • AOF相关状态参数
    info persistence
    

    loading:0 ;当前是否在进行RDB文件的加载操作
    current_cow_size:0 ;写时复制技术占用的内存
    current_cow_size_age:0 ;上一次current_cow_size的时间,单位秒
    current_fork_perc:0.00 ;当前fork进程的进度百分比
    current_save_keys_processed:0 ;当前RDB操作已处理keys的数量
    current_save_keys_total:0 ;当前RDB持久化进程一共需要处理的键数量
    rdb_changes_since_last_save:0 ;从上一次执行RDB以来更改的数量
    rdb_bgsave_in_progress:0 ;是否有RDB持久化的后台进程正在进行,0表示RDB已经操作完成
    rdb_last_save_time:1694702221 ;上次执行RDB持久化的时间戳
    rdb_last_bgsave_status:ok ;上次执行RDB持久化的执行状态
    rdb_last_bgsave_time_sec:0 ;上一次执行RDB持久化所花费的时间
    rdb_current_bgsave_time_sec:-1 ;当前正在执行的RDB持久化操作花费的时间
    rdb_last_cow_size:409600 ;上一次RDB持久化操作中使用的写时复制技术的内存大小
    aof_enabled:0 ;AOF是否开启
    aof_rewrite_in_progress:0 ;是否有AOF重写操作正在进行
    aof_rewrite_scheduled:0 ;是否有AOF重写操作已经被调度
    aof_last_rewrite_time_sec:-1 ;上一次AOF重写操作的执行时间
    aof_current_rewrite_time_sec:-1 ;当前正在执行的AOF重写操作花费的时间
    aof_last_bgrewrite_status:ok ;上一次AOF重写操作的执行状态
    aof_last_write_status:ok ;上一次AOF写入操作的执行状态
    aof_last_cow_size:0 ;上一次AOF操作中使用的cow机制内存大小,cow=copy on write 写时复制技术
    module_fork_in_progress:0 ;
    module_fork_last_cow_size:0 ;
    aof_current_size:127 ;AOF当前大小
    aof_base_size:127 ;AOF基础大小
    aof_pending_rewrite:0 ;等待执行AOF重写的数量
    aof_buffer_length:0 ;AOF缓冲区的大小
    aof_rewrite_buffer_length:0 ;AOF重写缓冲区的大小
    aof_pending_bio_fsync:0 ;等待执行AOF fsync操作的数量
    aof_delayed_fsync:0 ;延迟执行AOF fsync操作的数量

    • 重启通过AOF恢复数据
    1. 写入数据
    2. 关闭Redis并删除RDB文件
    shutdown
    ps -ef | grep redis
    cd /data/redis7001/data/
    rm -rf dump.rdb
    
    1. 再启动Redis并确定数据
    • AOF异常恢复实验
    1. 构造AOF异常场景
      修改AOF文件
    2. 重启尝试
    shutdown
    # 再重启,无法正常启动
    # 去查看日志
    cd /data/redis7001/log/
    tail -f redis.log
    
    1. 修复AOF文件
    redis-check-aof --fix ../data/appendonly.aof
    # 再启动redis
    

    Redis 7.0 AOF变化

    • 安装Redis7.0
    • 7.0配置AOF单独目录
    • 7.0的3个AOF文件
    # 控制AOF文件夹的名字
    config get appenddirname
    # 开启AOF
    config set appendonly yes
    # 进入数据目录,有个默认的文件夹 appendonlydir
    cd /data/redis7201/data/
    cd appendonlydir 
    ls
    

    .base.rdb ;基础的AOF,一个
    .incr.aof ;增量AOF,可以有多个
    .aof.manifest ;AOF的清单文件

    AOF的一些相关问题

    • Redis采用AOF而不是WAL的原因

    WAL :很多数据库都是采用WAL,先把修改的数据记录到日志中再进行写数据的提交,可以方便通过日志进行数据恢复
    AOF :先执行写命令,再把数据写入到内存中再写日志文件;可以避免错误命令的情况,AOF是在命令执行后再记录日志所以不会堵塞当前的写操作

    • AOF和RDB都开启,重启使用什么来恢复数据?
      Redis会使用AOF来恢复数据,AOF数据更完整。
    • AOF的优势和劣势
      优势:丢数据的概率低,且可读性强
      劣势:比RDB更占空间,因为记录的是每一条写命令,且AOF恢复数据恢复速度慢很多,每一次读写都落盘性能也会有点问题。

    建议:只做缓存建议都不开启,当数据库用需要备份,可以在从库开启AOF和RDB落盘

    Redis主从复制

    准备复制环境

    • 配置Redis主从复制
    # 在从库 
    # 配置主库的密码
    config set masterauth IdfaUqTcdad82
    # 建立关系,配置主库的ip和端口
    replicaof 192.168.12.161 7001 
    
    # 主从关系配置持久化
    vim /data/redis7001/conf/redis.conf
    # 新增参数
    masterauth "IdfaUqTcdad82"
    replicaof 192.168.12.161 7001 
    
    • 查看复制信息
    # 在从库redis
    info replication
    
    • 确定数据同步

    Redis复制原理

    Redis复制原理.jpg

    复制相关维护

    • 判断主从延迟
    # 在主节点执行
    info replication
    

    slave0:ip=192.168.12.162,port=7001,state=online,offset=77035,lag=1
    offset 表示从库的偏移量
    master_repl_offset:77035 主库的偏移量,两个一样代表没有延迟

    • 网络闪断导致全量复制
    config get repl-backlog-size
    
    • 断开复制关系
    # 在从库redis,情况主节点信息;断开后不会清除已经复制的数据
    replicaof no one
    

    复制架构调整

    • 更换主节点
    # 建立复制关系
    config set masterauth IdfaUqTcdad82
    replicaof 192.168.12.161 7001 
    info replication
    
    # 切换主节点,切换主节点会删除已经复制的数据然后复制新主节点的数据
    replicaof 192.168.12.163 7001 
    
    • 级联复制配置
    # 161->162->163
    #在 162执行
    replicaof no one
    config set masterauth IdfaUqTcdad82
    replicaof 192.168.12.161 7001
    # 在 163执行
    replicaof no one
    config set masterauth IdfaUqTcdad82
    replicaof 192.168.12.162 7001
    
    # 查看复制状态
    info replication
    
    # 如果需要配置持久化
    config rewrite
    
    • 复制相关建议
    1. 建议在低峰时进行新的主从配置
    2. 建议一个主节点别挂载太多的从节点
    3. 建议一台物理机上运行尽可能少的主节点

    Redis主从之哨兵

    哨兵的工作流程

    Redis哨兵的工作流程.jpg

    哨兵的选主逻辑

    • 首先:优先级靠前的
    # 参数越小优先级越高
    config get replica-priority
    
    • 其次:便宜量最大的
    info replication
    # salve_repl_offset 越大同步越靠前
    
    • 再次:ID最小的

    部署哨兵集群

    • 配置一主两从架构
    # 清空两台从库配置关系
    replicaof no one
    
    # 每个实例修改
    config set masterauth IdfaUqTcdad82
    # 在两个从库执行
    replicaof 192.168.12.161 7001
    
    # 在主库查看信息
    info replication
    
    • 配置哨兵文件
    # 在每个Redis实例 创建哨兵文件夹(3个)
    mkdir /data/sentinel26379/{data,conf,log} -p
    # 在每个节点增加配置文件(3个)
    vim /data/sentinel26379/conf/sentinel.conf
    
    # 哨兵端口
    port 26379
    # 后台运行
    daemonize yes
    # 日志文件
    logfile "/data/sentinel26379/log/26379.log"
    # 数据目录
    dir /data/sentinel26379/data/
    # sentinel监控的Redis,监控的集群名是mymaster,主的ip和端口,2表示至少有两个哨兵同意就进行故障切
    sentinel monitor mymaster 192.16812.161 7001 2
    # 被监控Redis的密码
    sentinel auth-pass mymaster IdfaUgTcdad82
    # 判断Reids 主观下线的阈值,单位毫秒
    sentinel down-after-milliseconds mymaster 10000
    
    • 启动哨兵
    # 在每个实例启动
    redis-sentinel /data/sentinel26379/conf/sentinel.conf
    # 查看是否启动
    ps -ef|grep sentinel
    # 哨兵启动后会在配置文件自动新增一些参数
    

    哨兵常用命令

    • 显示其他哨兵的状态
    # 登录哨兵
    redis-cli -p 26379
    # 显示其他哨兵的状态
    sentinel sentinels mymaster
    
    • 显示要监控的集群状态
    sentinel masters
    # 查看某一个master的状态
    sentinel master mymaster
    # 查看某一个master的地址
    sentinel get-master-addr-by-name mymaster
    # 查看被监控主的从库状态
    sentinel replicas mymaster
    
    • 强制进行故障转移
    sentinel failover mymaster
    # 查看
    sentinel get-master-addr-by-name mymaster
    # 在去新的主查看
    info replication
    

    Go程序通过哨兵操作Redis

    1. 通过chatgpt编写操作Redis的程序

    编写一个Go程序,能连接Redis的哨兵,有3个哨兵实例19216812161:26379,19216812162:26379,19216812163:26379,Redis密码是xxx
    帮忙每秒往Redis里面写一个唯一的key
    写入成功,输出success;
    写入失败,输出错误,但是循环继续

    1. 修改代码(redis密码)
    2. 测试代码

    故障切换测试

    1. 关闭住主实例并查看程序输出
    # 关闭主
    info replication
    shutdown
    
    1. 分析故障恢复过程的哨兵日志
    # 查看日志文件
    tail -n 30 /data/sentinel26379/log/26379.log
    
    1. 确定新的复制架构
    # 在新主查看信息
    info replication
    # 再启动关闭的实力
    redis-sentinel /data/sentinel26379/conf/sentinel.conf
    # 再查看信息
    info replication
    

    关于哨兵的建议

    1. 至少需要3个sentinel实例才能实现稳健的部署
    2. sentinel放在不同的机柜上
    3. 需要保证客户端支持sentinel

    Redis Cluster架构

    Redis Cluster架构.jpg

    Redis Cluster部署

    需要部署六台redis

    • 让chatgpt编写Redis部署脚本
      ⚠️... ...
      在每台实例运行部署脚本(三台服务器,每台安装2个redis)
    # 与常规安装redis相比新增集群参数
    # 开启集群
    cluster-enabled yes
    cluster-config0file /data/redis8001/data/nodes8001.conf
    # 节点的超时事件,毫秒
    cluster-node-timeout 5000
    
    # 需要密码的话
    masterauth "IdfaUqTcdad82"
    
    • 创建集群
    # 随便一台机器执行; --cluster 表示加集群的参数;create 创建集群;后面跟集群节点;--cluster-replicas 表示每个节点分配几个从节点;-a 表示密码(生产环境也是建议每个节点分配一个从节点)
    redis-cli --cluster create 192.168.12.161:8001 192.168.12.161:8002 192.168.12.162:8001 192.168.12.162:8002 192.168.12.163:8001 192.168.12.163:8002 --cluster-replicas 1 -a IdfaUqTcdad82
    
    # 查看集群的状态
    redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
    
    # 查看集群配置文件(启动集群后redis自动创建)
    cat /data/redis8001/data/node8001.conf
    

    集群使用

    • 数据测试
    # Redis Cluster 可以通过任意一个节点redis连接集群;-c 表示按集群的方式连接redis
    redis-cli -p 8001 -a IdfaUqTcdad82 -c
    
    # 查看集群信息,在redis内执行
    cluster nodes
    
    • 集群相关命令
    # 查看某个key在哪个槽上
    cluster keyslot aaa
    # 查看某个槽有多少个key,只能查询本节点槽的数量
    cluster countkeysinslot 10439
    # 返回某个槽的某些key;10 查询槽中10个key
    cluster getkeysinslot 13785 10
    

    通过Go程序连接Redis Cluster

    查看某些开发语言怎么连接redis官方文档

    • 通过chatgpt编写Go连接Redis Cluster的代码

    编写Go程序,需要连接带密码的Redis Cluster
    每秒写入一个唯一的key
    写入成功和失败都输出带时间的日志

    • 修改代码
    • 运行代码

    故障恢复测试

    • 关闭一个主实例
    # 登录redis后执行
    shutdown
    
    • 查看集群状态
    cluster nodes
    
    • 启动关掉的实例
    # 新启动的实例会变成从节点
    /usr/local/redis6/bin/redise-serrver /data/redis8001/conf/redis.conf
    # 极端场景,主和从都挂掉,是否继续提供服务参数;yes 表示主和从不可用的时候整个集群就不可用;no 这个主从节点不可用,其他节点可用,但是挂的节点的数据不可查询
    config get cluster-require-full-coverage
    

    Redis Cluster扩容

    • 部署要扩容的Redis实例
    # 在两台实例上各部署一个Redis
    
    • 添加新的主从实例到集群
    # 192.168.12.161:8003 新增的节点;192.168.12.161:8001 已经存在的任一节点
    redis-cli --cluster add-node 192.168.12.161:8003 192.168.12.161:8001 -a IdfaUqTcdad82
    # 查看集群状态
    redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
    
    # 为新增的主实例添加从实例;192.168.12.162:8003 新增的节点;192.168.12.161:8001 已经存在的任一节点;--cluster-slave 以从节点加入;--cluster-master-id 主节点的id
    redis-cli --cluster add-node 192.168.12.162:8003 192.168.12.161:8001 --cluster-slave --cluster-master-id 70502ee36d2476e6f39d335d56373d141daa4653  -a IdfaUqTcdad82
    
    # 查看集群状态;此时新加的主从节点还没有槽
    redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
    
    • 进行槽迁移
    # 192.168.12.161:8001 集群任一节点;reshard 重新分配槽;槽总数/主从个数=新增节点的槽
    redis-cli --cluster reshard 192.168.12.161:8001 -a IdfaUqTcdad82
    

    Redis Cluster缩容

    • 转移要缩容节点的槽
    # --cluster-from 表示要迁移槽的源节点;...a4777 要迁移到哪个节点;--cluster-slots 要迁移槽的数量;192.168.12.161:8001 集群任意一节点的ip和端口
    redis-cli --cluster reshard --cluster-from 70502ee36d2476e6f39d335d56373d141daa4653 --cluster-to 70502ee36d2476e6f39d335d56373d141daa4777 --cluster-slots 1365 192.168.12.161:8001 -a IdfaUqTcdad82
    # 迁移时最好迁移到连续编号的槽节点
    
    • 删除要缩容的节点
    # 192.168.12.161:8001 集群任意一节点的ip和端口;...a4653 要删除的节点
    redis-cli --cluster del-node 192.168.12.161:8001 70502ee36d2476e6f39d335d56373d141daa4653 -a IdfaUqTcdad82
    redis-cli --cluster del-node 192.168.12.161:8001 70502ee36d2476e6f39d335d56373d141daa4666 -a IdfaUqTcdad82
    # 查看集群状态
    redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
    

    Redis Cluster原理解析

    • 虚拟槽和哈希标签

    Redis Cluster采用虚拟槽分区,一个集群有16384个虚拟槽,虚拟槽类似数据分区,每个键值对都会根据它的key再按照CRC16算法计算一个16bit的值,然后这个16bit的值对16384进行取模,通过模来映射到槽中。

    # 有时候想要某些key在一个槽里面,可以用哈希标签
    redis-cli -p 8001 -a IdfaUqTcdad82 -c
    set {user001}.name aaa
    set {user001}.email aaa@qq.com
    # 查看在哪个槽
    cluster keyslot {user001}.name
    # 查看这个槽下所有key
    cluster getkeysinslot 1390 10
    
    # 不能过度使用,可能会导致数据分表不均匀
    
    • 客户端怎样定位数据的?

    在客户端和集群建立连接后,实例就会把hash槽的分片信息发送给客户端,每个实例会把自己的hash槽信息发送给集群内其它实例,这样每个实例都会知道所有hash槽和实例的对应关系。

    • 故障转移

    集群内每个节点都会定期向集群中其它节点发送ping命令,互相探测,这样可以交换节点状态信息。

    # 选取资格判断参数
    config get cluster-node-timeout
    
    # 如果这个参数设置为0,那么不管断开多久多会参与选举
    config get cluster-slave-validity-factor
    

    Redis Cluster的优势

    1. 无中心架构
    2. 动态扩缩容
    3. 高可用性

    Redis Cluster的限制

    1. key批量操作支持有限
    2. 不能将一个大的键值对象映射到不同的节点
    3. 只支持单个库

    相关文章

      网友评论

        本文标题:DBA数据库笔记之(七)Redis基础知识

        本文链接:https://www.haomeiwen.com/subject/urksodtx.html