zoukankan      html  css  js  c++  java
  • Redis

    Redis 特性

    特性一:速度快 - 快的原因就是内存
    数据存在内存中
    

    特性二

    持久化 - 断电不丢数据
    Redis所有数据保存在内存中,对数据的跟新将异步地保存在磁盘上
    
     redis 支持两种持久化方式,一种是 Snapshotting(快照)也是默认方式,另一种是 Append-only file(缩写 aof)的方式。
    

    Redis 特性三

    特性三 - 多数据结构
    

    Redis 特性四

    支持多种客户端语言
    

    Redis 特性五

    功能丰富
    

    安装redis

    方式一

    通过yum工具安装redis

    yum install  redis -y
    

    方式二

    编译安装redis

    下载redis安装包

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

    解压缩redis安装包

    tar -zxvf redis-4.0.10.tar.gz
    

    进入到解压后的文件夹目录中进行编译

    make && make install
    

    编辑redis的配置文件redis.conf,让其支持更安全的启动方式‘

    requirepass 123456#打开redis密码的参数 
    protected-mode yes #开启安全模式
    bind 0.0.0.0 #修改redis的默认绑定地址
    port 6800 #修改redis的默认启动端口
    

    过滤出非空行,注释行的内容,重定向写入到一个文件中

    grep  -v "^$"  redis.conf |grep  -v "^#"  > new_redis.conf
    

    在新配置文件结尾加上后台启动参数

    daemonize  yes
    

    启动redis服务端

    启动时指定加载写好的配置文件

    redis-server new_redis.conf 
    

    验证redis是否启动

    ps -ef|grep redis 
    

    指定密码登录redis

    redis-cli -p 6800
    

    测试

    127.0.0.1:6800> ping
    (error) NOAUTH Authentication required. 
    127.0.0.1:6800> auth 123456
    OK
    127.0.0.1:6800> ping
    PONG
    

    基础命令

    keys *       查看所有key
    type key     查看key类型
    expire key seconds    过期时间
    ttl key      查看key过期剩余时间,-2表示key已经不存在了
    persist      取消key的过期时间,-1表示key存在,没有过期时间
    
    exists key   判断key存在  存在返回1  否则0
    del keys     删除key  可以删除多个
    dbsize       计算key的数量
    
    config get requirepass 查看redis是否设置密码
    config set requirepass “xx” 为redis设置密码
    
    


    redis的五大数据类型

    字符串(strings)

    set   设置key 
    	>set v1 a	
    get    获取key
    	>get v1
    append 追加string
    	>append v1 b	
    mset   设置多个键值对
    	>mset v2 a v3 b
    mget   获取多个键值对
    	>mget v1 v2 v3
    del    删除key
    	>del v1
    incr   递增+1
    	>set v4 =1
    	>incr v4
    decr   递减-1
    	>decr v4
    
    





    列表(lists)

    lpush       从列表左边插
    	>lpush v1 1 2
    rpush       从列表右边插
    	>rpush v1 3 4 
    lrange      获取一定长度的元素
    	>lrange v1 0 -1
    ltrim       截取一定长度列表
    	>ltrim v1 0 -1
    lpop        删除最左边一个元素
    	>lpop v1
    rpop        删除最右边一个元素
    	>rpop v1
    lpushx/rpushx   key存在则添加值,不存在不处理
    
    












    集合(sets)

    sadd/srem   添加/删除 元素
    	>sadd v1 1 2 3 4
    	>sadd v2 3 4 5 6
    sismember   判断是否为set的一个元素
    	>sismember v1 2
    smembers    返回集合所有的成员
    sdiff       返回一个集合和其他集合的差异
    	>sdiff v1 v2
    sinter      返回几个集合的交集
    	>sinter v1 v2 
    sunion      返回几个集合的并集
    	>sunion v1 v2
    
    

    有序集合(sorted sets)

    zadd/zrem  添加/删除
    	>zadd v1 10 a
    	>zadd v1 10 b
    zrange     从小到大查看
    	>zrange v1 0 -1
    zrevrange  从大到小查看
    	>zrevrange v1 0 -1
    

    散列(hashes)

    hset    设置散列值
    	>hset v1 age 10
    	>hset v1 sex 0
    hget    获取散列值
    	>hget v1 age
    hmset   设置多对散列值
    	>hmset v2 age 15 sex 1
    hmget   获取多对散列值
    	>hmget v2 age sex
    hsetnx  如果散列已经存在,则不设置(防止覆盖ke
    hkeys   返回所有keys
    	>hkeys v2
    hvals   返回所有values
    	>hvals v2
    hlen    返回散列包含域(field)的数量
    	>hlen v2
    hdel    删除散列指定的域(field)
    	>hdel v2 name age
    hexists 判断是否存在
    	>hexists v2 name
    
    





    发布订阅

    Redis 通过 PUBLISH(发布者)、 SUBSCRIBE (订阅者)等命令实现了订阅与发布模式。发布者在指定频道发布消息,订阅者通过订阅这个频道来获取消息。一个发布者可以对应多个订阅者

    #发布者
    >publish pd1 abc
    >publish pd2 123
    
    #订阅者1
    >subscribe pd1 pd2
    >pd1
    >abc
    >pd2
    >123
    
    #订阅者2
    >subscribe pd2
    >pd2
    >123
    

    模糊匹配频道

    #发布者
    >publish pd1 abc
    >publish pd2 123
    
    #订阅者
    >psubscribe pd*
    >abc
    >123
    

    持久化存储
    Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失。

    RDB持久化
    redis提供了RDB持久化的功能,这个功能可以将redis在内存中的的状态保存到硬盘中,它可以手动执行。也可以再redis.conf中配置,定期执行。
    RDB持久化产生的RDB文件是一个经过压缩的二进制文件,这个文件被保存在硬盘中,redis可以通过这个文件还原数据库当时的状态。

    使用rdb持久化

    1.准备配置文件

    touch rdbredis.conf 
    

    写入以下内容

    daemonize yes   #后台运行 
    port 6379 	    #指定端口 
    logfile /data/6379/redis.log   #指定日志路径
    dir /data/6379	   #redis的数据文件,会存放在这里
    dbfilename  dbmp.rdb   #开启rdb持久化,指定持久化文件名
    bind 0.0.0.0
    save 900 1 	 #定义触发rdb持久化的时间机制,也可以手动使用save进行持久化
    save 300 10
    save 60  10000  
    
    

    2.创建数据文件夹

    mkdir  -p /data/6379
    

    3.指定rdb文件启动redis

    redis-server  rdbredis.conf  
    

    AOF持久化
    记录服务器执行的所有变更操作命令(例如set del等),并在服务器启动时,通过重新执行这些命令来还原数据集。AOF 文件中的命令全部以redis协议的格式保存,新命令追加到文件末尾。
    优点:最大程序保证数据不丢
    缺点:日志记录非常大

    使用aof持久化

    1.准备配置文件

    touch aofredis.conf 
    

    写入以下内容

    daemonize yes #后台运行
    port 6379 # 指定端口
    logfile /data/6379/redis.log # 指定日志路径
    dir /data/6379 #redis的数据文件,会存放在这里
    appendonly yes  		 #开启aof的俩参数
    appendfsync everysec     #aof的持久化机制 
    # 参数
    	#always    总是修改类的操作
        #everysec  每秒做一次持久化
    	#no        依赖于系统自带的缓存大小机制
    
    

    2.创建数据文件夹

    mkdir  -p /data/6379
    

    3.指定aof文件启动redis

    redis-server aofredis.conf 
    

    RDB切换AOF

    在redis4.0中,通过config set命令,达到不重启redis服务,从RDB持久化切换为AOF。在进行切换之前注意文件的备份。

    config set appendonly yes # #开启AOF功能
    config set save ""  #关闭RDB功能
    

    此时RDB已经正确切换AOF,但它是临时生效,注意还得修改redis.conf添加AOF设置,不然重启后,通过config set的配置将丢失

    主从复制
    redis的主从复制基于redis的多实例完成,基于不同的端口,运行独立的数据库

    主库具有读写的权限,从库只有读的权限

    使用主从复制

    1.准备三个库的配置文件

    主库配置文件 masterreids.conf

    port 6380
    daemonize yes
    pidfile /data/6380/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6380
    protected-mode no
    
    

    从库1配置文件 slaveredis1.conf

    port 6381
    daemonize yes
    pidfile /data/6381/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6381
    protected-mode no
    
    

    从库2配置文件 slaveredis2.conf

    port 6382
    daemonize yes
    pidfile /data/6382/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6382
    protected-mode no
    
    

    2.创建三个数据库的数据文件夹

    mkdir -p  /data/{6380,6381,6382}
    

    3.分别启动三个数据库实例

    redis-server masterredis.conf 
    redis-server slaveredis1.conf
    redis-server slaveredis2.conf
    

    4.使用命令建立主从复制关系

    redis-cli -p 6381  slaveof 127.0.0.1 6380 
    redis-cli -p 6382  slaveof 127.0.0.1 6380 
    

    5.查看库信息

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

    主库:

    # Replication
    role:master # 身份
    connected_slaves:2 # 两个连接者
    slave0:ip=127.0.0.1,port=6381,state=online,offset=14,lag=0
    slave1:ip=127.0.0.1,port=6382,state=online,offset=14,lag=1
    
    

    从库:

    role:slave # 身份
    master_host:127.0.0.1
    master_port:6380
    master_link_status:up # 连接状态
    

    6.当主库由于某种原因挂掉后,手动将从库切换为主库,继续主从复制

    # 剔除自己的从库身份
    127.0.0.1:6381> slaveof no one
    

    7.再次启动一个新的从库,以6381为主库即可

    补充:除了通过指令建立主库和从库的关系外还可以在配置文件中直接指定为从库

    port 6381
    daemonize yes
    pidfile /data/6381/redis.pid
    loglevel notice
    logfile "/data/6381/redis.log"
    dbfilename dump.rdb
    dir /data/6381
    protected-mode no
    slaveof  127.0.0.1 6380  # 指定为从库
    
    

    哨兵配置
    Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能。而redis-sentinel就是一个独立运行的进程,用于监控多个master-slave集群,自动发现master宕机,进行自动切换slave > master。

    sentinel主要功能

    1.持续监视redis运行状态,如果节点不可达就会对节点进行下线标识

    2.如果被标识的是主节点,sentinel就会和其他的sentinel节点“协商”,如果其他节点也认为主节点不可达,就会选举一个sentinel节点来完成自动故障转义

    3.在master-slave进行切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换

    使用redis哨兵

    1.准备三个库的配置文件

    主库配置文件 masterreids.conf

    port 6380
    daemonize yes
    pidfile /data/6380/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6380
    protected-mode no
    
    

    从库1配置文件 slaveredis1.conf

    port 6381
    daemonize yes
    pidfile /data/6381/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6381
    protected-mode no
    slaveof  127.0.0.1 6380  
    
    

    从库2配置文件 slaveredis2.conf

    port 6382
    daemonize yes
    pidfile /data/6382/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6382
    protected-mode no
    slaveof  127.0.0.1 6380 
    
    

    2.创建三个数据库的数据文件夹

    mkdir -p  /data/{6380,6381,6382}
    

    3.分别启动三个数据库实例

    redis-server masterredis.conf 
    redis-server slaveredis1.conf
    redis-server slaveredis2.conf
    

    4.准备三个哨兵(sentinel)的配置文件,这三个配置文件,仅仅是端口的不同,默认端口是26379

    sentinel1.conf

    port 26379  # 端口
    dir /var/redis/data/ # 数据文件
    logfile "26379.log" # 日志
    sentinel monitor mymaster 127.0.0.1  6380  2
    // 当前Sentinel节点监控 192.168.119.10:6380 这个主节点
    // 2代表判断主节点失败至少需要2个Sentinel节点节点同意
    // mymaster是主节点的别名
    sentinel down-after-milliseconds mymaster 30000
    //每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒(30s)没有回复,则判定不可达
    sentinel parallel-syncs mymaster 1
    //当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,
    原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
    sentinel failover-timeout mymaster 180000
    //故障转移超时时间为180000毫秒
    daemonize yes 
    //后台运行哨兵 
    
    

    替换 端口生成另外两个配置文件

    sed 's/26379/26380/g'   sentinel1.conf  > sentinel2.conf
    sed 's/26379/26381/g'   sentinel1.conf  > sentinel3.conf
    

    5.创建数据文件夹

    mkdir -p /var/reids/data/
    

    6.分别启动三个哨兵进程

    redis-sentinel sentinel1.conf
    redis-sentinel sentinel2.conf
    redis-sentinel sentinel3.conf
    
    [redis-4.0.10]# ps -ef |grep redis
    root     15754     1  0 Mar16 ?        00:00:40 redis-server *:6380
    root     15764     1  0 Mar16 ?        00:00:39 redis-server *:6381
    root     15771     1  0 Mar16 ?        00:00:39 redis-server *:6382
    root     16988     1  0 16:09 ?        00:00:00 redis-sentinel *:26379 [sentinel]
    root     16999     1  0 16:10 ?        00:00:00 redis-sentinel *:26380 [sentinel]
    root     17004     1  0 16:10 ?        00:00:00 redis-sentinel *:26381 [sentinel]
    
    

    当主库挂掉30秒后哨兵会将其中一个从库变为主库,并将这个库的配置文件修改(删掉slaveof 配置),然后会让另一个从库变为自己的从库。当挂掉的这个库重启,会在一段时间内将这个库自动变为从库。

    redis集群
    redis3.0集群采用P2P模式,完全去中心化,将redis所有的key分成了16384个槽位,每个redis实例负责一部分slot,集群中的所有信息通过节点数据交换而更新。redis实例集群主要思想是将redis数据的key进行散列,通过hash函数特定的key会映射到指定的redis节点上

    数据分布理论

    分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。

    顺序分区
    在这里插入图片描述

    哈希分区

    例如按照节点取余的方式,分三个节点,节点取余的优点是简单,客户端分片直接是哈希+取余

    1~100的数据对3取余,可以分为三类

    • 余数为0
    • 余数为1
    • 余数为2

    在这里插入图片描述

    一致性哈希

    客户端进行分片,哈希+顺时针取余

    虚拟槽分区

    Redis Cluster采用虚拟槽分区

    虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。
    Redis Cluster槽的范围是0 ~ 16383。
    槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,
    每个节点负责一定数量的槽。
    

    搭建redis cluster

    搭建三主三从的数据库主从集群

    1.准备6个数据库节点(7000~7005 )各个节点仅是端口的不同

    # redis-7000.conf 
    port 7000
    daemonize yes
    dir "/opt/redis/data"
    logfile "7000.log"
    dbfilename "dump-7000.rdb"
    cluster-enabled yes   #开启集群模式
    cluster-config-file nodes-7000.conf  #集群内部的配置文件
    
    
    sed 's/7000/7001/g'  redis-7000.conf > redis-7001.conf 
    sed 's/7000/7002/g'  redis-7000.conf > redis-7002.conf 
    sed 's/7000/7003/g'  redis-7000.conf > redis-7003.conf 
    sed 's/7000/7005/g'  redis-7000.conf > redis-7005.conf 
    
    

    2.分别启动6个redis节点

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

    3.配置ruby环境,一键创建redis机群slot槽位分配

    安装ruby解释器

    yum install ruby -y  
    

    下载ruby操作redis的模块

    wget http://rubygems.org/downloads/redis-3.3.0.gem      
    gem install -l redis-3.3.0.gem
    

    先找到ruby的绝对路径

    [opt]# find / -name  redis-trib.rb 
    /opt/redis-4.0.10/src/redis-trib.rb
    
    

    一键开启redis集群槽位分配

    /opt/redis-4.0.10/src/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
    
    
    [root@izhk773c62kz06z redis-4.0.10]# /opt/redis-4.0.10/src/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
    >>> Creating cluster
    >>> Performing hash slots allocation on 6 nodes...
    Using 3 masters:
    127.0.0.1:7000
    127.0.0.1:7001
    127.0.0.1:7002
    Adding replica 127.0.0.1:7004 to 127.0.0.1:7000
    Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
    Adding replica 127.0.0.1:7003 to 127.0.0.1:7002
    >>> Trying to optimize slaves allocation for anti-affinity
    [WARNING] Some slaves are in the same host as their master
    M: 1b1d442426ade3249d833f910531579bf70a6209 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
    M: 1429bfd7306b2bec90b86a5f4e3c0c4105f286fc 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
    M: 285d0ad96a9de180786c3ea1b682aeeab727eb8b 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
    S: 6af27019c3230081b0b492ffacb29a4548b9db58 127.0.0.1:7003
       replicates 285d0ad96a9de180786c3ea1b682aeeab727eb8b
    S: 29b1640bab990b358291b7e547bc6b4beefd74f4 127.0.0.1:7004
       replicates 1b1d442426ade3249d833f910531579bf70a6209
    S: 92b567379ee3e5c7488a2dc0a6984d4358d01e33 127.0.0.1:7005
       replicates 1429bfd7306b2bec90b86a5f4e3c0c4105f286fc
    Can I set the above configuration? (type 'yes' to accept): yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join..
    >>> Performing Cluster Check (using node 127.0.0.1:7000)
    M: 1b1d442426ade3249d833f910531579bf70a6209 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
       1 additional replica(s)
    S: 92b567379ee3e5c7488a2dc0a6984d4358d01e33 127.0.0.1:7005
       slots: (0 slots) slave
       replicates 1429bfd7306b2bec90b86a5f4e3c0c4105f286fc
    M: 1429bfd7306b2bec90b86a5f4e3c0c4105f286fc 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
       1 additional replica(s)
    S: 29b1640bab990b358291b7e547bc6b4beefd74f4 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 1b1d442426ade3249d833f910531579bf70a6209
    S: 6af27019c3230081b0b492ffacb29a4548b9db58 127.0.0.1:7003
       slots: (0 slots) slave
       replicates 285d0ad96a9de180786c3ea1b682aeeab727eb8b
    M: 285d0ad96a9de180786c3ea1b682aeeab727eb8b 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
       1 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    
    

    4.以集群模式登陆redis-cluster

    redis-cli -p 7000 -c
    

    5.向集群中写入数据,查看数据重定向

    [root@izhk773c62kz06z redis-4.0.10]# redis-cli -p 7000 -c
    127.0.0.1:7000> keys *
    (empty list or set)
    127.0.0.1:7000> set v1 1
    OK
    127.0.0.1:7000> set v2 2
    -> Redirected to slot [13550] located at 127.0.0.1:7002
    OK
    127.0.0.1:7002> set v5 3
    -> Redirected to slot [1033] located at 127.0.0.1:7000
    OK
    127.0.0.1:7000> get v5
    "3"
    127.0.0.1:7000> get v2
    -> Redirected to slot [13550] located at 127.0.0.1:7002
    "2"
    127.0.0.1:7002> 
    
    

    django使用redis

    安装django-redis模块

    pip3 install django-redis
    

    在settings中配置redis配置

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100},
                "PASSWORD": "12345",
            }
        }
    }
    
    

    视图中使用

    from django_redis import get_redis_connection
    conn = get_redis_connection("default")
    

    使用redis做缓存

    全站缓存

    # 中间件配置
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
    

    单视图缓存

    from django.views.decorators.cache import cache_page
    @cache_page(60 * 15)
    def my_view(request):
       ...
    

    url缓存

    from django.views.decorators.cache import cache_page
    
    urlpatterns = [
    	url(r'^index/$', cache_page(60 * 15)(my_view)),
    ]
    

    页面局部缓存

    {% load cache %}
    {% cache 5000 缓存key %}
        缓存内容
    {% endcache %}
    

    使用Redis做session

    # 配置session存储
    SESSION_ENGINE = "django.contrib.sessions.backends.cache"
    SESSION_CACHE_ALIAS = "default"
    
  • 相关阅读:
    java Class.getResource和ClassLoader.getResource
    Ext Grid控件的配置与方法
    BLANK_IMAGE_URL
    js中变量和jsp中java代码中变量互相访问解决方案
    PL/SQL
    滴滴2021后端开发岗笔试:
    顺丰科技2021研发岗笔试:贪心算法应用
    2021顺丰科技研发笔试: 深度优先算法的应用
    动态规划算法轻松解决01背包,完全背包,多重背包问题
    寻找二叉树的最近公共祖先
  • 原文地址:https://www.cnblogs.com/zgboy/p/12701288.html
Copyright © 2011-2022 走看看