美文网首页
一、 Redis

一、 Redis

作者: 一个反派人物 | 来源:发表于2021-04-26 10:49 被阅读0次

    1. NoSQL(Not Only SQL)产品

    缓存数据库(Key-Value):

    • Redis
    • Memcached
    • Tair

    文档类:

    • MongoDB
    • ES

    列存储:

    • HBASE

    图形存储:

    • Neo4J

    2. 缓存数据库对比

    Memcached:
    优点:高性能读写、单一数据类型、支持客户端式分布式集群、一致性hash、多核结构、多线程读写性能高。
    缺点:无持久化、节点故障可能出现缓存穿透、分布式需要客户端实现、跨机房数据同步困难、架构扩容复杂度高。
    场景:适合,多用户访问,每个用户少量的rw

    Redis:
    优点:高性能读写、多数据类型支持、数据持久化、高可用架构、支持自定义虚拟内存、支持分布式分片集群、单线程读写性能极高
    缺点:多线程读写较Memcached慢
    场景:适合,少用户访问,每个用户大量rw,直播类平台、网页游戏

    部署差异:
    Memcached:多核的缓存服务,更加适合于多用户并发访问次数较少的应用场景
    Redis:单核的缓存服务,单节点情况下,更加适合于少量用户,多次访问的应用场景。

    3. Redis安装部署

    3.1 下载安装

    下载

    wget http://download.redis.io/releases/redis-3.2.12.tar.gz
    

    解压

    tar -xf redis-3.2.12.tar.gz
    mv redis-3.2.12 /usr/local/
    cd /usr/local && ln -s redis-3.2.12 redis
    

    安装依赖包

    yum -y install gcc automake autoconf libtool make
    

    安装

    cd  /usr/local/redis && make
    

    修改环境变量

    vim /etc/profile
    ...
    export PATH=/usr/local/redis/src:$PATH
    

    3.2 redis启动及客户端连接

    后台启动

    redis-server & 
    redis-server /data/conf  #指定配置文件运行,配置文件中配置daemonize yes
    

    客户端连接

    redis-cli
    redis-cli command #免交互执行命令
    redis-cli -h ip地址 -p 端口 -a 密码
    

    3.3 redis配置文件

    vim /data/6379/redis.conf

    daemonize yes
    port 6379
    logfile /data/6379/redis.log
    dir /data/6379
    dbfilename dump.rdb
    bind 10.0.0.51 127.0.0.1
    requirepass 123456
    save 900 1
    save 300 10
    save 60 10000
    appendonly yes
    appendfsync everysec
    
    
    
    参数解释:
    daemonize yes                            后台运行
    port 6379                                默认端口号
    logfile /data/6379/redis.log             日志文件位置
    dir /data/6379                           持久化文件存储位置
    dbfilename dump.rdb                      RDB持久化数据文件名
    bind 10.0.0.51 127.0.0.1                 Redis默认只允许通过127.0.0.1接口
                                            (即本机)的访问,通过配置允许通
                                             过10.0.0.51接口访问
    requirepass 123456                       设置密码
    ++++++++++++++++++++++++                 数据持久化配置
    + save 900 1           +
    + save 300 10          +
    + save 60 10000        +
    + appendonly yes       +
    + appendfsync everysec +
    ++++++++++++++++++++++++
    

    4. Redis客户端命令

    免交互,redis-cli command
    交互式,进入redis后输入

    常用命令

    shutdown                              #关闭redis
    AUTH 密码                              #登陆后输入密码认证
    SAVE                                  #前台持久化,阻塞redis正常写入,直到持久化完成
    BGSAVE                                #后台持久化,开启子线程,异步持久化,不会阻塞redis正常写入
    
    
    set a 1                               #设置变量a为1
    get key                               #取得key的值
    KEYS *                                #查看所有的键名,生产中慎用!!!!!
    KEYS a*                               #查看所有a开头的键名
    KEYS *a*                              #查看所有包含a的键名
    TYPE KEY                              #返回key所存储值的类型
    EXPIRE key seconds                    #设置key的过期时间,秒
    PEXPIRE key milliseconds              #设置key的过期时间,毫秒
    TTL key                               #查看key的剩余时间,秒
    PTTL key                              #查看key的剩余时间,毫秒
    PERSIST key                           #取消key生存时间设置,永不过期
    DEL KEY                               #删除键
    EXISTS key                            #检查key是否存在
    RENAME key newkey                     #更名key为newkey
    
    
    INFO [Memory|Replication|CPU|...]     #查看系统信息
    Client list                           #查看当前连接的客户
    Client kill ip:port                   #断开客户的连接
    CONFIG get/set/rewrite                #配置查看、修改、写入文件
    DBsize                                #查看系统里有多少个键
    FLUSHALL                              #清空所有数据
    select 0-15
    FLUSHDB                               #选择库,并清空当前库
    MONITOR                               #监控实时指令
    

    5. Redis在线查看和修改配置

    配置查看

    CONFIG GET *              #模糊查询所有配置
    CONFIG GET re*            #查询re开头的配置
    

    配置修改

    CONFIG SET XXX XXX
    

    配置写入文件

    CONFIG REWRITE
    

    5.1 Redis内存设置

    一般建议设置为内存的70%

    CONFIG SET maxmemory 128M
    

    6. Redis持久化(内存落盘)

    6.1 持久化介绍

    RDB 持久化:
    可以在指定的时间间隔内生成数据集的时间点快照(point in time snapshot),新快照会覆盖旧快照。
    优点:速度快,适用于做备份,主从复制也是基于RDB持久化实现的。
    缺点:会有数据丢失。

    AOF 持久化:
    记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF文件中的命令全部以Redis协议的格式来保存,新命令会被追加到文件的末尾。
    优点:可以最大程度保证数据不丢
    缺点:日志记录量级比较大,持久化时间较长

    6.2 配置持久化

    6.2.1 RDB持久化配置

    vim /data/6379/redis.conf

    ...
    save 900 1
    save 300 10
    save 60 10000
    
    参数解释:
    save XX XX,进行持久化的触发条件
    save 900 1             900秒(15分钟)内有1个更改
    save 300 10            300秒(5分钟)内有10个更改
    save 60 10000          60秒内有10000个更改
    

    6.2.2 AOF持久化配置

    appendonly yes
    appendfsync everysec/always
    
    参数解释:
    appendonly yes              开启AOF功能
    appendfsync                 AOF间隔:everysec--每秒,always--每次操作
    

    7. Redis多数据类型支持

    7.1 支持5种数据类型

    string:字符串
    hash:字典
    list:列表
    set:集合
    zset:有序集合

    7.2 数据类型存储结构

    key value
    string name zhangsan
    hash stu_1 id:100 name:zhangsan
    list wechat [...,day3,day2,day1]
    头插列表,新数据在最前,利用下标寻址(0,1,...,-1)
    set seta (张三,王五,李四,...)
    zset ssa (歌曲1,歌曲2,歌曲3,...)
    也可利用下标寻址

    7.3 各类数据类型应用场景

    7.3.1 string字符串类型

    会话缓存、计数器

    #计数器例子
    incr 变量                      #变量自增1
    decr 变量                      #变量自减1
    incrby 变量 数值                #变量增加特定数值
    decrby 变量 数值                #变量减少特定数值
    
    set key value                  #设置变量值
    get key                        #取变量值
    

    7.3.2 hash字典类型

    最接近mysql表结构的一种类型,主要是可以做数据库缓存。

    7.3.2.1 使用语法

    存数据语法:hmset key field1 value1 field2 value2...

    hmset stu  id 101 name zhangsan age 20 gender m
    hmset stu1 id 102 name zhangsan1 age 21 gender f
    

    取数据语法:

    • 取一个key的所有field:hgetall key
    hgetall stu
    hgetall stu1
    
    • 取一个key的某几个field:hmget key field1 field2 field3...
    HMGET stu id name age gender
    HMGET stu1 id name age gender
    

    7.3.2.2 手工将mysql数据导入redis

    mysql中用select concat语句拼接语法

    select concat("hmset key_",id," field1 ",field1," field2 ",field2," field3 ",field3) from table_1 limit 10 into outfile '/tmp/hmset.txt';
    
    例子:
    select concat("hmset city_",id," id ",id," name ",name," countrycode ",countrycode," district ",district," population ",population) from city limit 10 into outfile '/tmp/hmset.txt'
    

    将数据导入redis

    cat /tmp/hmset.txt | redis-cli -a 123456 &> /dev/null
    

    7.3.3 list列表类型

    应用场景:微信朋友圈,即时消息展示。

    7.3.3.1 使用语法

    存数据语法:LPUSH key value1 [value2...],先存value1、再存value2

    LPUSH schedule 'today is zhou1'
    LPUSH schedule 'today is zhou2' 'today is zhou3'
    

    取数据语法:LRANGE key start下标 end下标

    LRANGE schedule 0 -1
    1) "today is zhou3"
    2) "today is zhou2"
    3) "today is zhou1"
    

    7.3.4 set集合类型

    应用场景:社交类的平台,好友系统。共同好友,二度好友。

    7.3.4.1 使用语法

    存数据语法:sadd key member1 [member2...]

    sadd a 1 2 3 4 5
    sadd b 2 3 4 5 6
    

    求并集:SUNION key1 key2

    SUNION a b
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    5) "5"
    6) "6"
    

    求交集:SINTER key1 key2

    SINTER a b
    1) "2"
    2) "3"
    3) "4"
    4) "5"
    

    求差集:SDIFF key1 key2

    SDIFF a b
    1) "1"
    

    7.3.5 sortset有序集合类型

    应用场景:排行榜应用

    7.3.5.1 使用语法

    存数据语法:zadd key score1 member1 [score2 member2...]

    zadd keya 0 a 0 b 0 c 0 d 
    

    增加member score语法:ZINCRBY key increment member

    ZINCRBY keya 10 a
    ZINCRBY keya 100 b
    

    显示有序集合语法:ZREVRANGE key start stop,按照score从高到低排序

    ZREVRANGE keya 0 -1
    1) "b"
    2) "a"
    3) "d"
    4) "c"
    

    7.4 Redis消息格式

    7.4.1 介绍

    消息模式在资源有效利用方面提供了有效的协调。
    有2种消息模式:消息队列,发布订阅

    7.4.2 发布订阅

    3个角色:

    • publisher 发布者
    • channel 频道
    • subscriber 订阅者

    订阅频道:SUBSCRIBE channel1 [channel2 ...]

    SUBSCRIBE fm928 fm929
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "fm928"
    3) (integer) 1
    1) "subscribe"
    2) "fm929"
    3) (integer) 2
    

    模糊订阅:SUBSCRIBE wang*,订阅wang开头的频道
    发布消息:PUBLISH channel message

    PUBLISH fm928 hi
    (integer) 1
    

    8. Redis事务

    Redis事务和Mysql事务的区别:

    • Redis事务:基于队列实现的,redis是乐观锁机制,仅实现原子性的保证,属于弱事务支持。
    • Mysql事务:基于事务日志、悲观锁机制、MVCC、Isolation等机制一起保证,强事务支持。

    事务开启后,操作先写入队列,执行EXEC后事务结束。回滚直接在队列中丢弃操作。


    redis事务工作原理

    8.1 事务命令

    • 开启事务multi
    • 提交事务EXEC
    • 丢弃未提交的操作DISCARD

    例子:

    127.0.0.1:6379> MULTI 
    OK
    127.0.0.1:6379> SET a 1 
    QUEUED
    127.0.0.1:6379> SET b 2
    QUEUED
    127.0.0.1:6379> EXEC
    1) OK
    2) OK
    

    8.2 乐观锁实现

    watch key
    如果key的value在事务未提交时改变,事务将提交失败,返回nil

    127.0.0.1:6379> WATCH a 
    OK
    127.0.0.1:6379> MULTI 
    OK
    127.0.0.1:6379> set a 1
    QUEUED
    127.0.0.1:6379> EXEC
    (nil)
    

    9. Redis主从复制

    9.1 主从复制原理

    1. 副本库通过slaveof 10.0.0.51 6379命令,连接主库,并发送SYNC给主库
    2. 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库
    3. 副本库接收后会应用RDB快照
    4. 主库会陆续将中间产生的新的操作,保存并发送给副本库
    5. 到此,我们主复制集就正常工作了
    6. 再此以后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库.
    7. 所有复制相关信息,从info信息中都可以查到.即使重启任何节点,他的主从关系依然都在.
    8. 如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库
    9. 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的

    9.2 主从数据一致性保证

    min-slaves-to-write 1 保证至少有1个从服务器存活
    min-slaves-max-lag 3从服务器网络延迟的最大值

    9.3 主库开启持久化

    如果不开持久化,主库重启时,将造成所有主从数据丢失。

    9.4 主从配置

    9.4.1 准备配置文件

    主库

    cat >> /data/6380/redis.conf <<EOF
    port 6380
    daemonize yes
    pidfile /data/6380/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6380
    requirepass 123
    masterauth 123
    EOF
    

    从库

    cat >>   /data/6381/redis.conf <<EOF
    port 6381
    daemonize yes
    pidfile /data/6381/redis.pid
    loglevel notice
    logfile "/data/6381/redis.log"
    dbfilename dump.rdb
    dir /data/6381
    requirepass 123
    masterauth 123
    EOF
    
    
    cat >>   /data/6382/redis.conf <<EOF
    port 6382
    daemonize yes
    pidfile /data/6382/redis.pid
    loglevel notice
    logfile "/data/6382/redis.log"
    dbfilename dump.rdb
    dir /data/6382
    requirepass 123
    masterauth 123
    EOF
    

    启动数据库

    #主
    redis-server /data/6380/redis.conf
    #从
    redis-server /data/6381/redis.conf
    redis-server /data/6382/redis.conf
    

    9.4.2 开启主从

    从库执行命令

    redis-cli -p 6381 -a 123 SLAVEOF 127.0.0.1 6380
    redis-cli -p 6382 -a 123 SLAVEOF 127.0.0.1 6380
    

    9.4.3 查询主从状态

    redis-cli -p 6380 -a 123 info replication
    redis-cli -p 6381 -a 123 info replication
    redis-cli -p 6382 -a 123 info replication
    

    9.4.4 解除主从状态

    redis-cli -p 6381 -a 123 SLAVEOF no one
    redis-cli -p 6382 -a 123 SLAVEOF no one
    

    10. redis-sentinel(哨兵)

    10.1 sentinel作用

    类似于Mysql中MHA+Atlas的集合体,可以作为自动完成宕机后的主从切换,还可以做读写分离。一般对于一个redis集群,部署3个sentinel进行监控。

    哨兵之间通信:哨兵与 master 建立通信,利用 master 提供发布/订阅机制发布自己的信息,比如IP、端口……,当多个哨兵实例都在主库上做了发布和订阅操作后,它们之间就能知道彼此的 IP 地址和端口,从而相互发现建立连接
    哨兵与slave通信:哨兵向 master 发送 INFO 命令, master 接收到命令后,便将 slave 列表告诉哨兵,哨兵根据 master 响应的 slave 名单信息与每一个 salve 建立连接,并且根据这个连接持续监控slave。

    作用:

    1. 监控
    2. 自动选主,切换
    3. 主库宕机后,从库指向新主库
    4. 应用透明
    5. 自动处理故障节点

    10.2 sentinel搭建

    sentinel是一个单独的redis实例,监控一个1主2从的redis集群

    mkdir /data/26380
    cd /data/26380
    vim sentinel.conf
    
    
    port 26380
    dir "/data/26380"
    sentinel monitor mymaster 127.0.0.1 6380 1
    sentinel down-after-milliseconds mymaster 5000
    sentinel auth-pass mymaster 123 
    

    参数解释:

    • sentinel monitor mymaster 127.0.0.1 6380 1mymaster是定义的redis集群的名字,127.0.0.1 6380是集群master的ip地址和端口号,1以表示仲裁master宕机需要的sentinel节点数,一般设置为sentinel节点的一半以上。
    • sentinel down-after-milliseconds mymaster 5000:判断master节点失效的时间,单位毫秒
    • sentinel auth-pass mymaster 123:主节点密码

    10.3 开启sentinel并记录日志

    redis-sentinel /data/26380/sentinel.conf  &>/tmp/sentinel.log &
    

    10.4 宕机切换

    如果主库宕机,会自动将1台Replica提升为Master,原主库恢复后,自动成为Replica挂在新的Master下。

    11. Redis cluster

    11.1 介绍

    1. 在多分片节点中,将16384个slot,均匀分布到多个分片节点中
    2. 存数据时,将key做crc16(key),然后和16384进行取模,得出槽位值(0-16383之间)
    3. 根据计算得出的槽位值,找到相对应的分片节点的主节点,存储到相应槽位上
    4. 如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正存储节点进行数据存储


    11.2 集群搭建

    11.2.1 安装集群插件(5.0版本以后不需要)

    #安装ruby支持
    yum install ruby rubygems -y
    #转换为国内源
    gem sources -a http://mirrors.aliyun.com/rubygems/ 
    gem sources  --remove https://rubygems.org/
    gem install redis -v 3.3.3
    

    11.2.2 准备节点配置文件

    mkdir /data/700{0..5}
    cat > /data/7000/redis.conf <<EOF
    port 7000
    daemonize yes
    pidfile /data/7000/redis.pid
    loglevel notice
    logfile "/data/7000/redis.log"
    dbfilename dump.rdb
    dir /data/7000
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    EOF
    
    cat >> /data/7001/redis.conf <<EOF
    port 7001
    daemonize yes
    pidfile /data/7001/redis.pid
    loglevel notice
    logfile "/data/7001/redis.log"
    dbfilename dump.rdb
    dir /data/7001
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    EOF
    
    cat >> /data/7002/redis.conf <<EOF
    port 7002
    daemonize yes
    pidfile /data/7002/redis.pid
    loglevel notice
    logfile "/data/7002/redis.log"
    dbfilename dump.rdb
    dir /data/7002
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    EOF
    
    
    cat >>  /data/7003/redis.conf <<EOF
    port 7003
    daemonize yes
    pidfile /data/7003/redis.pid
    loglevel notice
    logfile "/data/7003/redis.log"
    dbfilename dump.rdb
    dir /data/7003
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    EOF
    
    
    cat >> /data/7004/redis.conf <<EOF
    port 7004
    daemonize yes
    pidfile /data/7004/redis.pid
    loglevel notice
    logfile "/data/7004/redis.log"
    dbfilename dump.rdb
    dir /data/7004
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    EOF
    
    cat >> /data/7005/redis.conf <<EOF
    port 7005
    daemonize yes
    pidfile /data/7005/redis.pid
    loglevel notice
    logfile "/data/7005/redis.log"
    dbfilename dump.rdb
    dir /data/7005
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    EOF
    

    参数解释

    protected-mode no              #外部网络可以直接访问,如果配置yes需bind ip或者设置访问密码
    cluster-enabled yes            #开启集群功能
    cluster-config-file nodes.conf #设置集群配置文件名称,文件在dir下
    cluster-node-timeout 5000      #集群心跳时间
    

    启动redis

    redis-server /data/7000/redis.conf 
    redis-server /data/7001/redis.conf 
    redis-server /data/7002/redis.conf 
    redis-server /data/7003/redis.conf 
    redis-server /data/7004/redis.conf 
    redis-server /data/7005/redis.conf 
    

    11.2.3 创建集群

    5.0及以后版本,直接使用redis-cli命令

    redis-cli --cluster create  127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
    
    #参数 --cluster-replicas 1 表示每个主节点带1个从节点
    #节点的书写顺序为:主1、主2、主3、从1、从2、从3
    

    老版本使用ruby插件

    redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
    127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
    
    #节点的书写顺序为:主1、主2、主3、从1、从2、从3
    

    11.2.4 查询集群状态

    #集群主节点状态
    redis-cli -p 7000 cluster nodes | grep master
    #集群从节点状态
    redis-cli -p 7000 cluster nodes | grep slave
    

    11.3 添加节点

    11.3.1 准备配置文件

    mkdir /data/7006
    mkdir /data/7007
    cat > /data/7006/redis.conf <<EOF
    port 7006
    daemonize yes
    pidfile /data/7006/redis.pid
    loglevel notice
    logfile "/data/7006/redis.log"
    dbfilename dump.rdb
    dir /data/7006
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    EOF
    
    cat >  /data/7007/redis.conf <<EOF
    port 7007
    daemonize yes
    pidfile /data/7007/redis.pid
    loglevel notice
    logfile "/data/7007/redis.log"
    dbfilename dump.rdb
    dir /data/7007
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    EOF
    
    redis-server /data/7006/redis.conf 
    redis-server /data/7007/redis.conf 
    

    11.3.2 添加主节点127.0.0.1:7006

    添加主节点需要重新分片,将slot分配到新的主节点

    5.0及以后版本,直接使用redis-cli命令

    redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
    

    老版本使用ruby插件

    redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
    

    11.3.3 添加主节点后,转移slot(重新分片)

    5.0及以后版本,直接使用redis-cli命令

    redis-cli --cluster reshard 127.0.0.1:7000
    
    #后续步骤
    1.输入要转移多少slot
    2.输入接收slot的节点id
    3.输入转出slot的节点id,输入all表示从所有节点转出
    4.输入yes确认
    
    #免交互执行
    redis-cli --cluster reshard <host>:<port> --cluster-from <node-id> --cluster-to <node-id> --cluster-slots <number of slots> --cluster-yes
    

    老版本使用ruby插件

    redis-trib.rb reshard 127.0.0.1:7000
    
    #后续步骤
    1.输入要转移多少slot
    2.输入接收slot的节点id
    3.输入转出slot的节点id,输入all表示从所有节点转出
    4.输入yes确认
    

    11.3.4 添加一个从节点127.0.0.1:7007

    添加从节点无需重新分片

    5.0及以后版本,直接使用redis-cli命令

    redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave
    
    # 添加从节点时直接指定主节点
    redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave --cluster-master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
    

    老版本使用ruby插件

    redis-trib.rb add-node --slave --master-id 主节点ID 127.0.0.1:7007 127.0.0.1:7000
    

    11.4 删除节点

    11.4.1 删除主节点

    转移slot(重新分片)

    redis-cli --cluster reshard 127.0.0.1:7000
    
    #后续步骤
    将127.0.0.1:7006节点的slot分别转移到其他3个节点,循环执行:
    1.输入要转移多少slot
    2.输入接收slot的节点id
    3.输入转出slot的节点id,输入done
    4.输入yes确认
    

    删除主节点127.0.0.1:7006
    5.0以后版本

    redis-cli --cluster del-node 127.0.0.1:7000 节点ID
    

    5.0之前版本

    redis-trib.rb del-node 127.0.0.1:7000 节点ID
    

    11.4.2 删除从节点

    不需要重新分片
    删除从节点127.0.0.1:7007
    5.0以后版本

    redis-cli --cluster del-node 127.0.0.1:7000 节点ID
    

    5.0之前版本

    redis-trib.rb del-node 127.0.0.1:7000 节点ID
    

    12. 多API支持

    12.1 python支持

    安装python及redis库

    yum install -y python3
    yum install -y python3-pip
    pip3 install redis 
    pip3 install redis-py-cluster
    

    12.1.1 python对redis单实例操作

    [root@db01 ~]$ redis-server /data/6379/redis.conf 
    -------------------------------------------------
    
    #! /bin/python3
    # -*- coding:utf-8 -*-
    
    import redis
    
    r = redis.StrictRedis(host='127.0.0.1',port=6379,db=0,password='123456')
    r.set('a','111')
    r.get('a')
    

    12.1.2 python对sentinel集群进行操作

    [root@db01 ~]$ redis-server /data/6380/redis.conf
    [root@db01 ~]$ redis-server /data/6381/redis.conf
    [root@db01 ~]$ redis-server /data/6382/redis.conf 
    [root@db01 ~]$ redis-sentinel /data/26380/sentinel.conf  &>/tmp/sentinel.log &
    -------------------------------------------------
    
    #! /bin/python3
    # -*- coding:utf-8 -*-
    
    from redis.sentinel import Sentinel  
    
    ##指定sentinel的地址和端口号
    sentinel = Sentinel([('localhost', 26380)], socket_timeout=0.1)
    ##测试,获取以下主库和从库的信息
    sentinel.discover_master('mymaster')
    sentinel.discover_slaves('mymaster')
    

    配置读写分离

    #写节点
    master = sentinel.master_for('mymaster', socket_timeout=0.1,password="123")  
    #读节点
    slave = sentinel.slave_for('mymaster', socket_timeout=0.1,password="123")  
    ###读写分离测试   key     
    master.set('b', '123')  
    slave.get('b')  
    

    12.1.3 python连接redis cluster集群

    #! /bin/python3
    # -*- coding:utf-8 -*-
    
    from rediscluster import RedisCluster
    
    startup_nodes = [{"host":"127.0.0.1", "port": "7000"},{"host":"127.0.0.1", "port": "7001"},{"host":"127.0.0.1", "port": "7002"}]   
    rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True) 
    rc.set("foo", "bar")  
    print(rc.get("foo"))  
    

    13. 缓存穿透、雪崩、击穿

    • 穿透:访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。
      解决方法:

      1. 最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
      2. 如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
    • 雪崩: 大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。
      解决方法:

      1. 可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。
      2. 设置过期标志更新缓存:
        • 缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存;
        • 缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60分钟。这样,当缓存标记key过期后,实际缓存还能把旧数据返回给调用端,直到另外的线程在后台更新完成后,才会返回新缓存。
    • 击穿: 一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。
      解决方法:
      在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。

    SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。

    相关文章

      网友评论

          本文标题:一、 Redis

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