Redis第一关之常规用法

简介

Redis不用多说,已经火了很多年了,也用了很多年了。现在做一些归纳总结。
这篇文章主要介绍Redis的常规知识及用法,包括数据结构、使用场景、特性、过期机制、持久化机制。

Redis与Mysql

Mysql是一款基于磁盘的关系型SQL数据库。
Redis是一款基于内存的、非关系型、Nosql数据库,

Mysql的基本构成结构是二维表,由行和列组成。
Redis的数据存储形式是Key-Value结构,由键和值组成。

相较于传统的RDBMS数据库,NOSQL数据库更满足Web2.0时代数据爆炸式需求。不需要固定的格式,严格的关系,提供高并发性能等等。单NOSQL并不能完全取代传统数据库,因此,RDBMS+NOSQL是最好的方式。

下面具体来分析Redis的数据结构

Redis数据结构

Redis是Key-Value结构,Key值都是单字符串,Value也是字符串,但却有9种数据类型,分别如下:

  1. String(字符串)
  2. List(链表)
  3. Set(无序集合)
  4. ZSet(有序集合)
  5. Hash(哈希)
  6. Geo 地理位置
  7. Bitmaps 位图
  8. HyperLogLog 基数统计

除了最后三种特殊数据结构外,常用的5种数据结构可以按类型分类。

1. 按单、多个字符串分类:
String为单个字符串结构
List、Set、Zset、Hash为多字符串结构

2. 在多字符串结构中,再按有序、无序分类
List、ZSet为有序数据结构,其中List底层为链表结构,以插入顺序排序。ZSet通过分数Score来排序。
Set、Hash为无序数据结构,其中Set为无序唯一性集合,会自动去重。

Hash数据结构是以field-value形式,非常适合存储对象结构。同时支持对对象属性的增删。
在这里插入图片描述

Redis应用场景

Redis作为Web2.0时代受欢迎的产物,其基于内存的高性能、过期机制、特殊的数据结构都分别决定了它的用途广泛。

在这里插入图片描述

缓存应用的三大问题

缓存击穿

概念: 缓存将某个或小面积热Key击穿,
造成原因:误操作、缓存过期
解决办法:暂时设置永不过期、增加热点监控

缓存穿透

概念: 请求穿过了缓存,直达缓存后的数据库层,大并发下容易造成数据库宕机,从而影响全局。
造成原因:大并发请求,缓存层未命中,黑客攻击等
解决办法:增加数据有效性校验,对不存在的数据进行Null值缓存,使用布隆过滤器。

缓存雪崩

概念:大面积缓存的key值在同一时间段都未命中
造成原因:key值过期时间过于集中,或者Redis宕机。
解决办法:分散key值得过期时间,通过随机数加权计算。增加Redis高可用性。 

过期时间

在Redis中,很多场景可以通过过期机制来实现。比如短信验证码、七天免登录等。
但是Redis中允许key不设置过期时间,这会让key值永不过期,占用内存。如果不是特殊设计不建议这样使用。

关于Redis的设计缺陷及补丁措施思考

Redis是一款基于内存的数据库,其目的是为了满足快速处理的高并发特性。
但是内存是有物理局限的,它无法像硬盘一样容量可以扩充到很大,也容易受到断电丢失数据影响。
在这里插入图片描述

因此,Redis作者又做了几个补丁。

补丁一:过期机制

如果Redis没有过期机制?

那么意味着,所有存入到内存的数据都是永不过期的,使用完了就得删除,这像是 C++语言开发,而过期机制相当于Java的内存回收机制,操作起来更柔性。

过期机制的底层原理?

Redis内部采用的是定期删除+惰性删除,两种机制相配合保证了最终一定被删除。

定期删除
设置了定时器,每次会取出一部分过期的key进行删除。

为什么不是轮询全部过期的key值?

因为如果内存较大,过期的key值较多,轮询比较耗时,会消耗大量的CPU在轮询上。

那么,未被取出的过期key值如何删除?

惰性删除
惰性删除,类似于java中的类的懒加载,Spring IOC对象的懒加载。
未被定期删除策略命中的过期key,只有当这个key再次被访问时来判断是否要删除。

因此,定期删除+惰性删除策略,一定会删除所有过期的key,但是有一个时间差问题。

某个key值过期了,它的最快删除时间是定期任务第一次扫描就被取出来并删除。它的最慢删除时间是…很久,这取决于定期删除是怎么取出数据的了。

在这里插入图片描述

虽然这些过期的key最终会被删除,但Redis内存容量总是动态变化的,不断的有增量Key,也有不断的删除Key。

在这里插入图片描述
如果:

增量速度 > 删除速度,删除速度>=0(等于0时所有的key都未过期)

Redis内存就会膨胀,逐渐趋于饱和。这时候,那些未被及时删除的过期Key就亟需被找到并删除掉了,作者怎么做的呢?

内存淘汰策略

当出现上述情况时,作者设计了一种内存淘汰机制,使用者可以不同的策略来清理内存,保证Redis能否正常使用。

1. volatile-lru(least recently used) 从设置了过期时间的数据中(server.db[i].expires) 淘汰最近最少被使用的数据。
2. volatile-random 从设置了过期时间的数据中 随机淘汰数据。
3. volatile-lfu 从设置了过期时间的数据中 淘汰最不频繁被使用的数据。

4. allkeys-lru 从所有的数据中(server.db[i].dict) 淘汰最近最少被使用的数据。- 常用
5. allkeys-random 从所有的数据中(server.db[i].dict)随机淘汰数据。
6. allkeys-lfu 从所有的数据中(server.db[i].dict)淘汰最不频繁被使用的数据。

7. volatile-ttl 从设置了过期时间的数据中(server.db[i].expires)淘汰将要过期的数据。
8. no-eviction 禁止淘汰数据。

补丁二: 持久化机制

Redis毕竟是基于内存的数据库,如果断电了肯定会导致数据丢失。所以设计持久化机制是必然的。

作者设计了两种持久化机制:AOF、RDB

AOF持久化

AOF是一种以记录实时日志的方式,将Redis的每个操作命令持久化,其优点是实时性比较强,可以每秒钟记录一次,其缺点是产生的日志量较大,重启恢复时的耗时较长。
AOF有三种模式:同步写回(Always)、每秒写回(Everysec)、系统自动写回(No)

Always同步写回,对性能影响较大,数据不会丢失
Everysec每秒写回,性能适中,数据丢失范围1秒内
No系统自动写回,性能较好,丢失数据范围较大

RDB持久化

RDB是一种全量备份模式,将Redis中的所有数据全部备份下来,可以实现备份和迁移。
其优点是产生的数据量较小,重启时可以快速的恢复,其缺点是实时性较弱,容易产生数据丢失。

RDB持久化时,如果发生在Redis运行中,由于数据是动态变化的,因此常见的备份方式是将Redis其他操作阻塞,直到全量备份完成在放行,另一种方式是Redis作者提供的异步备份。

1. 同步备份 save
2. 异步备份 bgsave

异步备份是bgsave命令,其原理是在主进程中fork一个子进程异步执行,不会阻塞主进程操作。

Redis高可用设计

Redis提供了高可用设计,分别是主从模式、哨兵模式、集群模式。

主从模式
Redis数据库的主从模式和Mysql数据库的主从模式类似,都是以容灾备份为目的设计的,因此当Redis主结点发生故障时,可手动切换为从结点提供服务。
主从模式需要两个Redis结点。

哨兵模式

虽然主从模式可以提供容灾备份的功能,但是当发生故障时,需要手动切换,并不智能。 于是,哨兵模式解决了这个问题。

哨兵模式通过哨兵集群监控所有Redis结点,让主结点发生故障时,自动将主节点踢出,然后重新选择一个从节点作为主节点提供服务,保证了高可用性。
哨兵模式最大的优点是故障自动转移,但至少需要3个Redis结点。

群集模式

群集模式提供了Redis分布式数据存储功能,由于单机内存上限的限制,群集模式解决了这个问题,通过数据分片的形式将Redis数据分散到多个结点,实现容量的横向扩展,每个主结点都需要配置一个从结点作为数据容灾备份,以便故障自动转移。
Redis群集模式一般需要3主3从,共6个Redis结点。

  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值