Redis:总结

安装

单机安装
  • 1、下载上传解压:redis-6.0.10.tar.gz

  • 2、需要gcc版本5.3及以上版本,升级gcc
    sudo yum -y install centos-release-scl
    sudo yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
    sudo scl enable devtoolset-9 bash
    #注意:scl命令启用只是临时的,推出xshell或者重启就会恢复到原来的gcc版本。
    #如果要长期生效的话,执行如下:
    echo “source /opt/rh/devtoolset-9/enable” >>/etc/profile

  • 3、编译:
    cd /home/msy/install/redis-6.0.10
    make

  • 4、安装:
    #PREFIX前缀就是redis安装目录,会在redis安装根目录下生成一个bin目录
    make install PREFIX=/home/msy/install/redis-6.0.10/

  • 5、修改配置文件:
    #为了启动方便,将redis.conf拷贝到bin目录下
    cd redis.conf bin/
    vim /bin/redis.conf
    (注意以下的配置)
    #绑定的ip
    bind 10.10.96.247
    #关闭保护模式
    protected-mode no
    #端口
    port 6379
    #守护进程的方式
    daemonize yes
    #log文件
    logfile /home/msy/install/redis-6.0.10/redis-log
    #rdb持久化的时机
    save 900 1
    save 300 10
    save 60 10000
    #rdb文件
    dbfilename dump.rdb
    #pidfile文件
    pidfile /home/msy/install/redis-6.0.10/redis_6379.pid
    #目录(最好修改,默认是 ./ 是在当前启动目录下)
    dir /home/msy/install/redis-6.0.10/
    #密码,暂不设置
    #requirepass 123
    #开启aof持久化
    appendonly yes
    #aof文件名
    appendfilename appendonly.aof
    #aof刷盘机制:1秒一次(建议用这个,默认的)
    appendfsync everysec
    #指当前aof文件比上次重写的增长比例大小(100%),达到这个大小就进行 aof 重写
    auto-aof-rewrite-percentage 100
    #最开始aof文件必须要达到这个文件时才触发aof重写,后面的每次重写就不会根据这个变量了
    auto-aof-rewrite-min-size 64mb
    #开启混合持久化(需要同时开启rdb和aof)
    aof-use-rdb-preamble yes
    #lazyfree机制,建议开启
    lazyfree-lazy-eviction yes
    lazyfree-lazy-expire yes
    lazyfree-lazy-server-del yes
    replica-lazy-flush yes
    lazyfree-lazy-user-del yes

  • 6、启动、关闭
    cd bin
    #后台启动,以守护进程的方式
    ./redis-server redis.conf
    #关闭redis
    ./redis-cli -h 10.10.96.247
    #进去之后
    shutdown
    exit

  • 7、设置开机自启动脚本
    在redis安装目录下有一个 utils/redis_init_script 的一个启动脚本,我们可以基于这个脚本做一些修改。首先打开这个脚本,我们可以看到这里主要是这么几个参数比较重要:
    REDISPORT:表示redis的端口号
    EXEC:redis-server所在的目录,这里我们是在bin目录下,所以应该改为:/home/msy/install/redis-6.0.10/bin/redis-server
    CLIEXEC:redis-cli所在的目录,这里我们也是在bin目录下,所以应该改为:/home/msy/install/redis-6.0.10/bin/redis-cli
    PIDFILE:这个表示redis启动的时候会生成一个pidfile文件,关闭的时候会删除这个文件,用来判断redis是否运行状态,这里根据redis.conf的配置文件来看,应该改为:/home/msy/install/redis-6.0.10/redis_6379.pid
    CONF:这个表示redis配置文件所在的目录,所有应该改为:"/home/msy/install/redis-6.0.10/bin/redis.conf"

    #!/bin/sh
    #
    # Simple Redis init.d script conceived to work on Linux systems
    # as it does use of the /proc filesystem.
    
    ### BEGIN INIT INFO
    # Provides:     redis_6379
    # Default-Start:        2 3 4 5
    # Default-Stop:         0 1 6
    # Short-Description:    Redis data structure server
    # Description:          Redis data structure server. See https://redis.io
    ### END INIT INFO
    
    REDISPORT=6379
    EXEC=/usr/local/bin/redis-server
    CLIEXEC=/usr/local/bin/redis-cli
    
    PIDFILE=/var/run/redis_${REDISPORT}.pid
    CONF="/etc/redis/${REDISPORT}.conf"
    
    case "$1" in
        start)
            if [ -f $PIDFILE ]
            then
                    echo "$PIDFILE exists, process is already running or crashed"
            else
                    echo "Starting Redis server..."
                    $EXEC $CONF
            fi
            ;;
        stop)
            if [ ! -f $PIDFILE ]
            then
                    echo "$PIDFILE does not exist, process is not running"
            else
                    PID=$(cat $PIDFILE)
                    echo "Stopping ..."
                    $CLIEXEC -p $REDISPORT shutdown
                    while [ -x /proc/${PID} ]
                    do
                        echo "Waiting for Redis to shutdown ..."
                        sleep 1
                    done
                    echo "Redis stopped"
            fi
            ;;
        *)
            echo "Please use start or stop as first argument"
            ;;
    esac
    

    修改之后我们把该配置文件复制到 /etc/init.d目录下,然后重命名,修改权限,加入自启动
    sudo cp redis_init_script /etc/init.d
    sudo cd /etc/init.d
    mv redis_init_script redisd
    sudo chmod 777 redisd
    sudo chkconfig redisd on
    然后需要在该启动脚本开头加上下面这两行

    # chkconfig: 2345 90 10
    # description: Redis is a persistent key-value database
    
  • 8、然后我们就可以通过 service redisd start 来启动redis,同时redis也会在开机的时候自启动,但是在通过 service redisd stop 来关闭redis的时候发现报错,错误信息为:连接不上127.0.0.1的redis服务,于是再次查看脚本 发现 stop的时候是通过 redis-cli -p 6379来关闭的,由于我们配置文件中修改了 bind 10.10.96.247,所以需要修改下stop时候的脚本,添加一个参数 HOST=10.10.96.247,然后修改为 $CLIEXEC -h $HOST -p $REDISPORT shutdown。(注意:如果你的redis配置了密码,这里需要加上 -a [密码] )即可。

  • 9、至此,redis的单机安装,相关配置文件修改,开机启动脚本,开始关闭脚本都配置好了,这里我是以非root用户操作的。

主从+哨兵搭建
  • 1、主节点配置不变
  • 2、从节点修改redis.conf,添加如下配置
    vim redis.conf
    #绑定的ip
    replicaof 10.10.96.247 6379
    masterauth 123
  • 3、分别启动主从,从节点默认只读
  • 4、哨兵搭建
    cp sentinel.conf /bin
    cd bin
    vim sentinel.conf
    #绑定的ip
    bind 172.16.157.201
    port 26379
    protected-mode no
    daemonize yes
    pidfile /home/msy/install/redis-6.0.10/sentinel_26379.pid
    logfile /home/msy/install/redis-6.0.10/sentinel_log
    dir /home/msy/install/redis-6.0.10/
    sentinel monitor mymaster 172.16.157.201 6379 2
    #如果redis设置了密码,这个配置一定要配上,而且这个配置要在 sentinel monitor 之后,不然报错(亲测遇到过)
    #sentinel auth-pass mymaster 123
    sentinel down-after-milliseconds mymaster 10000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 180000
    (从节点也这样操作,注意bind不一样)
  • 5、分别启动三个哨兵
    cd bin
    ./redis-sentinel sentinel.conf
  • 6、设置开启自启动脚本,同redis的启动脚本,在 /etc/init.d 目录下。复制一份 redisd 改名为 sentineld,修改如下内容:REDISPORT=26379。EXEC=/home/msy/install/redis-6.0.10/bin/redis-sentinel。PIDFILE=/home/msy/install/redis-6.0.10/sentinel_${REDISPORT}.pid。CONF="/home/msy/install/redis-6.0.10/bin/sentinel.conf"。我相信为什么改这几个参数应该很好理解,只要你能看的懂这个脚本就行。同样的把这个脚本加入开机自启动。
  • 7、后面开启关闭sentinel的话就用命令: service sentineld start|stop
集群搭建

常用数据类型及应用场景:

  • String:字符串
    内部编码:
    int:8个字节的长整型
    embstr:<=44字节的字符串
    raw:>44字节的字符串
    场景:
    缓存功能 计数器 共享用户Session

  • Hash
    内部编码:
    外层是hashtable
    内层是ziplist和hashtable
    场景:
    缓存 库存 爆品

  • list
    多个有序字符串的集合
    内部编码:
    3.0之前是ziplist和linkedlist
    3.2之后是quicklist
    场景:
    存储列表结构-粉丝列表,好友列表,文章评论

  • set
    多个无序不重复的字符串集合
    内部编码:
    整数集合(intset)或哈希表(hashtable)
    场景:
    自动去重 数据集玩法:共同好友,你可能认识

  • zset
    和set一样,但是有排序,为每个元素设置一个分数作为排序依据
    内部编码:
    压缩列表(ziplist)或跳跃表(skiplist)
    场景:
    topN 热搜-标题名加热度值

高级数据类型

  • bitmap
    统计用户在线状态,如果在线则设置为1,不在线为0。
    setbit key [用户id,必须为数字] [0或者1]
    bitcount key
  • hyperLogLog
    统计UV,得到不重复的元素个数。
    pfadd key a
    pfcount key
    pfmerge key1 key2 key3
  • geospatial
    做附近的人功能 geoadd key [经度] [纬度] [名称]
    GEOADD cities 116.404269 39.91582 “beijing” 121.478799 31.235456 “shanghai”
    GEORADIUS cities 120 30 500 km

Redis持久化

  • RDB

    以快照的形式,当复合一定条件时将数据写入磁盘,是一个二进制文件,Redis的默认持久化方式。
    触发时机:手动命令、符合配置的快照规则、主从复制时
    手动命令:sava、bgsave.
    save会阻塞redis服务器,执行命令期间,redis不能处理客户端的请求。
    bgsave是主进程会fork一个子进程异步做快照,只有在fork的时候才会阻塞,阻塞过程很短。
    快照规则:save 900 1 | save 300 10 | save 60 10000

  • AOF
    将redis命令追加到aof文件中
    配置规则:always、everysec、no 一般配置一秒操作一次。
    AOF的重写:aof文件会很大,如果配置了重写,在达到配置要求时会重写aof文件,会对一些命令做 优化合并,减少aof文件大小,它也是fork一个子进程;下面的配置表示:第一次重写的时候是AOF文件达到64mb后续的重写是在前一个AOF文件大小增加了100%就发生重写。
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb

  • 两个优缺点比较和选择:
    RDB恢复快,对redis性能影响小;但是数据会丢失。
    AOF数据更全,最多丢失1秒的数据,追加操作写入性能高;但是文件很大,恢复速度没有RDB快,对redis性能影响上比RDB大,但依然还是很快。
    选择上:一起使用,恢复的时候 优先以aof文件为主。

  • Redis在4.0之后新增了混合化持久化方式
    当前数据以RDB的形式写入文件开头,后续用AOF的方式追加命令。
    开启方式:aof-use-rdb-preamble yes 5.0以后默认开启,之前的版本要手动开启。

Redis 数据恢复

可以每小时、每天 对dump.rdb 文件做备份,然后恢复的时候,如果只是redis进程挂了,直接重启redis;如果redis的appendonly.aof和dump.rdb文件都坏了且不可恢复(这种情况基本都是r人为的),则可以基于最近的一小时备份文件做恢复。操作如下:

  1. 首先拷贝备份的dump.rdb文件到redis中,然后要关闭appendonly。因为如果appendonly和rdb都开启的话,恢复的时候是以appendonly.aof为主,而重启后会生成一个新的appendonly.aof文件,此文件没有内容,所以redis重启后不会恢复任何数据。
  2. 重启redis,此时数据肯定是恢复过来的.
  3. 热修改appendonly属性,config set appendonly yes,此时会在redis目录下生成一个appendonly.aof文件,这个文件内容和dump.rdb一样(因为我们配置的是混合持久化,它的特点就是当前数据以rdb的形式写入,也从侧面印证了我们的混合持久化是开启成功的)。
  4. 然后修改 redis.conf 配置文件,将 appendonly 改为 yes ;然后再次重启redis,也就是调用
    在这里插入图片描述
  5. 然后我们发现数据都恢复过来了,因为此时是基于我们之前生成的有数据的 appendonly.aof文件来恢复的,它里面的数据就是dump.rdb中是一样的,所以全部的数据都恢复成功了。然后继续添加新的key的时候,会往appendonly.aof文件中追加命令(同样印证了混合持久化的方式)。
  6. 至此,我们的数据就已经从备份的dump.rdb文件中恢复了。

Redis过期策略和内存淘汰策略

Redis4.0新增了一个lazy free特性,可以理解为延迟删除或者惰性删除,意思就是在删除的时候可以异步延迟释放键值,把键值的释放操作放在一个BIO单独的子线程中处理,以减少删除对Redis主线程的阻塞,可以避免删除big key时带来的性能问题。

  • 主动删除
    UNLINK命令,他是lazy free的一个实现;而DEL命令是阻塞的

  • 被动删除
    比如过期key的删除、超过内存时的删除
    目前有四个配置,默认都是关闭的,建议开启这些配置
    lazyfree-lazy-eviction no
    lazyfree-lazy-expire no
    lazyfree-lazy-server-del no
    slave-lazy-flush no
    lazyfree-lazy-eviction:表示当 Redis 运行内存超过最大内存时,是否开启 lazy free 机制删除;
    lazyfree-lazy-expire:表示设置了过期时间的键值,当过期之后是否开启 lazy free 机制删除;
    lazyfree-lazy-server-del:有些指令在处理已存在的键时,会带有一个隐式的 del 键的操作,比如rename 命令,当目标键已存在,Redis 会先删除目标键,如果这些目标键是一个 big key,就会造成阻塞删除的问题,此配置表示在这种场景中是否开启 lazy free 机制删除;
    slave-lazy-flush:针对 slave(从节点) 进行全量数据同步,slave 在加载 master 的 RDB 文件前,会运行 flushall 来清理自己的数据,它表示此时是否开启 lazy free 机制删除。

  • 限制最大内存:64位系统中Redis内存大小是没有限制的,需要配置下 maxmemory 参数,单位 bytes。

  • 超过最大内存后,Redis就会执行自己的内存淘汰策略:
    noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,Redis 默认内存淘汰策略。
    LRU:历史访问记录来进行淘汰数据,也就是把最久不访问的数据优先淘汰。
    可以对所有的key设置,也就是allkeys-lru
    也可以只对设置了ttl失效时间的key设置,也就是volatile-lru
    LFU:在一段时间内,数据被使用频次最少的,优先被淘汰(4.0新增的)
    可以对所有的key设置,也就是allkeys-lfu
    也可以只对设置了ttl失效时间的key设置,也就是volatile-lfu
    随机淘汰:allkeys-random:随机淘汰任意键值;
    volatile-random:随机淘汰设置了过期时间的任意键值。
    volatile-ttl:优先淘汰更早过期的键值。

  • 定期删除+惰性删除

    定期删除:指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。
    惰性删除:在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了,如果过期就会删除,不返回任何东西。

Redis集群演变

  1. 主从复制
    Redis 的主从同步,分为全量同步和增量同步。
    只有从机第一次连接上主机是全量同步。
    断线重连有可能触发全量同步也有可能是增量同步( master 判断 runid 是否一致)。
    除此之外的情况都是增量同步。
    在Redis2.8版本后,主从断线后恢复的情况下实现增量复制。
    配置: # replicaof
    #4.0之前只能slaveof 4.0之后默认replicaof,slaveof都起作用
    slaveof 192.168.133.154 6379
    replicaof 192.168.133.154 6379

  2. 主从复制+哨兵机制
    监控: 哨兵会不断地检查你的 Master 和 Slave 是否运作正常。
    提醒:当被监控的某个 Redis 节点出现问题时, 哨兵可以通过 API向管理员或者其他应用程序发送通知。
    自动故障迁移:当一个 Master 不能正常工作时,哨兵会开始一次自动故障迁移操作。

  3. Redis-Cluster
    架构细节
    (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
    (2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
    (3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
    (4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value
    Redis 集群中内置了 16384个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。
    容错
    (1)集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout),认为该master节点挂掉。
    (2)半数以上master挂掉,集群进入fail状态。
    (3)slot中某一段的主从节点都挂掉,集群进入fail状态。
    (4)最少三主三从.

Redis事务

redis事务是一个单独的隔离操作,事务中所有命令都会序列化、按顺序的执行,事务在执行过程中,不会被客户端其他发送来的命令请求所打断。
redis事务的主要作用就是串联多个命令防止其他命令插队。更类似一个批量执行的指令。
队列中的命令没有提交之前都不会实际执行。
不保证原子性,如果同一个事务中如果有一条命令执行失败,其后的命令任然会被执行,没有回滚。
注意:如果Redis Cluster模式下,不建议用事务,因为多个key的写入按照slot分之后可能分布在多个节点上。

Redis常见问题

  • 缓存雪崩:大量的key同时失效,高并发下对DB的请求会增大。
    让缓存失效时间打散,均匀分不开来。
  • 缓存穿透:对不存在的key高并发查询,查询的请求会发到DB上,导致数据库压力增加。
    采用布隆过滤器,用一个bitmap存所有的key,每次请求都先查询bitmap中是否 有这个key。
  • 缓存一致性问题:
    1.先更新DB再删除redis
    2.先删除redis再更新DB
    都会有脏数据产生的可能,可以采取延迟双删的策略:
    先删除redis,再更新DB,再睡眠一段时间(比如1s)再次删除redis。可以防止在删除redis和更新DB之间来了一个读请求,它查询redis没有然后读取数据库中旧数据再更新到redis中去。
  • redis分布式锁:后续单独写分布式锁的文章来讲这个。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值