Redis

1.非关系型数据库

基础数据类型:String(字符串)、List(列表)、Set(集合)、Hash(散列表)、Zset(有序集合)

String:基础的key-value模式 常用于缓存

List: 基础的key-value模式,不过value为list格式,可以根据list的特性,实现最新消息排队功能

Set: 基础的key-value模式,value为set格式,根据set不容许重复数据的特性,可以用于实现标签,点赞,收藏,转发等;在此基础上,根据标签来进行推送也可以(INCR 命令)

Hash: 个人理解为升级版的String,可以更节省时间

Zset: 不容许重复元素,且每个元素都有一个对应的double类型的分数,因此可以用于排行榜相关的功能

特殊数据类型: HyperLogLogs(基数统计),Bitmaps (位图),geospatial (地理位置)

 HyperLogLogs : 自动去重,但是存在误差,可以用于统计数据,但是需要接受微小误差的情况

Bitmaps:一种vlaue值只有0,1的模式,可以用于适用该模式的数据,如统计用户打卡,登陆等只有2种状态的数据

geospatial:地理位置相关,可以用于存储地理位置,进行相关计算,如点位距离,半径距离等

2.为什么使用Redis

  • Redis的数据是存储在内存中,所有读写性能优异
    • 高性能:用户第一次从硬盘读取数据后,将访问的数据存在缓存中,这样在下一次用户访问时就会直接从缓存中获得数据,获取速度大大加快
    • 高并发:操作缓存的承受是大于访问数据库,避免出现高并发情况,减少数据库压力
  • 支持数据持久化,支持AOF和RDB俩种持久化方式
  • 数据结构丰富而简单,支持多种数据结构
  • 采用单线程避免多线程的各种锁和性能消耗问题(文件事件分派器队列消费的单线程),使用多路复用I/O复用模型,非阻塞IO
  • 拥有自身的VM机制,避免了调用系统函数所浪费的时间
  • 支持事务,支持中从复制,主机会自动将数据同步到从机,可以进行读写分路

3.使用中要注意什么

  • 数据库容量受物理内存限制,不能进行海量数据的高性能读写
  • 不具备自动容错和恢复能力,需要小心使用,避免主机从机的宕机以及随意的切换IP而照成数据丢失
    • 解决办法:Redis持久化机制
  • 很难支持在线扩容,容易造成资源浪费

4.缓存类型

  • 本地缓存
  • 分布式缓存
  • 多级缓存

5.如在非阻塞的去查询数据

使用scan命令代替keys命令去查询数据,而不阻塞,但是要在客户端做一次去重

6.持久化机制

  • 持久化就是把内存中的数据写到磁盘中,防止服务宕机了内存数据丢失
  • 持久化机制
    • RDB(默认):一种快照机制,每隔一段时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期
      • 优点
        • 只有一个dump.rdb文件,方便持久化
        • 使用fork子进程来进行写操作,而主线程继续处理命令,达到性能最大化,保证了Redis的高性能
        • 数据集大时,比AOF的启动效率高
      • 缺点:数据安全性低,如果在持久化过程中Redis发生故障会照成数据丢失
    • AOF:每次写执行命令记录都到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。数据恢复Redis会优先选择AOF恢复
      • 优点
        • 数据安全。通过配置appendfsync属性可以将每次命令操作都记录到AOF文件中
        • append模式和rewrite模式。避免服务器数据丢失,在重写前删除无用数据
      • 文件较大,恢复速度慢,启动速率低
  • 一般情况下,我们要将数据数据进行备份,比如在本地放一份,在另外地方也放一份备份仿制丢失。当我们因为宕机等原因回复数据时,一般会采用RDB做数据恢复,AOF做数据补全。

7.Redis持久化数据和缓存怎么做扩容

  • 缓存:一致性哈希实现动态扩容缩容
  • 持久化存储:必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样

8.Redis怎样处理过期键:惰性处理和定期过期

  • 定时过期:设置定时去定期清理数据,但是会占用大量CPU资源,从而影响缓存的响应和处理
  • 惰性处理:只有当访问一个key时,才会判断该key是否已过期,过期则清除,节约CPU资源但是会大量占用内存资源
  • 定期过期:每个一段时间扫描一定量的资源,然后去清理其中过期的数据

9.Redis内存数据淘汰策略

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错
  • (常用)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key
  • Redis的内存达到上限,只会影响写入命令,并不会影响读命令
  • Redis内存优化:尽可能的将数据模型抽象到一个散列表里面,减少内存的使用
  • Redis事务具有隔离性(当使用Redis分区时,无法使用Redis事务,因为Redis事务也具有原子性和一致性)

  • Redis集群
    • 哨兵模式:集群监控,消息通知,故障转移,配置中心
      • 需要三个实例保证自己的健壮性
      • 保证Redis集群的高可用性,并不能保证数据零丢失
      • 应该在生产环境和测试环境进行多次测试
    • Redis集群模式的工作原理
      • 通过哈希的方式,将数据分片,每个节点均分存储一定哈希槽(哈希值)区间的数据,默认分配了16384 个槽位
      • 每份数据分片会存储在多个互为主从的多节点上
      • 数据写入先写主节点,再同步到从节点(支持配置为阻塞同步)
      • 同一分片多个节点间的数据不保持一致性
      • 读取数据时,当客户端操作的key没有分配在该节点上时,redis会返回转向指令,指向正确的节点
      • 扩容时时需要需要把旧节点的数据迁移一部分到新节点
    • 一致性hash算法(自动缓存迁移)

  • redis主从复制原理
    • 当启动一个 slave node 的时候,它会发送一个 PSYNC 命令给 master node。如果这是 slave node 初次连接到 master node,那么会触发一次 full resynchronization 全量复制。此时 master 会启动一个后台线程,开始生成一份 RDB 快照文件,同时还会将从客户端 client 新收到的所有写命令缓存在内存中。RDB 文件生成完毕后, master 会将这个 RDB 发送给 slave,slave 会先写入本地磁盘,然后再从本地磁盘加载到内存中,接着 master 会将内存中缓存的写命令发送到 slave,slave 也会同步这些数据
    • 全量复制与增量复制
    • 开始启动阶段 从节点发起请求,进行全量复制主节点的数据,当主节点的数据发生更改的时候,主节点发起请求,从节点进行增量赋值主节点变化的数据,进行数据同步

  • Redis要实现分布式锁吗?怎么实现?
    • 为了解决并发竞争Key的问题,需要使用分布式锁。首推Zookeeper,即每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点。只需要判断有序节点中序号最小的一个就知道是否获得锁。 当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。完成业务流程后,删除对应的子节点释放锁

  • 缓存异常
    • 缓存降级
      • 防止出现缓存雪崩
    • 缓存预热
      • 定时刷新缓存
    • *缓存击穿
      热点数据过期问题:热点数据被大量用户访问,那么在它失效的一瞬间,大量用户的请求就会直接打到数据库造成数据库崩溃
      • 设置热点数据永不过期,加互斥锁
    • &缓存穿透
      攻击行为:缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据,因为此时id所对应的数据并不存在,所有Redis也等于没有发生任何作用。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。
      • 接口层增加校验,采用布隆过滤器
    • *缓存雪崩
      秒杀问题:如果所有首页的Key失效时间都是12小时,中午12点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能DBA都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。这就是我理解的缓存雪崩
      • 缓存数据过期时间设置随机仿制同一时间大量数据过期,甚至对访问进行加锁排队

  • Redis回收进程:LRU算法
    • 一个客户端运行了新的命令,添加了新的数据
    • Redis检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收
    • 一个新的命令被执行,等等
    • 所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下

  • Redis是删除缓存好还是更新缓存好
    • 删除缓存好,因为很多时候缓存不单单是从数据库中取出来的指,而是经过计算得来的值。这样更新缓存的代价会非常大,尤其是缓存计算复杂的场景。而且这样更新出来的缓存也并不能保证是一个访问非常频繁的,比如缓存更新非常的频繁,但是实际访问缺很少,就会产生很多的冷数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值