美文网首页
Redis学习笔记3

Redis学习笔记3

作者: 这货不是王马勺 | 来源:发表于2021-08-23 13:28 被阅读0次

    P1 sentinel
    13.redis-sentinel(哨兵)
    1、监控
    2、自动选主,切换(6381 slaveof no one)
    3、2号从库(6382)指向新主库(6381)
    4、应用透明
    5、自动处理故障节点
    sentinel和MHA一样可一次性管理多套集群
    sentinel搭建过程

    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 
    

    配置文件内容一共就五行,前两行是端口号和工作目录,
    第三行到第五行中mymaster是我们取的集群名,未来如果再有其他集群,那么类似第三行到第五行的内容还需要再写一组
    第三行写主库的ip地址和端口号,最后的数字1代表了有1台哨兵认为主库宕了就切换
    标配是三个哨兵,2台认为主库宕了就切换
    第四行代表了判定主库为宕的时间是5000ms,即5s
    第五行是集群节点密码,和主从密码一致(主从密码设置相同也是为了sentinel此时能切换)

    启动:

    [root@db01 26380]# redis-sentinel /data/26380/sentinel.conf  &>/tmp/sentinel.log &
    

    可以查看/tmp/sentinel.log日志信息


    正常的启动信息

    ==============================
    如果有问题:
    1、重新准备1主2从环境
    2、kill掉sentinel进程
    3、删除sentinel目录下的所有文件
    4、重新搭建sentinel
    ======================================

    停主库测试:

    [root@db01 ~]# redis-cli -p 6380 -a 123 shutdown
    [root@db01 ~]# redis-cli -p 6381 -a 123 info replication
    

    启动原来的主库(6380),看状态

    redis-server /data/6380/redis.conf
    

    Sentinel管理命令:

    redis-cli -p 26380
    

    PING :返回 PONG 。
    SENTINEL masters :列出所有被监视的主服务器
    SENTINEL slaves <master name>
    SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。
    SENTINEL reset <pattern> : 重置所有名字和给定模式 pattern 相匹配的主服务器。
    SENTINEL failover <master name> : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移,理解为手动failover。

    P2 redis cluster

    分布式集群

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

    高可用
    在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof的功能,同时当主节点down,实现类似于sentinel的自动failover的功能。

    1、redis会有多组分片构成(3组)
    2、redis cluster 使用固定个数的slot(槽位)存储数据(一共16384slot),每个槽位可以存n多个键值对
    3、每组分片分得1/3 slot个数(0-5500 5501-11000 11001-16383)
    4、基于CRC16运算(key) % 16384(和16384取模) ====》值 (槽位号)。

    P3 Redis Cluster搭建
    14.2 规划、搭建过程
    6个redis实例,一般会放到3台硬件服务器
    注:在企业规划中,一个分片的两个分到不同的物理机,防止硬件主机宕机造成的整个分片数据丢失。
    端口号:7000-7005

    安装集群插件
    EPEL源安装ruby支持,因为redis集群插件是用ruby开发的(早期是纯手工敲命令部署)
    redis集群功能是在3版本之后才有

    yum install ruby rubygems -y
    

    使用国内源

    gem sources -l
    gem sources -a http://mirrors.aliyun.com/rubygems/ 
    gem sources  --remove https://rubygems.org/
    gem sources -l
    gem install redis -v 3.3.3
    

    gem就是安装ruby专用的程序
    安装的插件可以理解为一个让ruby能操作redis的驱动

    集群节点准备

    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
    

    启动节点:

    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 
    [root@db01 ~]# ps -ef |grep redis
    root       8854      1  0 03:56 ?        00:00:00 redis-server *:7000 [cluster]     
    root       8858      1  0 03:56 ?        00:00:00 redis-server *:7001 [cluster]     
    root       8860      1  0 03:56 ?        00:00:00 redis-server *:7002 [cluster]     
    root       8864      1  0 03:56 ?        00:00:00 redis-server *:7003 [cluster]     
    root       8866      1  0 03:56 ?        00:00:00 redis-server *:7004 [cluster]     
    root       8874      1  0 03:56 ?        00:00:00 redis-server *:7005 [cluster]  
    

    将节点加入集群管理:

    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
    

    记得敲yes,别直接回车就退出了

    集群状态查看:
    集群主节点状态

    redis-cli -p 7000 cluster nodes | grep master
    
    主节点

    最左边一长串是nodeid,是节点通信用的,然后就是ip地址和端口
    再后边是角色,7000节点的myself可以理解为是管理节点
    connected后边的数字就是槽位分布,不管多少个节点,总数都是16384

    集群从节点状态

    redis-cli -p 7000 cluster nodes | grep slave
    

    注:同一组的主和从是不能放在同一硬件上的,我们此处示例用了多实例是为了方便

    P4 Redis Cluster添加节点
    14.3 集群节点管理
    增加新的节点

    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 
    
    

    添加主节点

    redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
    
    未重新分片

    转移slot(重新分片)

    redis-trib.rb reshard 127.0.0.1:7000
    

    此时会有提示问你移动多少个slot?我们计算一下16384/4=4096,此处输入4096
    提示谁接受这些slot,则输入新加节点的node id
    源节点输入all
    这个操作需要在业务窗口期操作,比较影响性能

    添加一个从节点:

    redis-trib.rb add-node --slave --master-id 8ff9ef5b78e6da62bd7b362e1fe190cba19ef5ae 127.0.0.1:7007 127.0.0.1:7000
    

    这个master id要用你选的主节点的id,比如此处就找7006的id

    P5删除节点
    14.4 删除节点
    首先将需要删除节点slot移动走(reshard)
    像我们的7006,就要原路返回,哪来的回哪去,而不是都挪到一个上面
    所以要分三次挪,输入slot数量、接收的node id,源node id(7006的id),再done

    redis-trib.rb reshard 127.0.0.1:7000
    49257f251824dd815bc7f31e1118b670365e861a 
    127.0.0.1:7006
    0-1364 5461-6826 10923-12287
    1365      1366     1365
    

    删除一个节点:
    删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点

    redis-trib.rb del-node 127.0.0.1:7006 8ff9ef5b78e6da62bd7b362e1fe190cba19ef5ae
    

    因为7007没有slot所以可以直接删除:


    删除7007节点

    设置redis最大内存

    config set maxmemory 102400000
    

    P6 Redis API支持for python
    15. redis的多API支持
    python为例

    yum install -y python36 
    python3 -V
    yum install -y python36-pip
    pip3 install redis  --单击和sentinel
    pip3 install redis-py-cluster  --集群的
    

    ++++++++++++源码方式+++++++++++++++
    https://redis.io/clients
    下载redis-py-master.zip
    安装驱动:

    unzip redis-py-master.zip
    cd redis-py-master
    python3 setup.py install
    

    redis cluster的连接并操作(python2.7.2以上版本才支持redis cluster,我们选择的是3.6)
    https://github.com/Grokzen/redis-py-cluster
    安装redis-cluser的客户端程序

    cd redis-py-cluster-unstable
    python3 setup.py install
    

    +++++++++++++++++++++++++++++++++

    对redis的单实例进行连接操作

    [root@db01 ~]# redis-server /data/6379/redis.conf 
    
    python3
    >>>import redis
    >>>r = redis.StrictRedis(host='10.0.0.51', port=6379, db=0,password='123456')
    >>>r.set('oldboy', 'oldguo')
    >>>r.get('oldboy')
    

    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 &
    

    导入redis sentinel包

    >>>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('oldboy', '123')  
    >>> slave.get('oldboy')  
    ```
    
    python连接rediscluster集群测试
    在应用端将六个节点都加到连接池,应用通过正确的驱动连redis集群,
    就有转向错误提醒功能
    使用
    
    python3
    ```
    >>> from rediscluster import StrictRedisCluster  
    >>> startup_nodes = [{"host":"127.0.0.1", "port": "7000"},{"host":"127.0.0.1", "port": "7001"},{"host":"127.0.0.1", "port": "7002"}]  
    ### Note: decode_responses must be set to True when used with python3  
    >>> rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)  
    >>> rc.set("foo", "bar")  
    True  
    >>> print(rc.get("foo"))  
    'bar'
    ```
    
    **16.一些概念**
    缓存穿透
    概念
    访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。
    解决方案
    采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;
    访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。
    
    
    缓存雪崩
    概念
    大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。
    解决方案
    可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。
    
    
    缓存击穿
    概念
    一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。
    解决方案
    在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。
    
    
    
    

    相关文章

      网友评论

          本文标题:Redis学习笔记3

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