Redis相关

Redis相关

Redis

使用场景

  1. 数据库缓存,减轻服务器压力,提高系统响应。当系统访问量太大,数据库压力增大,使用redis将访问过的内容或者数据存储起来,再次访问的时候先找缓存,缓存命中返回数据,不命中再找数据库,并回填数据。
  2. session分离。集群或者分布式环境不同web容器管理自己的session,自带的session共享通过网络和IO进行同步,极大地影响性能。
  3. 实现分布式锁。sexNX
  4. 实现乐观锁。watch+incr

数据类型及使用场景

Redis以K-V方式存储KEY的类型是字符串,Value的数据类型有:

String、list、set 、sortedset(zset)有序集合、hash、stream 处理消息、bitmap位图、geo地理位置

String:一个字符串value最多可以存512M。

事务

redis事务是一个单独的隔离操作,事务中所有的命令都会序列化、按顺序执行、执行过程中不会被其他客户端发送来的命令打断。主要作用就是串联多个命令,防止别的命令插队。

multi 开启事务==>输入命令==>exec 开始执行。期间可使用discard取消。

如果期间输入时失败,所有命令全部失效

如果是输入正确 但是执行期间错误,则只有错误的失效 其他正常执行

参考 编译阶段错误直接不能运行,编译成功,运行期间错误

特性

  1. 单独的隔离操作

    事务中所以命令都会序列化、按顺序执行

  2. 没有隔离级别

    队列中那个命令在没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行

  3. 不保证原子性

    事务中如果有一条命令执行失败,其后的命令任然会被执行,没有回滚。

Redis秒杀实现

实现

  1. 获取库存,如果库存null 则还没有开始。
  2. 判断用户是否重复秒杀动作
  3. 判断商品数量,库存数量小于1,秒杀结束
  4. 秒杀过程
    1. 库存-1
    2. 存储秒杀成功用户

测试 yum install httpd-tools -y

ad -n 10000 -c 1000 http://www.baidu.com/?

连接超时

使用连接池。

超卖问题

使用乐观锁事务

  1. 使用redis watch监视库存
  2. 事务 multi中执行update操作

库存遗留问题

库存多了,但是秒杀结束库存还剩余。这是由于乐观锁造成,因为版本号不一致。

解决:使用LUA脚本(redis.version>2.6)

利用redis单线程特性,用任务队列的方式解决多任务并发问题。

https://cloud.tencent.com/developer/article/1890939

持久化操作

RDB

在指定的时间间隔内将内存中的数据集快照写入磁盘(dump.rdb)。

流程

单独创建(fork)子进程—同步数据到临时缓冲区,然后再替换dump.rdb持久化文件:写时复制

优势:周期性大规模备份

缺点:因为是周期性,所以最后一次持久化的数据可能会,因为会复制一份所以空间需要考虑

丢失。

触发:配置文件中配置 save、执行save命令或者bgsave

bgsave会在后在后台异步进行快照操作,快照同时可以响应客户端请求。

AOF

追加日志的形式来对每个写操作增量保存不记录读操作,redis启动时会读取改文件重新构建数据,也就是说重启后会根据日志内的写指令完整执行一次来恢复数据。

AOF默认不开启,需要在配置文件中手动开启appendonly yes

如果同事开启RDB AOF 系统默认取AOF的数据(因为数据不会丢失)

如果AOF文件损坏 可以通过redis-check-aof —fix 修复

流程

  1. 写命令会被append追加到AOF缓冲区
  2. AOF缓冲区根据AOF持久化策略将操作sync同步到磁盘的AOF中
  3. 当文件大小超过重写策略或者手动重写时,会对AOF文件重写,压缩AOF文件容量。
  4. 重启服务时会加载AOF文件恢复数据。

比RDB占用更多空间

推荐

官方推荐都启用

如果数据不敏感可以单独选用RDB

主从复制

主机数据更新后根据配置和策略自动同步到备机,Master写为主,Slave读为主

读写分离性能扩展。

快速恢复

应用问题解决

  1. 缓存穿透:请求多,命中率降低,数据库压力大。
    • 对空值缓存,但是如果每次请求的KEY是随机的,这种处理无效
    • 使用布隆过滤器,判断某个key是否存在。
    • 实时监控报警。
  2. 缓存雪崩: 某一时刻大量缓存失效,导致数据库压力巨大,可能宕机,如果这时候启动数据库又有新的流量冲击数据库,造成再次宕机。
    • 在失效时间上加随机值,避免因同一时间过期导致雪崩
    • 熔断,当流量达到一定的阈值,进行限流。
    • 提高数据库
  3. 缓存击穿:雪崩是大规模KEY失效,击穿是个别的KEY失效并且有大量请求,造成数据库崩溃。
    • 可考虑设置KEY不过期
    • 使用互斥锁。如果缓存失效,只有拿到锁才可以查询数据库。但是这样性能会变差。

分布式锁

通过setnx设置锁,用del释放锁

问题:如果锁一直未释放,可以设置过期时间解决这个问题expire

set user 10 nx ex 10上锁+设置过期时间 同步进行

缓存与数据库一致性

更新策略

  • 理由redis的缓存淘汰策略被动更新 例如LRU
  • TTL被动
  • 更新数据库时主动更新(先更数据库再删缓存—延时双删)
  • 异步更新定时任务,数据不保证实时性
作者

Heng.Wang

发布于

2022-11-15

更新于

2023-09-20

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×