redis从小白到大佬

redis是什么

简单的说redis是一种在内存中存储数据的数据库,其内部采用 key-value的形式进行存储。redis的读取速度非常快。因为它与MySql等常规数据库不同,不用与硬盘交互来读取数据。另外,redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同的业务场景。除此之外,redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。

Redis的优点

  1. 性能极高,高并发
    在这里插入图片描述
    如图所示,用户在第一次访问某个数据库空的数据的时是从硬盘上读取的,读取速度比较慢。这是我们可以利用redis创建一个缓存,存储相应的数据(value)其并给命名(key)。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可!
    在实际项目中,数据库往往不足以支持用户的频繁请求。而redis可以把用户对数据库的请求转移到缓存中,这样用户的一部分请求会直接到缓存这里而不用经过数据库。

  2. 丰富的数据类型

    Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

  3. 可持久化
    与java自提供的Map不同,redis可以本地化到相应的磁盘中,重启的时候可以再次加载进行使用。因为AOF(append-only file)持久化的性能较好。下面只介绍AOF机制。
    默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:

	appendonly yes

开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof。

在Redis的配置文件中存在三种不同的 AOF 持久化方式,它们分别是:

appendfsync always    #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec  #每秒钟同步一次,显示地将多个写命令同步到硬盘
appendfsync no        #让操作系统决定何时进行同步

为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。

缺点

  1. 由于redis是存储在内存上,由于设备的限制,所存储的数据量会比较小。
  2. 会出现缓存雪崩和缓存穿透。具体解决办法下文进行探讨。

redis的过期时间和内存淘汰机制

我们在使用redis的时候可以设置一个过期时间。当超过这个过期时间之后,与之对应的key随即删除。下面是两种删除方式

  • 定期删除:redis默认是每隔 100ms 就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载!
  • 惰性删除:定期删除可能会导致很多过期 key 到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,也是够懒的哈!

但是仅仅通过这两种方法不足以删除内存中的所有key。这就会导致大量的key堆积在内存中,导致内存耗尽。怎么解决这个问题呢? redis 内存淘汰机制
redis 提供 6种数据淘汰策略:

  • volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的)

  • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

  • no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!

4.0版本后增加以下两种:

  • volatile-lfu:从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰
  • allkeys-lfu:当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的key

缓存雪崩和缓存穿透问题解决方案

什么是缓存雪崩?

简介:缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。

有哪些解决办法?
事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉
事后:利用 redis 持久化机制保存的数据尽快恢复缓存
在这里插入图片描述

什么是缓存穿透?

缓存穿透说简单点就是大量请求的 key 根本不存在于缓存中,导致请求直接到了数据库上,根本没有经过缓存这一层。举个例子:某个黑客故意制造我们缓存中不存在的 key 发起大量请求,导致大量请求落到数据库。下面用图片展示一下(这两张图片不是我画的,为了省事直接在网上找的,这里说明一下):

有哪些解决办法?
最基本的就是首先做好参数校验,一些不合法的参数请求直接抛出异常信息返回给客户端。比如查询的数据库 id 不能小于 0、传入的邮箱格式不对的时候直接返回错误消息给客户端等等。

  • 缓存无效 key
  • 布隆过滤器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值