【redis】介绍与功能

为什么要用Redis

随着时代的发展,数据量逐渐加大。最开始是单机MySql时代,但是这种方式需要不断的查找数据库,效率低。因此考虑采用了缓存的方法。memecache。
后面开始考虑表的垂直切分,多数据库协同。到最后的集群。

NoSQL特点

NoSQL = NotOnly SQL。可以不需要传统MySQL的表行列。非关系数据库。
解耦!

  1. 方便扩展(数据库之间没有关系,很好扩展!)
  2. 大数据的高性能,基于缓存,读写速度很快
  3. 数据类型多样,不需要事先设计数据库。

Redis(remote dictionary sever)远程字典服务。基于内存,可以持久化的日志型、Key-Value数据库。

单机MySQL

瓶颈:1.数据量太大,一个机器放不下;2.数据索引(B+tree),一个机器的内存放不下;3。访问量大(无法读写分离),一个服务器无法处理

缓存(读写分离)+MySQL

利用缓存提高读效率,不用每次都进行数据库的查询。

垂直拆分+水平拆分+集群

分库分表,解决写的压力

数据类型丰富,改用非关系型数据库

关系型数据库不方便。采用redis为代表的非关系型数据库。

键值对类型数据库:redis,主要是内存存储,查找速度快。
列存储数据库:HBase 分布式的分拣系统
文档型数据库:MongoDB

缓存击穿、缓存穿透与缓存雪崩

前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。
在这里插入图片描述

缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决策略
布隆过滤器:接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;

缓存空对象:从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击。

缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。

解决方案:

  1. 设置热点数据永远不过期,但是会增加空间消耗。
  2. 接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用时候,进行熔断,失败快速返回机制。
  3. 布隆过滤器。bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小,
  4. 加互斥锁,互斥锁。保证只有一个线程可以查询热点的key。参考代码

缓存雪崩

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

  1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  2. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
  3. 设置热点数据永远不过期。

发布与订阅

通过SUBSCRIBE命令,客户端可以订阅一个或者多个频道。或者通过PSUBSCRIBE订阅一个或者多个模式。

Redis中频道是采用了字典的形式,键的值是一个链表。每有新增加的订阅者,就把客户端添加到订阅者链表的尾部。而模式订阅采用了链表的结构,链表中的每个节点都包含了一个Pubsub Pattern结构。保存了客户端的名称和订阅的模式

事务

通过MULTI、EXEC、WATCH等命令实现事务功能。在事务执行完毕旗舰,服务器不会中断事务而去执行其他客户端的命令请求。

每个redis客户端都有自己的事务状态,这个事务状态保存在客户端状态(redisClient)中。事务状态包含一个事务状态和一个已入队命令计数器。事务队列采用先进先出的方式保存入队命令。在客户端向服务器发送EXEC命令之后,服务器会遍历这个事务ui列,执行命令。

WATCH命令

实际上WATCH命令是一个乐观锁,在执行EXEC命令之前,监视任意数量的数据库键,并且在EXEC执行时,检查被监视的键是否存在被修改,如果是的话,服务器会拒绝执行事务,并返回事务失败。

  • 实现方式:
    数据库(redisDB)保存了一个watched_keys的字典,键是被watch的数据库键,字典的值是一个链表,链表记录了所有监视这个键的客户端。执行数据库修改指令时,会检查字典,看看有没有被监视的键,如果有被监视的键刚刚被修改,就会打开客户端的REDIS_DIRTY_CAS标识,表示事务的安全性被破坏。

在执行EXEC之前,服务器会检查客户端的CAS标识有没有被打开,如果是则拒绝执行事务。

ACID性质

  • 原子性
    Redis是原子性的,事务队列的命令要不全部执行,要不一个都不执行。如果事务出现了命令入队错误,事务中的所有命令都不会被执行。但是,与其他关系型数据库不同,redis不支持事务回滚机制。即事务队列中某个命令在执行期间出现了错误,整个事务也会继续执行。

Redis的作者解释说,不支持事务回滚是因为这种复杂的功能和redis追求的简单高效的设计主旨不符合,并且他认为,redis事务的执行时错误通常都是编程错误造成的,这种错误通常只会出现在开发环境中,而很少会在实际的生产环境中出现,所以他认为没有必要为redis开发事务回滚功能。

  • 一致性
    数据符合数据库本身的定义和要求,没有包含非法和无效的错误数据。redis是满足的。
  • 隔离性
    Redis是单线程的方式执行事务,因此串行运行,是隔离的。
  • 持久性
    这取决于持久化的参数。主要是AOF的参数。太高的持久化频率会影响性能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值