Redis简介(二)

Redis简介(二)

Redis高级特性以及用法

生存时间
  • 在Redis中,可以使用expire命令设置一个键的生存时间,生存时间到了以后Redis会自动删除它
    • expire 设置生存时间
    • ttl 查看剩余生存时间 生存时间没了会显示-2
    • persist 取消生存时间 就是永久存在的 会显示-1
    • expireat 设置生存时间 时间戳
事务
  • Redis中的事务就是一组命令的集合,事务和命令一样都是Redis的最小的执行单元,一个事务中的命令要么都执行、要么都不执行(原子性)
    • 先将属于一个事务的命令发给Redis进行缓存,最后再让这些Redis执行这些命令
  • 一个事务的实例
    • multi
    • 命令1
    • 命令2
    • exec 事务截止
    • discard 在事务运行之前放弃事务
  • 如果事务运行出现错误的处理方式
    • 语法错误:其中一条指令的语法错误就会导致整个事务不可以执行
    • 运行错误:运行过程中的错误 不会影响其他命令的执行(例如使用list的指令操作set类型的key)
  • Redis不支持回滚
    • 因为Redis不支持回滚才有了Redis事务的简洁快速
  • watch命令
    • 作用:监控一个键或者多个键,一但这个键的值被修改了立马终止之后的事务的执行
    • 但是不能保证其他客户端不修改这一键值,所以我们需要在事务失败的时候重新启动这个事务(就是说事务执行的过程中必须保证这个键值不变,在其他时候键值改变也可以)
    • 注意:当事务执行结束以后即执行完exec命令以后,watch就会取消对所有键值的监控
    • 使用 UNwatch取消监控
发布订阅模式
  • 我们可以使用Redis来实现一个发布订阅的功能
  • subscribe aaa 订阅aaa频道
  • publish aaa message 发布信息 向aaa频道发送message 信息
  • unsubscribe 取消订阅
管道
  • 针对批量数据操作使用效率高 例如批量初始化数据
  • 在这里插入图片描述
  • Redis的pipeline管道在命令行上是没有的,但是Redis支持管道,在Java的客户端可以使用
  • 管道可以减少客户端以及Redis服务器之间的交互从而大大提升命令执行的速度,在执行管道中的命令的时候中间可以添加其他命令执行
事务与管道的区别
  • 相同点:批量执行
  • 不同点:
    • 一个client发起的事务中的命令可以连续执行,而中间不会插入其他client命令,管道命令执行的过程中可以插入其他命令
    • 管道(pipline)的侧重点是效率高
    • 事务(transaction)的侧重点是一致性
    • pipeline不是原子命令,在Redis之中会把一个携带很多命令的pipeline拆分为几个子命令
    • transaction是原子命令

Redis的两种持久化

  • Redis的持久化就是就是把内存中的数据持久化存储到磁盘当中,可以保证Redis重启之后还能恢复之前的数据
RDB(Redis默认)
  • rdb方式的持久化是通过快照完成的,当符合一定条件时redis会自动将内存中的所有数据执行快照操作并存储到硬盘上。默认存储在dump.rdb文件中。(文件名在配置文件中dbfilename)
  • Redis进行快照的时机
    • save 900 1:表示900秒内至少一个键被更改则进行快照。
    • save 300 10
    • save 60 10000
  • 手动执行save或者bgsave命令让redis执行快照
    • 两个命令的区别在于,save是由主进程进行快照操作,会阻塞其它请求。bgsave是由redis执行fork函数复制出一个子进程来进行快照操作。
  • 文件修复:redis-check-rdb
  • rdb的优缺点
    • 优点:由于存储的有数据快照文件,恢复数据很方便。
    • 缺点:会丢失最后一次快照以后更改的所有数据。
  • Redis实现快照的过程
    • Redis使用fork函数复制一份当前进程的副本(子进程)
    • 父进程继续接收并处理客户端发来的请求,而子进程开始将内存中的数据写入到磁盘当中的临时文件
    • 当子进程写入万所有数据后,会使用该临时文件替换原来的旧文件,此次快照完毕
    • 注意:Redis在执行快照的过程中不会删除之前的rdb文件,只有快照结束后才会将所有的旧文件替换成为新的,也就是说任何时候rdb文件都是完整的,值就使得我们可以通过定时备份rdb文件来实现Redis数据库的备份
    • rdb文件是经过压缩的二进制文件,占用的空间会小于内存中的数据
AOF
  • aof方式的持久化是通过日志文件的方式。默认情况下redis没有开启aof,可以通过参数appendonly参数开启。 appendonly yes
  • aof文件的保存位置和rdb文件的位置相同,都是dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改 appendfilename appendonly.aof
  • Redis同步命令的时机
    • appendfsync always 每次都会执行
    • appendfsync everysec 默认 每秒执行一次同步操作(推荐)
    • appendfsync no不主动进行同步,由操作系统来做,30秒一次
  • AOF日志文件重写
    • auto-aof-rewrite-percentage 100(当目前aof文件大小超过上一次重写时的aof文件大小的百分之多少时会再次进行重写,如果之前没有重写,则以启动时的aof文件大小为依据)
    • auto-aof-rewrite-min-size 64mb
    • 手动执行bgrewriteaof进行重写
    • 重写的过程只和内存中的数据有关,和之前的aof文件无关。
    • 所谓的“重写”其实是一个有歧义的词语,实际上, AOF 重写并不需要对原有的 AOF 文件进行任何写和读取, 它针对的是数据库中键的当前值。
  • 动态切换redis持久方式,从RDB 切换到 AOF(支持Redis 2.2及以上)
    • CONFIG SET appendonly yes
    • CONFIG SET save “”(可选)
  • 注意:当Redis启动之后,如果持久化机制RDB、AOF都已经打开了,系统默认会选择AOF来恢复数据,因为一般AOF保存的数据相对完整,如果AOF的数据丢失了也不会从RDB获取,该数据库内容就为空
  • 如果想吧正在运行的Redis数据库从RDB转换为AOF需要先动态切换,在修改配置文件,重启Redis就会从AOF中恢复数据

Redis扩展

Redis的安全策略
  • 设置数据库密码
    • 修改配置requirepass password
    • 验证密码auth password
  • bind参数 可以让数据库在指定IP下才能访问
    • bind 192.168.32.111
    • 注意:bind后面只能指定本机的IP,可以是内网IP也可以是外网IP(本机IP的意思就是指定一个本机的网卡IP 如果说本机有两个网卡,就可以指定一个网卡的IP,我们只能通过指定的网卡IP来对Redis进行访问)
    • bind:127.0.0.1 指定只能在本机访问本机Redis
  • 命令重命名
    • 修改命令的名称rename-command flushall cleanall
    • 禁用命令 rename-command flushall “”
  • 一个Redis实例最多可以存放多少key
    • Redis的存储极限就是系统中的内存值
Redis的优化
  • 精简键名和键值

    • 键名:尽量精简,但是也不能单纯为了节约空间而使用不易理解的键名。
    • 键值:对于键值的数量固定的话可以使用0和1这样的数字来表示,(例如:male/female、right/wrong)
  • 当业务不需要进行持久化的时候,关闭所有持久化机制可以获得最佳的性能

  • slowlog 记录执行慢的命令

    • slowlog-log-slower-than 它决定要对执行时间大于多少微秒(microsecond,1秒 = 1,000,000 微秒)的命令进行记录
    • slowlog-max-len 它决定 slowlog 最多能保存多少条日志
    • 当大仙Redis的性能下降的时候,可以查看日志看是哪些命令执行速度过慢
  • monitor 监控Redis的所有操作

    • 生产环境下不建议使用,除非是为了紧急排查问题 主要目的是监控所有机器对Redis的操作
  • 限制Redis的内存大小

    • 通过redis的info命令查看内存使用情况

    • 如果不设置maxmemory或者设置为0,64位系统不限制内存,32位系统最多使用3GB内存。

    • 修改配置文件中的maxmemory和maxmemory-policy

    • maxmemory:最大内存

    • maxmemory-policy:内存不足时,数据清除策略

    • 如果确定数据量不大,并且内存足够的话就不需要进行Redis的内存限制,如果数量不可预估,并且内存有限的话,尽量限制Redis的使用内存大小,这样可以避免Redis使用swap分区

    • 注意:如果不限制内存,当内存使用完以后,Redis就会占用swap分区,这样性能就比较低了,如果限制了内存,当内存用完的时候就不能再增加数据了,否则会报错OOM,可以设置maxmemory-policy,内存不足时删除数据

      如果一个Redis实例的内存使用率超过可用最大内存(used_memory>可用最大内存),那么操作系统开始进行内存与swap空间交换,把内存中旧的或不再使用的内容写入硬盘上(硬盘上的这块空间叫Swap分区),以便腾出新的物理内存给新页或活动页(page)使用。写入硬盘以后速度就会慢很多了。

  • Redis是单线程模型,客户端传过来的命令式按照顺序执行的,所以想要一次添加多条数据的时候可以使用管道或者是使用可以添加多条数据的命令

Redis的内存碎片
  • 问题:一个4G内存的Redis数据库,里面存储的key只有一万多个,结果服务器却提示内存使用率超过80%了,也没有存储很大的key。
  • 执行info命令查看内存相关信息发现
    • mem_fragmentation_ratio:20.76 (内存碎片率=used_memory_rss/used_memory)
  • 可以看到内存碎片率已经达到了20.76,内存碎片率在1~1.5之间属于正常,但超出1.5的时候就说明redis的内存管理变差了
  • 在这里插入图片描述
  • 产生原因:
    • redis自身的内存分配器,当删除数据的时候,不会马上返还内存,这样就不用每次都向OS申请内存了,从而实现高性能。
    • 修改数据的值,且修改后的value与原来value的大小差异较大。redis的每个k-v对初始化的内存大小是最适合的,当这个value改变了并且原来内存大小不适用的时候,就需要重新分配内存了。
  • 解决方案
    • 重启Redis服务器
    • Redis4.0以后,可以使用新增指令来手动回收内存碎片
Redis的应用场景
  • 排行榜相关
    • 使用sorted set
    • 获取前十名zrevrange zset 0 9
    • 获取某用户排名 zrank zset key
  • 计数
    • 使用incrby来进行计数
  • 队列
    • 使用list中的pop和push可以实现多种队列
  • 手机验证码
    • 可以使用expire来设置验证码的生存时间
  • Redis既可以作为数据库使用,也可以作为缓存系统使用

Redis的主从结构

  • 在这里插入图片描述
  • Redis的复制功能支持多个数据库之间的同步
    • 一类是主数据库(master)
    • 一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,只接收主数据库同步过来的数据
    • 一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。
  • 修改配置文件redis.conf,修改从数据库
    • slaveof ip port
  • 或者在redis-cli命令行中动态执行slaveof命令设置主从关系
  • 通过redis的复制功能可以很好的实现数据库的读写分离,提高服务器的负载能力。主数据库主要进行写操作,而从数据库负责读操作。
  • 在这里插入图片描述
  • 复制的过程:
    1. 当一个从数据库启动时,会向主数据库发送sync命令
    2. 主数据库接收到sync命令后会开始在后台保存快照(执行rdb操作),并将保存快照期间接收到的命令缓存起来
    3. 当快照完成后,redis会将快照文件和所有缓存的命令发送给从数据库
    4. 从数据库收到后,会载入快照文件并执行收到的缓存的命令。
  • 注意:
    • 如果你使用主从复制,那么要确保你的master激活了持久化,或者确保它不会在当掉后自动重启。slave是master的完整备份,因此如果master通过一个空数据集重启,slave也会被清掉。
    • 在配置redis复制功能的时候如果主数据库设置了密码,需要在从数据的配置文件中通过masterauth参数设置主数据库的密码,这样从数据库在连接主数据库时就会自动使用auth命令认证了。相当于做了一个免密码登录。

Redis的哨兵结构

  • 在这里插入图片描述
  • redis的sentinel系统用于管理多个redis服务器,该系统主要执行三个任务
    1. 监控:Redis Sentinel实时监控主服务器和从服务器运行状态
    2. 提醒:当被监控的某个Redis 服务器出现问题时,Redis Sentinel 可以向系统管理员发送通知,也可以通过 API 向其他程序发送通知。
    3. 自动故障转移:当一个主服务器不能正常工作时,Redis Sentinel 可以将一个从服务器升级为主服务器,并对其他从服务器进行配置,让它们使用新的主服务器。当应用程序连接Redis
      服务器时, Redis Sentinel会告之新的主服务器地址和端口

Redis的集群结构

  • 在这里插入图片描述
  • redis集群是一个无中心的分布式Redis存储架构,可以在多个节点之间进行数据共享,解决了Redis高可用、可扩展等问题。redis集群提供了以下两个好处
    • 将数据自动切分(split)到多个节点
    • 当集群中的某一个节点故障时,redis还可以继续处理客户端的请求
  • 一个 Redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。
  • 集群中的主从复制
    • 集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点,继续工作。这样集群就不会因为一个主节点的下线而无法正常工作。
    • 注意:如果某一个主节点和他所有的从节点都下线的话,redis集群就会停止工作了。
  • redis集群不保证数据的强一致性,在特定的情况下,redis集群会丢失已经被执行过的写命令
    • 使用异步复制(asynchronous replication)是 Redis集群可能会丢失写命令的其中一个原因,有时候由于网络原因,如果网络断开时间太长,redis集群就会启用新的主节点,之前发给主节点的数据就会丢失。
  • 添加节点
    • 主节点:如果添加的是主节点,那么我们需要创建一个空节点,然后将某些哈希槽移动到这个空节点里面
    • 从节点:如果添加的是从节点,我们也需要创建一个空节点,然后把这个新节点设置成集群中某个主节点的复制品。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值