redis6.0 学习笔记 (耗时一周)

解压  安装包 tar

安装 gcc   yum install  gcc

make  如果make 动作报错 用 make distclean

        Hint: It's a good idea to run 'make test' ;)
    
        make[1]: 离开目录“/root/redis-6.2.6/src”
    
        出现上面两行  就可以安装


make install

        make[1]: 进入目录“/root/redis-6.2.6/src”
            CC Makefile.dep
        make[1]: 离开目录“/root/redis-6.2.6/src”
        make[1]: 进入目录“/root/redis-6.2.6/src”
    
        Hint: It's a good idea to run 'make test' ;)
    
            INSTALL redis-server
            INSTALL redis-benchmark
            INSTALL redis-cli
        make[1]: 离开目录“/root/redis-6.2.6/src”

进入到 /usr/local/bin 目录 

        总用量 18904
        -rwxr-xr-x. 1 root root 4829472 3月   9 15:19 redis-benchmark                   性能测试工具
        lrwxrwxrwx. 1 root root      12 3月   9 15:19 redis-check-aof -> redis-server   修改有问题的AOF文件
        lrwxrwxrwx. 1 root root      12 3月   9 15:19 redis-check-rdb -> redis-server
        -rwxr-xr-x. 1 root root 5003760 3月   9 15:19 redis-cli                            客户端,操作入口
        lrwxrwxrwx. 1 root root      12 3月   9 15:19 redis-sentinel -> redis-server    redis集群使用
        -rwxr-xr-x. 1 root root 9518888 3月   9 15:19 redis-server                        redis服务器启动命令

启动:     前台启动      ./redis-server &
        后台启动      /root/redis-6.2.6  有个  redis.conf
                    cp redis.conf /etc/redis.conf
            找到 daemonize no  修改为 daemonize yes
            /usr/local/bin  执行
            redis-server /etc/redis.conf

        [root@master bin]# ps -ef |grep redis
        root      6136  1388  0 15:32 pts/0    00:00:00 ./redis-server *:6379
        root     16847  1388  0 15:40 pts/0    00:00:00 grep --color=auto redis

关闭      进入到 redis-cli shutdown
        或者 kill -9 进程
        
dbsize 查看当前数据库的 key 的数量

flushdb 清空当前库

flushall 通杀全部库

redis 是单线程 +  多路IO 的复用技术
        多路复用是指一个线程来检查多个文件描述符socket的就绪状态,比如调用select
        和poll 函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则
        阻塞直到超时,得到就绪状态后经行真正的操作可以在同一个线程里面执行,也可
        启动线程执行(比如使用线程池)
        


string  字符串

        类型操作:
        set k liudh
        keys *
        exists key
        type key
        del  key
        unlink  key     根据value选择非阻塞删除
        仅将 keys 从 keyspace 元数据中删除,真正的删除会在后续的异步操作
    
        expire key 10   10秒钟  设置过期时间
    
        ttl key 查询还有多少秒过期  -1  永不过期  -2 表示已经过期
    
        一个 key 的 value 最多可以是 512M
    
        append k1 追加
    
        strlen
    
        setnx  存在的话 不执行  不存在的话 执行
    
        incr 将key 中的存储的数字值+1
    
        decr 将key 中存储的数字值 - 1 
    
        incrby
    
        decrby
    
        mset k1 v1  k2 v2  k3 v3
        mget  k1  k2  k3
        msetnx   同时设置一个 或者 多个key-value 对  当且仅当所有给定的
                key都不存在 (有一个存在 将不成功)
    
        getrange    
    
                127.0.0.1:6379> set name lucymary
                OK
                127.0.0.1:6379> get name
                "lucymary"
                127.0.0.1:6379> GETRANGE name 0 3
                "lucy"

        setrange
    
                127.0.0.1:6379> GETRANGE name 0 3
                "lucy"
                127.0.0.1:6379> SETRANGE name 3 aaa
                (integer) 8
                127.0.0.1:6379> get name
                "lucaaary"
    
        setex 


​            
                127.0.0.1:6379> SETEX age 20 value30
                OK  
                127.0.0.1:6379> get age
                "value30"
                127.0.0.1:6379> ttl age
                (integer) 7
                
        getset 旧值换新值
    
                127.0.0.1:6379> GETSET name aaa
                "lucaaary"
                127.0.0.1:6379> get name
                "aaa"


​        
--------------------------------------------------------

list 列表
        单键多值:      
        lpush     rpush    从左边/右边 插入一个或者多个值
        
            127.0.0.1:6379> LPUSH k1 v1 v2 v3
            (integer) 3
            127.0.0.1:6379> LRANGE k1 0 -1
            1) "v3"
            2) "v2"
            3) "v1"
    
            127.0.0.1:6379> RPUSH k2 v1 v2 v3
            (integer) 3
            127.0.0.1:6379> LRANGE k2 0 -1
            1) "v1"
            2) "v2"
            3) "v3"


        lpop    rpop    从左边/右边吐出一个值    值在键在,值光键亡
                    
            127.0.0.1:6379> LPOP k1
            "v3"
            127.0.0.1:6379> RPOP k2
            "v3"
                    
        rpoplpush  key1 key2  从 key1 列表右边吐出一个值,插到 key2 列表的左边
        
            127.0.0.1:6379> RPOPLPUSH k1 k2
            "v1"
            127.0.0.1:6379> LRANGE k1 0 -1
            1) "v3"
            2) "v2"
            127.0.0.1:6379> LRANGE k2 0 -1
            1) "v1"
            2) "v1"
            3) "v2"


​        
        lrange key  start  stop   按照索引下标获得元素 (从左到右)
    
        lindex key  index  按照索引下标获取元素(从左到右)
        
        llen 获得列表长度
        
            127.0.0.1:6379> LLEN k1
            (integer) 2
            127.0.0.1:6379> LLEN k2
            (integer) 3
        linsert 
        lrem
        lset

set  集合    自动排重 ,但你需要存储一个列表数据,又不希望重复,set 是个很好的选择
            set 是 string类型的无序集合,他底层实际是一个value为null 的hash表
            所以添加 删除 查询复杂度都是 0(1)


            127.0.0.1:6379> SADD k1 a b c 
            (integer) 3
            127.0.0.1:6379> SMEMBERS k1
            1) "b"
            2) "a"
            3) "c"
            127.0.0.1:6379> SISMEMBER k1 c
            (integer) 1
            127.0.0.1:6379> SISMEMBER k1 cc
            (integer) 0
            127.0.0.1:6379> SCARD k1
            (integer) 3
            127.0.0.1:6379> SREM k1 a b
            (integer) 2
            127.0.0.1:6379> SCARD k1
            (integer) 1
            127.0.0.1:6379> SMEMBERS k1
            1) "c"


    sadd         key value1 value2  将一个或者多个member元素加入到集合key中,已经存在的member元素将被忽略
    smembers    key            取出该集合所有值
    sismember    key value     判断集合key是否为该value值 有1  没有0
    
    scard        key            返回集合的元素个数
    srem        key value1 value2 删除集合中的某个元素
    spop        key            随机从集合中吐出一个值
    
            127.0.0.1:6379> SPOP k1
            "c"
            127.0.0.1:6379> SPOP k1
            (nil)

    srandmember    key n          随机从集合中吐出n个值,不会从集合中删除
    smove        source destination value 把集合中一个值从一个集合移动到另个集合
    sinter        key1 key2     返回两个集合交集元素
    sunion        key1 key2     返回两个集合并集元素
    sdiff        key1 key2    返回两个集合差集元素(key1 中 不包含key2中的)


hash    是一个键值对的集合 ,是一个string类型的 field 和 value 的映射表,hash特别
        适用于存储对象
        
        
        hset    key field value     给 key 集合中的field 键 复制value
        hget    key field            从key1 集合 field 取出    value
        
                127.0.0.1:6379> HSET user:1001 id 1
                (integer) 1
                127.0.0.1:6379> HSET user:1001 name zhangsan
                (integer) 1
                127.0.0.1:6379> HGET user:1001 id
                "1"
                127.0.0.1:6379> HGET user:1001 name
                "zhangsan"


        hmset    key1 field  value1 field2 value2.。。     批量设置hash值
        
                127.0.0.1:6379> HMSET user:1002 id 1 name liudh  age 30
                OK
                127.0.0.1:6379> HGET user:1002 id
                "1"
                127.0.0.1:6379> HGET user:1002 name
                "liudh"
                127.0.0.1:6379> HGET user:1002 age
                "30"
    
        hexists key1 field 查看哈希表 key 中 给定域 field 是否存在
        
                127.0.0.1:6379> HEXISTS user:1002 age
                (integer) 1
                127.0.0.1:6379> HEXISTS user:1002 name
                (integer) 1
                127.0.0.1:6379> HEXISTS user:1002 sex
                (integer) 0
        
        hkeys    key 列出该hash 集合所有的 field
        hvals     key    列出该hash 集合所有的 value
    
                127.0.0.1:6379> HKEYS user:1001
                1) "id"
                2) "name"
                127.0.0.1:6379> HVALS user:1001
                1) "1"
                2) "zhangsan"

        hincrby    key field increment 为哈希表 key 中的 域 field 值 增量 1  -1
        hsetnx    key field value 将 哈希表 key 中的 域 field 值设置为value 当且仅当域field不存在
    
                127.0.0.1:6379> HINCRBY user:1002 age 2
                (integer) 32
                127.0.0.1:6379> HSETNX user:1002 age 40
                (integer) 0
                127.0.0.1:6379> HSETNX user:1002 gender 40
                (integer) 1


​        
zset        有序集合  没有重复元素的字符串集合
​    
        zadd    将一个或者多个member元素机器score值加入到有序集 key 当中
        
        zrange key start stop 【withscores】 返回有序集 key 中  下表在 start  到 stop 之间的元素


                127.0.0.1:6379> ZADD topn 200 java  300 c++ 400 mysql  500 php
                (integer) 4
                127.0.0.1:6379> ZRANGE topn 0 -1
                1) "java"
                2) "c++"
                3) "mysql"
                4) "php"


                127.0.0.1:6379> ZRANGE topn 0 -1 withscores
                1) "java"
                2) "200"
                3) "c++"
                4) "300"
                5) "mysql"
                6) "400"
                7) "php"
                8) "500"
                        
        zrangebyscore by minmax  【withscores】 返回有序集 key 中 所有score 值 介于 min max 之间 包含min max 成员
    
                127.0.0.1:6379> ZRANGebyscore topn 200 300
                1) "java"
                2) "c++"
        
        zrevrangebyscore key  规则为 从大到小
        
                127.0.0.1:6379> ZrevRANGebyscore topn 500 300
                1) "php"
                2) "mysql"
                3) "c++"
    
                127.0.0.1:6379> ZrevRANGebyscore topn 500 300 withscores
                1) "php"
                2) "500"
                3) "mysql"
                4) "400"
                5) "c++"
                6) "300"
        
        zincrby key increment value 为 元素 score 加上增量
    
                127.0.0.1:6379> ZINCRBY topn 10 php
                "510"
                127.0.0.1:6379> ZrevRANGebyscore topn 600 300 withscores
                1) "php"
                2) "510"
                3) "mysql"
                4) "400"
                5) "c++"
                6) "300"


​        
        zrem topn php  删除集合下 指定的元素
        
        zcount key min  max  统计该集合 分数区间内的元素个数
        
        zrank key value 返回改制的集合中的排名 从 0 开始
        
                127.0.0.1:6379> ZRANGE topn 0 -1 withscores
                1) "java"
                2) "200"
                3) "c++"
                4) "300"
                5) "mysql"
                6) "400"
                7) "php"
                8) "510"
                127.0.0.1:6379> ZRANK topn mysql
                (integer) 2


redis 配置文件------------

        bind 127.0.0.1 -::1  一般配置本地Ip
    
        protected-mode yes  yes 修改为 NO 支持远程链接访问 
    
        tcp-backlog 511  设置tcp 的backlog, 其实就是一个链接队列,backlog队列
                总和=未完成三次握手的队列 + 已经完成三次握手的队列
                
                在高并发的环境下 你需要一个高backlog 值 来避免慢客户端连接问题
                
                linux 内核会将这个值 减小到          
                [root@master ~]# cat /proc/sys/net/core/somaxconn 
                128
                所以需要增大 /proc/sys/net/core/somaxconn   和
                [root@master ~]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog 
                128
                来达到想要的效果
    
        tcp-keepalive 300  心跳连接 , 连接上不操作 300秒 直接断开
    
        daemonize yes 后台启动
        
        pidfile /var/run/redis_6379.pid
        
        loglevel notice log 级别
        
        logfile ""  文件路径
        
        databases 16
        
        requirepass    设置密码
        
            [root@master ~]# redis-cli 
            127.0.0.1:6379> CONFIG GET requirepass
            1) "requirepass"
            2) ""
            127.0.0.1:6379> CONFIG SET requirepass '123456'
            OK
            127.0.0.1:6379> CONFIG GET requirepass
            1) "requirepass"
            2) "123456"
            127.0.0.1:6379> auth 123456
            OK
            127.0.0.1:6379> CONFIG GET requirepass
            1) "requirepass"
            2) "123456"


​        
        maxclients 10000  客户端最大连接数
        
        maxmemory  建议必须设置,否则 内存占满 造成服务器宕机,一旦到达内存使用上线
                    redis 将会试图移除内部数据,移除规则可以通过 
                    maxmemory-policy 来指定


​                    
                        volatile-lru 使用lru算法移除key,只对设置了过期时间的key
                        
                        allkeys-lru  在所有集合 key 中,使用lru算法移除key
                        
                        volatile-random  在过期集合中移除随机的key 只对设置了过期时间的键
                        
                        allkey-random 在所有集合 key 中 移除随机的key
                        
                        volatile-ttl 移除那些ttl值最小的key  即那些最近要过期的key
                        
                        noeviction  不进行移除 针对写操作,只是返回错误信息


​                    
redis    发布和订阅------------    

        redis 发布订阅是一种消息通信模式 发送者pub 发送消息,订阅者 sub 接收消息
        redis 客户端可以订阅任意数量的频道
        
        SUBSCRIBE channel1 订阅者
        PUBLISH channel1 111  发布


​        
​                
redis    新数据类型------------新数据类型------------新数据类型------------新数据类型------------

    bitmaps        本身不是一种数据类型,实际上他就是字符串 key-value 但是他可以对
                字符串的位经行操作
            实例:
                每个独立用户是否访问过网站存放在bitmaps中,将访问的用户记做1,
                没有访问的记做0 ,用偏移量作为用户的ID
                
            127.0.0.1:6379> SETBIT user:20220321 1 1
            (integer) 0
            127.0.0.1:6379> SETBIT user:20220321 6 1
            (integer) 0
            127.0.0.1:6379> SETBIT user:20220321 11 1
            (integer) 0
            127.0.0.1:6379> SETBIT user:20220321 19 1
            (integer) 0
    
            127.0.0.1:6379> GETBIT user:20220321 6
            (integer) 1
            127.0.0.1:6379> GETBIT user:20220321 1
            (integer) 1
            127.0.0.1:6379> GETBIT user:20220321 11
            (integer) 1
            127.0.0.1:6379> GETBIT user:20220321 19
            (integer) 1
        
        计算访问用户数据量:
            
            127.0.0.1:6379> BITCOUNT user:20220321 
            (integer) 4
            
            setbit user:20220322 0 1
            setbit user:20220322 1 1
            setbit user:20220322 11 1
            setbit user:20220322 14 1
        计算出两天都访问过的网站用户数量:
                and 交集 or 并集 not 非 xor 异或 
        127.0.0.1:6379> bitop and user:and:20220322_21 user:20220322 user:20220321
            (integer) 3
    
        bitmaps 与 set 对比
        
                每个用户ID 占用空间        需要存储的用户量        全部内存
            set        64位                    50000000            64*50000000=400M
            bitmaps    1位                        100000000            1*1000000000=12.5M


​    
        但bitmaps 不是万金油 假如网站的每天独立访问用户很少,只有10W,那么两者对比 如下


​        
                每个用户ID 占用空间        需要存储的用户量        全部内存
            set        64位                    1000000            64*1000000=800KB
            bitmaps    1位                        100000000            1*1000000000=12.5M    
    
    HyperLogLog        在工作中 经常遇到与统计相关的功能需求,比如统计网站PV 可以
                    使用redis 的 incr incrby 轻松实现
                    但像UV 单独访客 单独IP 数 搜索记录数等要去重和计数问题如何解决
                    这种求集合中不重复元素个数的问题成为基数问题
                    
                    解决基数问题很多种方案:
                    1:数据存储在mysql 表中 使用distinct count 计算不重复的个数
                    2:使用redis提供的hash set bitmaps 等数据结构来处理
                    以上方案结果精确,但随着数据的不断增加,导致占用空间越来越多,对于非常大
                    的数据集是不切实际的
                    
            redis hyperLoglog 是用来做基数统计的算法,Hyperloglog 优点是 在输入元素的数量或者体积
                    非常大时,计算基数所需要的空间总是固定的,并且是很小的
            reids 里面 每个hyperloglog 键 只需要花费12Kb 内存,就可以计算接近2^64个不同元素的基数
            
            比如基数集{1,3,5,7,5,7,8} 那么这个基数集为{1,3,5,7,8}基数为5 ,基数估计
            就是再误差可接受范围内,快速计算基数
            
        pfadd
        
            127.0.0.1:6379> PFADD progam "java"
            (integer) 1
            127.0.0.1:6379> PFADD progam "php"
            (integer) 1
            127.0.0.1:6379> PFADD progam "java"
            (integer) 0
            127.0.0.1:6379> PFADD progam "c++" "mysql"
            (integer) 1
            127.0.0.1:6379> PFADD progam "c++" "mysql" "oracle"
            (integer) 1
    
            127.0.0.1:6379> PFCOUNT progam
            (integer) 5
    
        pfmerge
            127.0.0.1:6379> PFCOUNT progam
            (integer) 5
            127.0.0.1:6379> PFADD k1 a
            (integer) 1
            127.0.0.1:6379> PFADD k1 b
            (integer) 1
            127.0.0.1:6379> PFCOUNT k1
            (integer) 2
            127.0.0.1:6379> PFMERGE k100 k1 progam
            OK
            127.0.0.1:6379> PFCOUNT k100
            (integer) 7


​    
    Geospatial    GEO缩写,地理信息 就是元素的2维坐标,再地图上就是经纬度
                reids基于该类型 提供了经纬度设置,查询,范围查询,距离查询,经纬度hash等常见操作


​                
        geoadd
    
            127.0.0.1:6379> GEOADD china:city 121.47 31.23 shanghai
            (integer) 1
            127.0.0.1:6379> GEOADD china:city 106.50 29.53 chongqing 114.05 22.52 shenzhen 116.38 39.90 beijing
            (integer) 3
            127.0.0.1:6379>     
    
        GEOPOS
            127.0.0.1:6379> GEOPOS china:city shanghai
            1) 1) "121.47000163793563843"
               2) "31.22999903975783553"
            127.0.0.1:6379> GEOPOS china:city beijing
            1) 1) "116.38000041246414185"
               2) "39.90000009167092543"
            127.0.0.1:6379> 
        
        GEODIST        两个城市 直线距离 m 米 默认是 米   km 千米  mi 英里 ft 英尺
            127.0.0.1:6379> GEODIST china:city beijing shanghai 
            "1068153.5181"
            127.0.0.1:6379> GEODIST china:city beijing shanghai km
            "1068.1535"
            127.0.0.1:6379> 
        
        georadius    以给定的经纬度为中心 找出某一半内径的元素
                                                 经度  维度 距离 单位
            127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km
                1) "chongqing"
                2) "shenzhen"

 Jedis 操作 redis
 jedis 模拟验证码发送
 springBoot整合redis

 事务操作
            redis 事务时一个单独的隔离操作,事务中的所有命令都会序列化,按照顺序地执行,事务在
                执行过程中 不会被其他客户端发送来的命令请求所打断
                
            redis 事务的主要作用是串联多个命令防止别的命令插队
        
            从输入Multi 命令开始,输入的命令会一次进入命令队列中, 但不会执行,直到输入exec
            后,redis会将之前的命令队列中的命令依次执行
            组队的过程中可以通过discard 来放弃组队


​            
            Multi  Exec/discard
            
                127.0.0.1:6379> MULTI
                OK
                127.0.0.1:6379(TX)> set key1 value1
                QUEUED
                127.0.0.1:6379(TX)> set key2 value2
                QUEUED
                127.0.0.1:6379(TX)> exec
                1) OK
                2) OK
                127.0.0.1:6379> get key1
                "value1"
                127.0.0.1:6379> get key2
                "value2"
    
        事务的错误处理
        
                127.0.0.1:6379> MULTI
                OK
                127.0.0.1:6379(TX)> set b1 v1
                QUEUED
                127.0.0.1:6379(TX)> set b2 v2
                QUEUED
                127.0.0.1:6379(TX)> set b3
                (error) ERR wrong number of arguments for 'set' command
                127.0.0.1:6379(TX)> exec
                (error) EXECABORT Transaction discarded because of previous errors.
                127.0.0.1:6379> DISCARD
                (error) ERR DISCARD without MULTI
                127.0.0.1:6379> MULTI
                OK
                127.0.0.1:6379(TX)> set c1 v1
                QUEUED
                127.0.0.1:6379(TX)> INCR c1
                QUEUED
                127.0.0.1:6379(TX)> EXEC
                1) OK
                2) (error) ERR value is not an integer or out of range
    
                127.0.0.1:6379> get c1
                "v1"
        事务冲突问题
            
                一个请求想给金额减去8000
                一个请求想给金额减去5000
                一个请求想给金额将去1000


​        
                悲观锁  :每次拿数据的时候都认为别人会修改,所以每次在拿数据的时候会上锁,这样别人
                    想拿这个数据就会block直到它拿到锁,传统的关系型数据库里面就用到了很多这种
                    锁的机制,比如 行锁 表锁等,读锁 写锁,都是在操作之前先上锁


​                
​                
                乐观锁    :每次拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会
                    判断一下再次期间别人有没有去更新这个数据,可以使用版本号等机制,乐观锁用于多读的
                    应用类型,这样可以提高吞吐量,redis 就是利用这种 check-and-set 机制实现事务的


​        
        watch key
            在执行multi之前 先执行 watch key1 可以监视一个或者多个key ,如果在事务执行之前这个key
            被其他命令所改动,那么事务将被打断
    
            开启两个窗口:
            窗口1:
            127.0.0.1:6379> KEYS *                                                    
            1) "balance"
            127.0.0.1:6379> WATCH balance
            OK
            127.0.0.1:6379> MULTI
            OK
            127.0.0.1:6379(TX)> INCRBY balance 10
            QUEUED
            127.0.0.1:6379(TX)> EXEC  先执行 提交
            1) (integer) 110
            
            窗口2:
            127.0.0.1:6379> WATCH balance
            OK
            127.0.0.1:6379> MULTI
            OK
            127.0.0.1:6379(TX)> INCRBY balance 20
            QUEUED
            127.0.0.1:6379(TX)> EXEC    后执行的提交 结果是 空
            (nil)
            127.0.0.1:6379> 
            
        unwatch  取消watch 命令对所有key 的监视
        
            如果在执行watch 命令后,exec命令或者discard命令先被执行的话 那么就不需要再执行unwatch 了
        
    reids 事务三特性
    
        单独的隔离操作
            事务中的所有命令都会序列化,按照顺序执行,事务再执行的过程中,不会被其他客户端发来的命令请求打断
        
        没有隔离级别的概念
            队列中的命令没有提交之前不会实际被执行,因为事务提交前任何指令都不会实际执行
        
        不保证原子性
            事务中如果有一条命令执行失败,后面的命令仍然会被执行,没有回滚


​            
reids 事务秒杀案例

reids 事务秒杀案例    ab工具模拟并发    centos6 默认已经安装, centos7 yum install httpd-tools

reids 事务秒杀案例    超卖和超时问题解决

reids 事务秒杀案例    库存遗留问题


reids 持久化操作  两个持久化方式  两个方式都开启清理,系统默认AOF 数据(数据不会存在丢失)

        RDB        reids Database
                在指定的 时间间隔 内 将内存的数据集快照写入磁盘,也就是行话说的snapshot 快照
                他恢复时 将快照读取到内存
                
                redis 会单独创建fock 一个子进程 来经行持久化,会先将数据写入到一个临时文件中,待
                    持久化过程都结束了,在用这个临时文件替换上次持久化好的文件, 整个过程中,主进程是不
                    进行任何的IO操作,这就确保了极高的性能,如果需要经行大规模数据恢复,且对于数据恢复的
                    完整性不是非常的敏感,那RDB方式要比AOF方式更加高效,RDB 缺点就是最后一次持久化后的数据可能丢失
                
                配置文件里面 有参数
                dbfilename dump.rdb
                dir ./
                stop-writes-on-bgsave-error yes    当硬盘满了 就不在写如操作
                rdbcompression yes                是否压缩存储
                rdbchecksum yes                    检查完整性  大约10%的性能消耗
    
                # save 3600 1
                # save 300 100
                # save 60 10000
        
            redis 在fork时用了 写时拷贝技术  但是如果数据庞大时候还是比较消耗性能
            fork 时候 内存中的数据 被克隆了一份 大致2 倍的膨胀性 需要考虑
            在备份周期在一定间隔时间做一次备份,所以如果redis 意外down 掉的话 就会丢失最后
            一次快照后的修改
                
            动态停止备份:
                    redis-cli config set save ""  save给空置 表示禁用保存策略
                
        AOF        append OfFile  默认不开启
                
                以日志的形式来记录每个写的操作 增量保持,将redis执行过的所有写的指令记录下来
                (读操作不记录) 只需要追加文件但不可以改写文件,redis 启动之初会读取该文件的
                重新构建数据,换言之 redis 重启的话 就根据日志文件的内容将写的指令从前到后执行一次
                以完成数据的恢复工作 
            
            appendonly yes
    
            appendfilename "appendonly.aof"
    
        异常恢复:
            修改默认的appendonly no 为 yes
            如果遇到AOF 文件损坏 通过/usr/local/bin/redis-check-aof --fix  appendonly.aof恢复
            
                [root@master bin]# redis-check-aof --fix appendonly.aof 
                
                AOF analyzed: size=147, ok_up_to=147, ok_up_to_line=34, diff=0
                AOF is valid
        
            AOF文件损坏 会造成redis 启动失败 所以要修复
            
            AOF 同步频率设置
            
            appendfsync always
            
            始终同步,每次redis 的写入都会立刻计入日志,性能比较差但数据完整性比较好
            
            appendfsync everysec
            
            每秒同步,每秒计入日志一次,如果当即,本秒的数据可能丢失
            
            appendfsync no
            redis 不主动同步,把同步的时机交给操作系统
            
        rewrite 压缩
        
                重写原理:
                    AOF 文件持续增长过大时候,会fork 出一条新的进程将文件重写 也就是先写临时文件最后再rename
                    redis4.0 版本后的重写 是指上就是把rdb的快照,以二进制的形式附在新的aof头部 作为已有的历史数据,替换掉原来的流水账操作


​                    
                no-appendfsync-on-rewrite:
                    如果 no-appendfsync-on-rewrite = yes 不写入aof文件 只写入缓存,用户请求不会阻塞,但是他可以对
                    在这段时间如果宕机会丢失这段时间的缓存数据(降低数据安全性,提高性能)
                    
                    如果 no-appendfsync-on-rewrite=no 还是会把数据往磁盘里面刷,但是遇到重新操作 可能发生组设(数据安全,但性能降低)
                
                触发机制 何时重写
                
                    redis 会记录上次重写的 AOF 大小,默认值是当AOF 文件大小是上次rewrite后的大小的一倍
                    且文件大于64M时触发
                    
        AOF 持久化流程
                1:客户端的请求写明了会被apped 追加到AOF 缓冲区内
                2:AOF缓冲区根据AOF 持久化策略【always,everysec,no】 将操作的sync 同步到磁盘AOF文件中
                3:AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量
                4:redis 服务重启时,会重新load 加载Aof文件中的写操作到达数据恢复的目的

reids 主从复制:
        
                [root@master myreids]# cat redis6379.conf 
                include /usr/myreids/redis.conf
                pidfile /usr/myreids/redis_6379.pid
                port 6379
                dbfilename dump6379.rdb


                [root@master myreids]# cat redis6380.conf 
                include /usr/myreids/redis.conf
                pidfile /usr/myreids/redis_6380.pid
                port 6380
                dbfilename dump6380.rdb


                [root@master myreids]# cat redis6381.conf 
                include /usr/myreids/redis.conf
                pidfile /usr/myreids/redis_6381.pid
                port 6381
                dbfilename dump6381.rdb
            
                redis-server /usr/myreids/redis6379.conf 
                redis-server /usr/myreids/redis6380.conf 
                redis-server /usr/myreids/redis6381.conf 
            
             INFO replication
    
                slaveof ip port  就可以搭建主从复制关系
                
                127.0.0.1:6380> SLAVEOF 192.168.228.128 6379
                OK
    
                127.0.0.1:6381> SLAVEOF 192.168.228.128 6379
                OK                    
                
                127.0.0.1:6379> info replication
    
                # Replication
                role:master
                connected_slaves:2
                slave0:ip=192.168.228.128,port=6380,state=online,offset=42,lag=0
                slave1:ip=192.168.228.128,port=6381,state=online,offset=42,lag=0
                master_failover_state:no-failover
                master_replid:ed575fa2e263b7624b59f196455c171e98105c65
                master_replid2:0000000000000000000000000000000000000000
                master_repl_offset:42
                second_repl_offset:-1
                repl_backlog_active:1
                repl_backlog_size:1048576
                repl_backlog_first_byte_offset:1
                repl_backlog_histlen:42
        
        slave 宕机后 重新启动后 要重新操作 slaveof 操作
                启动后 直接从主库拉去 重新全库数据,并且保证 主从一致
            
                主服务器挂后,从服务器 正常不会选主    
                主服务器 重启后,还是主服务器,还是老大哥


​            
        主从复制原理:
                1:当从连接上主服务后,从服务器向主服务发送经行数据同步消息
                2:主服务器连接到从服务器过来的同步消息,把主服务器数据经行持久化rdbs文件,把rdb文件发送
                    从服务器,从服务器拿到rdb 进行读取
                3:每次主服务器经行写操作后,和从服务器经行数据同步
        
        薪火相传 : 上一个slave 可以时下一个slave 的 master,slave 同样可以接收其他slaves 的连接
                    和同步请求,那么该slave 作为了链条中的下一个master,可以有效减轻master 的写压力
                    去中心化降低风险
                    
        反客为主:    slaveof no one  将从机变为主机

reids 哨兵模式(sentinel)
        
        反客为主的自动版,能够后台监控主机是否故障,如果故障了 根据投票数自动将从库转换为主库
        
        [root@master myreids]# cat sentinel.conf 
        sentinel monitor mymaster 192.168.228.128 6379 1    mymaster为监控对象起的服务器名称    后面 1  为至少有多少个哨兵同意迁移的数量
        
        直接启动
        redis-sentinel sentinel.conf 


​        
        17460:X 25 Mar 2022 17:42:52.364 # +monitor master mymaster 192.168.228.128 6379 quorum 1
        17460:X 25 Mar 2022 17:42:52.365 * +slave slave 192.168.228.128:6380 192.168.228.128 6380 @ mymaster 192.168.228.128 6379
        17460:X 25 Mar 2022 17:42:52.367 * +slave slave 192.168.228.128:6381 192.168.228.128 6381 @ mymaster 192.168.228.128 6379
    
        6379 下线 后 走的 选主 流程
        
                17460:X 25 Mar 2022 17:55:09.901 # +sdown master mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:09.901 # +odown master mymaster 192.168.228.128 6379 #quorum 1/1
                17460:X 25 Mar 2022 17:55:09.901 # +new-epoch 1
                17460:X 25 Mar 2022 17:55:09.901 # +try-failover master mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:09.910 # +vote-for-leader e8d2dbd9e2c0e29c9d800427c48a1e0f7b94924c 1
                17460:X 25 Mar 2022 17:55:09.911 # +elected-leader master mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:09.911 # +failover-state-select-slave master mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:09.972 # +selected-slave slave 192.168.228.128:6380 192.168.228.128 6380 @ mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:09.972 * +failover-state-send-slaveof-noone slave 192.168.228.128:6380 192.168.228.128 6380 @ mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:10.059 * +failover-state-wait-promotion slave 192.168.228.128:6380 192.168.228.128 6380 @ mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:11.071 # +promoted-slave slave 192.168.228.128:6380 192.168.228.128 6380 @ mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:11.071 # +failover-state-reconf-slaves master mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:11.135 * +slave-reconf-sent slave 192.168.228.128:6381 192.168.228.128 6381 @ mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:12.083 * +slave-reconf-inprog slave 192.168.228.128:6381 192.168.228.128 6381 @ mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:12.083 * +slave-reconf-done slave 192.168.228.128:6381 192.168.228.128 6381 @ mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:12.149 # +failover-end master mymaster 192.168.228.128 6379
                17460:X 25 Mar 2022 17:55:12.149 # +switch-master mymaster 192.168.228.128 6379 192.168.228.128 6380
                17460:X 25 Mar 2022 17:55:12.149 * +slave slave 192.168.228.128:6381 192.168.228.128 6381 @ mymaster 192.168.228.128 6380
                17460:X 25 Mar 2022 17:55:12.149 * +slave slave 192.168.228.128:6379 192.168.228.128 6379 @ mymaster 192.168.228.128 6380
                17460:X 25 Mar 2022 17:55:42.180 # +sdown slave 192.168.228.128:6379 192.168.228.128 6379 @ mymaster 192.168.228.128 6380
        
        选举操作    :
                1:slave-priorty/replica-priority 100  值越小,优先级别越高
                2:选主偏移量最大的
                3:选主runid 最小的从服务(每个redis 实例会随机生成一个 40位的runid)


​        
        启动 6379 后 自动加入 集群
        
                [root@master myreids]# cat sentinel.conf 
                sentinel monitor mymaster 192.168.228.128 6380 1
                # Generated by CONFIG REWRITE
                protected-mode no
                port 26379
                user default on nopass ~* &* +@all
                dir "/usr/myreids"
                sentinel myid e8d2dbd9e2c0e29c9d800427c48a1e0f7b94924c
                sentinel config-epoch mymaster 1
                sentinel leader-epoch mymaster 1
                sentinel current-epoch 1
                sentinel known-replica mymaster 192.168.228.128 6379
                sentinel known-replica mymaster 192.168.228.128 6381
        
        复制延迟:
                master 同步到slave 机器有一定的延迟,当系统很繁忙的时候 延迟问题会更加严重,slave 机器数量的增加会是
                这个问题更加严重

redis    集群                
            容量不够
            并发写操作redis 如何分摊
            3。0 提供了解决方案 无中心化集群配置
            什么是集群
                redis 集群实现了对redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在
                N个节点中,每个节点存储总数居的1/N
                redis 集群通过分区 partion 来提供一定程度的可用性 availability 即集群中有一部分节点失效
                或者无法经行通讯,集群也可以继续处理命令请求
                
            删除持久化数据
                将rdb AOF文件都删除掉
        
            制作6个实例 6379 6380 6381   6389 6390 6391 
                [root@master myreids]# cat redis6379.conf 
                include /usr/myreids/redis.conf
                pidfile "/usr/myreids/redis_6379.pid"
                port 6379
                dbfilename "dump6379.rdb"
    
                # 打开集群模式
                cluster-enabled yes
    
                # 设定节点配置文件名字
                cluster-config-file nodes-6379.conf
                # 设定节点失联时间,超过该时间(毫秒)集群自动经行主从切换
                cluster-node-timeout 15000
    
                -rw-r--r--. 1 root root   333 4月   3 15:16 redis6379.conf
                -rw-r--r--. 1 root root   333 4月   3 15:36 redis6380.conf
                -rw-r--r--. 1 root root   333 4月   3 15:36 redis6381.conf
                -rw-r--r--. 1 root root   333 4月   3 15:37 redis6389.conf
                -rw-r--r--. 1 root root   333 4月   3 15:38 redis6390.conf
                -rw-r--r--. 1 root root   333 4月   3 15:38 redis6391.conf
        启动:
    
                [root@master myreids]# redis-server redis6379.conf 
                [root@master myreids]# redis-server redis6380.conf 
                [root@master myreids]# redis-server redis6381.conf 
                [root@master myreids]# redis-server redis6389.conf 
                [root@master myreids]# redis-server redis6391.conf 
                [root@master myreids]# redis-server redis6390.conf 
                [root@master myreids]# ps -ef |Grep redis
                -bash: Grep: 未找到命令
                [root@master myreids]# ps -ef |grep redis
                root      4978     1  0 15:40 ?        00:00:00 redis-server 0.0.0.0:6379 [cluster]
                root      4984     1  0 15:40 ?        00:00:00 redis-server 0.0.0.0:6380 [cluster]
                root      4990     1  0 15:40 ?        00:00:00 redis-server 0.0.0.0:6381 [cluster]
                root      4996     1  0 15:40 ?        00:00:00 redis-server 0.0.0.0:6389 [cluster]
                root      5002     1  0 15:40 ?        00:00:00 redis-server 0.0.0.0:6391 [cluster]
                root      5008     1  0 15:40 ?        00:00:00 redis-server 0.0.0.0:6390 [cluster]
                root      5016  4793  0 15:41 pts/0    00:00:00 grep --color=auto redis
        
                [root@master myreids]# ll
                总用量 168
                -rw-r--r--. 1 root root   114 4月   3 15:40 nodes-6379.conf
                -rw-r--r--. 1 root root   114 4月   3 15:40 nodes-6380.conf
                -rw-r--r--. 1 root root   114 4月   3 15:40 nodes-6381.conf
                -rw-r--r--. 1 root root   114 4月   3 15:40 nodes-6389.conf
                -rw-r--r--. 1 root root   114 4月   3 15:40 nodes-6390.conf
                -rw-r--r--. 1 root root   114 4月   3 15:40 nodes-6391.conf
                -rw-r--r--. 1 root root   333 4月   3 15:16 redis6379.conf
                -rw-r--r--. 1 root root     5 4月   3 15:40 redis_6379.pid
                -rw-r--r--. 1 root root   333 4月   3 15:36 redis6380.conf
                -rw-r--r--. 1 root root     5 4月   3 15:40 redis_6380.pid
                -rw-r--r--. 1 root root   333 4月   3 15:36 redis6381.conf
                -rw-r--r--. 1 root root     5 4月   3 15:40 redis_6381.pid
                -rw-r--r--. 1 root root   333 4月   3 15:37 redis6389.conf
                -rw-r--r--. 1 root root     5 4月   3 15:40 redis_6389.pid
                -rw-r--r--. 1 root root   333 4月   3 15:38 redis6390.conf
                -rw-r--r--. 1 root root     5 4月   3 15:40 redis_6390.pid
                -rw-r--r--. 1 root root   333 4月   3 15:38 redis6391.conf
                -rw-r--r--. 1 root root     5 4月   3 15:40 redis_6391.pid
        将 6个节点合成一个集群
            合成集群钱,请确保redis 启动 后 nodes-xxxx.conf 文件都正常
            
            cd /root/redis-6.2.6/src  切记 这个地方 要用到 源码路径 去执行 才能顺序 一主一从
            [root@master myreids]# redis-cli --cluster create --cluster-replicas 1 192.168.145.128:6379 192.168.145.128:6380 192.168.145.128:6381 192.168.145.128:6389 192.168.145.128:6390 192.168.145.128:6391
            --replicas 1 采用最简单的方式配置集群,一台主机 一台从机 
    
                M: 115557ce76ac902ac0c126c8ab1fb98957857841 192.168.145.128:6379
                   slots:[0-5460] (5461 slots) master
                M: 2b4202a0674f02dac7028c4292bb2e21d52ecd88 192.168.145.128:6380
                   slots:[5461-10922] (5462 slots) master
                M: 6d2c1fa7e8bc3096ae257381b654a85609d914b2 192.168.145.128:6381
                   slots:[10923-16383] (5461 slots) master
                S: 4dff65ec5892cf43c091298789fbaa3ef89fe159 192.168.145.128:6389
                   replicates 115557ce76ac902ac0c126c8ab1fb98957857841
                S: 3733986b31a40bc71a095a9f483386ad967d6de0 192.168.145.128:6390
                   replicates 2b4202a0674f02dac7028c4292bb2e21d52ecd88
                S: 40e2b454bb9e4f9a8671b7ed962330e3638bcef3 192.168.145.128:6391
                   replicates 6d2c1fa7e8bc3096ae257381b654a85609d914b2
    
            [OK] All nodes agree about slots configuration.
            >>> Check for open slots...
            >>> Check slots coverage...
            [OK] All 16384 slots covered.            
            
        链接集群 命令     设置数据会自动切换到相应的主机
            redis-cli -c -p 6379 
    
            查看集群节点:
            192.168.145.128:6379> CLUSTER NODES
            6d2c1fa7e8bc3096ae257381b654a85609d914b2 192.168.145.128:6381@16381 master - 0 1648972661000 3 connected 10923-16383
            3733986b31a40bc71a095a9f483386ad967d6de0 192.168.145.128:6390@16390 slave 2b4202a0674f02dac7028c4292bb2e21d52ecd88 0 1648972661153 2 connected
            115557ce76ac902ac0c126c8ab1fb98957857841 192.168.145.128:6379@16379 myself,master - 0 1648972659000 1 connected 0-5460
            40e2b454bb9e4f9a8671b7ed962330e3638bcef3 192.168.145.128:6391@16391 slave 6d2c1fa7e8bc3096ae257381b654a85609d914b2 0 1648972662177 3 connected
            4dff65ec5892cf43c091298789fbaa3ef89fe159 192.168.145.128:6389@16389 slave 115557ce76ac902ac0c126c8ab1fb98957857841 0 1648972661000 1 connected
            2b4202a0674f02dac7028c4292bb2e21d52ecd88 192.168.145.128:6380@16380 master - 0 1648972663199 2 connected 5461-10922
            192.168.145.128:6379> 
    
            执行:
            127.0.0.1:6379> set name liudh
            -> Redirected to slot [5798] located at 192.168.145.128:6380
            OK
            192.168.145.128:6380> set v1 k1
            -> Redirected to slot [1165] located at 192.168.145.128:6379
            OK
        
        分配原则
            尽量保证每个主数据库运行在不同的IP地址,每个主库和从库不在一个IP地址上
        
        什么是 slots 0 -16383  共 16384 个插槽
        
            0-5460 5461-10922 10923-10383
            
            这个报错要看懂
            192.168.145.128:6379> mset name liudh age 30 address beijing
            (error) CROSSSLOT Keys in request don't hash to the same slot
        
        查看集群中的值
            192.168.145.128:6381> CLUSTER KEYSLOT name
            (integer) 5798
    
            192.168.145.128:6380> set name1 zhang
            -> Redirected to slot [12933] located at 192.168.145.128:6381
            OK
            192.168.145.128:6381> CLUSTER COUNTKEYSINSLOT 12933
            (integer) 1
            192.168.145.128:6381> CLUSTER GETKEYSINSLOT 12933 1
            1) "name1"
        故障恢复
            如果主节点下线 从节点能否自动升级为主机点? 注意 15秒超时
            
            关闭 6381 的 节点  192.168.145.128:6381> shutdown
            
                        127.0.0.1:6379> CLUSTER nodes
                6381 已经断开了        6d2c1fa7e8bc3096ae257381b654a85609d914b2 192.168.145.128:6381@16381 master,fail - 1648977199466 1648977195375 3 disconnected        
                        3733986b31a40bc71a095a9f483386ad967d6de0 192.168.145.128:6390@16390 slave 2b4202a0674f02dac7028c4292bb2e21d52ecd88 0 1648977271166 2 connected
                        115557ce76ac902ac0c126c8ab1fb98957857841 192.168.145.128:6379@16379 myself,master - 0 1648977272000 1 connected 0-5460
                6391 已经成主了        40e2b454bb9e4f9a8671b7ed962330e3638bcef3 192.168.145.128:6391@16391 master - 0 1648977272198 7 connected 10923-16383
                        4dff65ec5892cf43c091298789fbaa3ef89fe159 192.168.145.128:6389@16389 slave 115557ce76ac902ac0c126c8ab1fb98957857841 0 1648977274247 1 connected
                        2b4202a0674f02dac7028c4292bb2e21d52ecd88 192.168.145.128:6380@16380 master - 0 1648977273219 2 connected 5461-10922
                        127.0.0.1:6379> 
    
                再启动6381 看看
    
                    [root@master myreids]# redis-server redis6381.conf 
                    [root@master myreids]# ps -ef |grep redis
                    root      4978     1  0 15:40 ?        00:00:15 redis-server 0.0.0.0:6379 [cluster]
                    root      4984     1  0 15:40 ?        00:00:14 redis-server 0.0.0.0:6380 [cluster]
                    root      4996     1  0 15:40 ?        00:00:14 redis-server 0.0.0.0:6389 [cluster]
                    root      5002     1  0 15:40 ?        00:00:14 redis-server 0.0.0.0:6391 [cluster]
                    root      5008     1  0 15:40 ?        00:00:14 redis-server 0.0.0.0:6390 [cluster]
                    root      5250     1  0 17:16 ?        00:00:00 redis-server 0.0.0.0:6381 [cluster]
                可以看到 6381 已经是 6391 的slave 了
                    127.0.0.1:6379> CLUSTER nodes
                    6d2c1fa7e8bc3096ae257381b654a85609d914b2 192.168.145.128:6381@16381 slave 40e2b454bb9e4f9a8671b7ed962330e3638bcef3 0 1648977451000 7 connected
                    3733986b31a40bc71a095a9f483386ad967d6de0 192.168.145.128:6390@16390 slave 2b4202a0674f02dac7028c4292bb2e21d52ecd88 0 1648977449415 2 connected
                    115557ce76ac902ac0c126c8ab1fb98957857841 192.168.145.128:6379@16379 myself,master - 0 1648977449000 1 connected 0-5460
                    40e2b454bb9e4f9a8671b7ed962330e3638bcef3 192.168.145.128:6391@16391 master - 0 1648977450439 7 connected 10923-16383
                    4dff65ec5892cf43c091298789fbaa3ef89fe159 192.168.145.128:6389@16389 slave 115557ce76ac902ac0c126c8ab1fb98957857841 0 1648977451467 1 connected
                    2b4202a0674f02dac7028c4292bb2e21d52ecd88 192.168.145.128:6380@16380 master - 0 1648977445325 2 connected 5461-10922


        思考题:
            如果所有某一段插槽的主从节点都宕机 redis 服务是否可以继续?
            
            如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为 yes 那么整个集群都挂掉
            
            如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为 no , 那么 该插槽的数据全部都不能使用,也无法存储
            
            redis.conf 中的参数 cluster-require-full-coverage  去设置 
            
        集群的有点:
            实现扩容
            分摊压力
            无中心化集群配置简单
        
        集群的不足:
            多建操作是不被支持的
            多建的redis事务是不被支持的,lua 脚本不被支持
            由于集群方案出现的比较晚,很多公司采用了其他集群方案,而代理或者客户端分片的方案想要迁移到
            redis cluster 需要整体迁移而不是过渡迁移,复杂度较大


​    应用问题解决
            
            缓存穿透
                    1 应用服务器压力变大
                    2 redis命中率降低
                    3 一直查询数据库
                    
                        造成 redis 查询不到数据
                        出现很多非正常url 访问
                    
                    解决方案:
                        
                        对空置缓存 
                            如果一个查询返回的数据为空,不管是否存在,我们仍然把这个空的结果 null 经常缓存,
                            这是空结果的过期时间很短,最长不超过5分钟
                        
                        设置可访问的名单(白名单)    
                            使用bitmaps类型定义一个可以访问的名单,名单的id 作为了bitmaps 偏移量
                            每次访问和bitmap 里面的ip 经行比较,如果访问的id 不在bitmaps 里面 惊醒拦截,不允许访问
                        
                        采用布隆过滤器
                        
                        进行实时监控
                            当发现redis 命中率开始急速下降,需要排查访问对象和访问的数据,和运维人员配合,设置黑名单限制
                                            
            
            缓存击穿
                    1 数据访问压力瞬间增加
                    2 redis 的key没有大量过期
                    3 redis 正常的运行,但数据库已经压力很大
                        
                        key 对应的数据存在,但在redis 中过期,此时如果有大量并大请求过来,这些请求发现缓存过期一般都会从
                            后端DB 加载数据并且回设到缓存,这个时候大并发的请求可能瞬间把后端DB 压垮
                        
                    redis 某个key 过期了,大量访问使用这个key
                    
                    解决方案:
                        
                        预先设置热门数据
                            在redis 高峰访问之前,把一些热门数据提前存放到 redis 里面,加大这些热门数据 key 的时长
                        
                        实时调整
                            现场监控哪些数据热门,实时调整key 的过期时长
                        
                        使用锁
                            就是在缓存失效的时候(判断拿出来值为空)不是立即去load db
                            先使用缓存工具的某些带成功操作返回值的操作(比如 redis 的setnx)
            
            缓存雪崩
                    key 对应的数据存在,但是在redis 中过期,此时有大量并发过来,这些请求发现缓存过期一般都会从
                        后端db 加载数据并且回设到缓存, 这个时候大并发的请求可能会瞬间把后端db 压垮
                    缓存雪崩和缓存击穿区别在于这里针对 很多 key 缓存,前者是 某一个key
                    
                    解决方案:    
                        构建多级缓存架构,nginx缓存+redis缓存+其他缓存等
                        
                        使用锁或者队列
                            用加锁或者队列的方式保证不会有大量的线程对数据库一次性进行读写,从而避免失效的大量的并发请求落
                            到底层存储系统上,不适用高并发情况
                        
                        设置过期标志更新缓存
                        
                        将缓存失效时间分散开
                        
                            
                            
            分布式锁
                    主流的实现方案
                    1 基于数据库实现分布式锁
                    2 基于缓存 redis 
                    3 基于 zookeeper
                
                设置锁和过期时间
                    redis  使用setnx上锁,通过del 释放锁
                    锁一直没有释放,可以设置key 过期时间,自动释放
                    上锁后突然出现异常,无法设置过期时间
                        可以用上锁时候 设置过期时间 set user 10 nx ex 12
                
                uuid防止误删
                
                lua保证删除的原子性                

    新功能:  权限设置  IO多线程  工具支持cluster
                [root@master myreids]# redis-cli 
                127.0.0.1:6379> acl list
                1) "user default on nopass sanitize-payload ~* &* +@all"
            
                127.0.0.1:6379> ACL  setuser travelsky
                OK
                127.0.0.1:6379> acl list
                1) "user default on nopass sanitize-payload ~* &* +@all"
                2) "user travelsky off &* -@all"

                127.0.0.1:6379> acl whoami
                "default"
                
                127.0.0.1:6379> acl setuser liudh on >woshimima ~cached:* +get
                OK
                
                127.0.0.1:6379> acl list
                1) "user default on nopass sanitize-payload ~* &* +@all"
                2) "user liudh on #229123a6f531553c9fe14d91deaacdd1cb6b0ace04c405bb1c50cded3b423d12 ~cached:* &* -@all +get"
                3) "user travelsky off &* -@all"
            切换用户登录

                    127.0.0.1:6379> auth liudh woshimima
                    OK
                    127.0.0.1:6379> acl whoami
                    (error) NOPERM this user has no permissions to run the 'acl' command or its subcommand
                    127.0.0.1:6379> set aaa  aaa
                    (error) NOPERM this user has no permissions to run the 'set' command or its subcommand
                    
                    127.0.0.1:6379> get cached:111
                    (nil)
        多线程 io-threads-do-reads yes
               io-threads 4 
        
​        工具支持 cluster
        

​            
redis    碎片整理  http://www.javashuo.com/article/p-agdjgpgb-nu.html
​        一、什么是redis内存碎片?

            由于一块连续空闲的空间比所要申请的空间小,导致这块空间不可用,对于内存整体来说就是内存碎片。
    
        二、redis内存碎片产生原因
    
            常用的增删改redis都会产生一定的碎片。
    
                1.写入数据
    
                内存是根据分配策略固定的大小来划分内存空间的 , 为了减少分配次数,Redis 会根据申请的内存最接近的固定值分配相应大小的空间。
    
                2.修改数据
    
                键值对进行修改时,可能会变大也会变小,相应的就会占用额外空间或者释放不用的空间。
    
                3.删除数据
    
                删除某个value后,删除了字节,释放了空间。
    
        三、redis内存碎片危害性
    
            在 Redis 中,由于大量的碎片存在,会导致实际利用率变低。
    
        四、如何解决
    
            1.版本低于4.0
    
                如果你的Redis版本是4.0以下的,Redis服务器重启后,Redis会将没用的内存归还给操作系统,碎片率会降下来。
    
            2.版本高于4.0
    
                可以在不重启的情况下,线上整理内存碎片 ,自动碎片清理,只要设置了如下的配置,内存就会自动清理了
                
                config set activedefrag yes
    
                下面参数都是满足任一条件后就可以进行清理:
    
                active-defrag-ignore-bytes 100mb:表示内存碎片的字节数达到 100MB 时,开始清理;
    
                active-defrag-threshold-lower 20:表示内存碎片空间占操作系统分配给 Redis 的总空间比例达到 20% 时,开始清理。
    
                active-defrag-threshold-upper 100    :表示内存碎片超过 100%,尽最大清理。
    
                Redis 同时还提供了监控 CPU 占用比例的参数,在满足以下条件时才会保证清理正常开展:
    
                active-defrag-cycle-min 25: 表示自动清理过程所用 CPU 时间的比例不低于 25%,保证清理能正常开展;
    
                active-defrag-cycle-max 75:表示自动清理过程所用 CPU 时间的比例不高于 75%,一旦超过,就停止清理,从而避免在清理时,大量的内存拷贝阻塞 Redis,导致响应延迟升高。
    
            手动清理 :memory purge 
    
            查看内存 :info memory 
    
                这里有一个 mem_fragmentation_ratio 的指标,它表示的就是 Redis 当前的内存碎片率 。
    
                mem_fragmentation_ratio = used_memory_rss/ used_memory             
         
                大于1:说明内存有碎片,一般在1到1.5之间是正常的。
    
                大于1.5:说明内存碎片率比较大,需要考虑是否要进行内存碎片清理,要引起重视。
    
                小于1:说明已经开始使用交换内存,也就是使用硬盘了,正常的内存不够用了,需要考虑是否要进行         

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值