关于Redis的记忆

1.Redis是什么

  • Redis是C语言开发的一个开源的高性能键值对(key-value)的内存数据库,与传统数据库不一样的是,Redis是非关系型数据库,数据是存储在内存中,读写性能很是高,因此Redis经常做为缓存在系统中存在。
  • Redis还能够用来作分布式锁。
  • Redis提供了多种数据类型来支持不一样的业务场景。
  • Redis支持事务、持久化、多种集群方案

2.为何要用Redis

2.1 提升系统性能

若是碰到须要执行耗时特别久,且结果不频繁变更的 SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求可以迅速响应 。redis

2.2 提升系统并发

在大并发的状况下,全部的请求直接访问数据库,数据库会出现链接异常。这个时候,就须要使用 Redis作一个缓冲操做,用缓存预热将一部分数据提早 加载到Redis中,让请求先访问到 Redis,而不是直接访问数据库算法

3.Redis和Memcached的区别

  • Redis支持更加丰富的数据类型,好比String、List、Set、Hash、SortedSet等,而Memcached只支持简单的String类型
  • Redis支持数据的持久化,能够将内存中的数据保存在磁盘中,重启的时候能够再次加载进行使用;而Memcached把全部的数据都在内存中存储着。
  • Redis3.0以上是原生支持cluster模式的,memcached没有原生的集群模式,须要依靠客户端来实现集中分片写入数据
  • Memcached是多线程的;Redis是单线程的

4.Redis的数据类型以及应用场景

  • String
    String类型就是简单的key-value类型,value能够是String,也能够是数字,。主要用来简单的key-value缓存,好比存储用户的粉丝数之类的;数据库

  • hash
    hash是一个field和value的映射表,适合用于存储对象,好比存储用户基本信息,咱们要修改用户的姓名的时候,就能够直接修改具体的字段;设计模式

  • List
    Redis list就是链表,在项目中应用的也比较多,好比微博的关注列表,粉丝列表等;Redis list能够经过 lrange 命令,就是从某个元素开始读取多少个元素,能够基于 list 实现分页查询,这个很棒的一个功能,基于 redis 实现简单的高性能分页,能够作相似微博那种下拉不断分页的东西(一页一页的往下走),性能高。缓存

  • Set
    set和list相似,也是一个列表功能,可是set是能够自动去重的,set提供了判断成员是否在一个set集合内的重要接口;基于set能够很好的实现交集、并集、差集等。
    好比:在微博应用中,能够将一个用户全部的关注人存在一个集合中,将其全部粉丝存在一个集合。Redis能够很是方便的实现如共同关注、共同粉丝、共同喜爱等功能。服务器

  • Sorted Set
    和set相比,sorted set增长了一个权重参数score,使得集合中的元素可以按score进行有序排列
    举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各类礼物排行榜,弹幕消息(能够理解为按消息维度的消息排行榜)等信息,适合使用 Redis 中的 Sorted Set 结构进行存储。网络

5.Redis的线程模型

反应器设计模式(Reactor pattern) 是一种为处理并发服务请求,并将请求提交到一个或者多个服务处理程序的事件设计模式。 当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收全部的请求,而后派发这些请求至相关的工做线程进行处理。 简单说,就是如何处理多个客户端的并发请求的解决模式。多线程

咱们都知道Redis是单线程模型,从内部结构来看,之因此Redis是单线程的,是由于Redis基于Reactor模式开发了本身的网络事件处理器,这个处理器被称为文件事件处理器,而这个文件事件处理器是单线程的,因此Redis才是单线程模型。文件事件处理器主要包含IO多路复用程序、socket队列、文件事件分派器、事件处理器。如图架构

6.Redis的过时策略

咱们都知道Redis是基于内存来存储的,因此咱们在设置key的时候须要去设置key的过时时间,经过这个过时时间咱们能够指定这个key在内存中的存活时长,那么Redis是怎么来删除这些过时的key的呢?并发

按期删除+惰性删除:

  • 按期删除:Redis默认是每隔100ms随机抽取一些设置了过时时间的key进行检查,判断key是否过时,若是过时了那就删除。可是,这样便会致使不少到了过时时间的key没有被删除。
  • 惰性删除:针对上面的问题,惰性删除就出现了,惰性删除是指程序主动去查询key,再查询的时候若是过时了那么就删除。

可是这样就有一个问题,若是按期删除没有删除,而后程序也没有主动去查询,那么会致使在内存中存在大量的过时key,进而会致使redis的内存耗尽,因此Redis提供了内存淘汰机制。

7.Redis的内存淘汰机制

Redis提供了六种淘汰机制

  • noeviction:当内存不足以容纳新写入数据时,新写入操做会报错
  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(经常使用)
  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key
  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,移除最近最少使用的key
  • volatile-random:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,随机移除某个key
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,有更早过时时间的key优先移除

MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?
经过内存淘汰机制咱们能够淘汰冷数据,将热数据加载到内存中;计算一下20W数据须要的内存,而后设置Redis的内存限制就行

8. Redis的持久化方式

Redis的持久化方式有两种:

8.1 RDB方式

  • RDB
    Redis能够经过建立快照来得到存储在内存里面的数据在某个时间点上的副本。Redis建立快照以后,能够对快照进行备份,能够将快照复制到其余服务器从而建立具备相同数据的服务器副本(Redis主从结构,主要用来提升Redis性能),还能够在便重启服务器的时候使用。Redis默认使用的是RDB持久化方式。
  • RDB原理
    默认Redis会以快照的形式将数据持久化到磁盘中,是一个二进制文件,dump.rdb;当Redis须要作持久化的时候,Redis会fork一个子进程,子进程负责将数据写到磁盘的一个临时rdb文件中,当子进程写完临时文件的时候,会直接将原来的RDB文件替换掉。
  • RDB的优势
    RDB持久化的文件很是适合用于备份,好比说,你能够在最近的 24 小时内,每小时备份一次 RDB 文件,而且在每月的每一天,也备份一个 RDB 文件。 这样的话,即便赶上问题,也能够随时将数据集还原到不一样的版本。RDB 很是适用于灾难恢复。
  • RDB的缺点
    若是须要尽可能避免在服务器故障时丢失数据,RDB方式就不适合。 虽然 Redis 容许设置不一样的保存点(save point)来控制保存 RDB 文件的频率,可是由于RDB 文件须要保存整个数据集的状态, 因此它并非一个轻松的操做。 所以咱们可能会至少 5 分钟才保存一次 RDB 文件。在这种状况下 一旦发生故障停机,就可能会丢失好几分钟的数据。

8.2 AOF方式

把全部的对Redis的服务器进行修改的命令都存到一个文件里,命令的集合。

  • AOF
    使用AOF作持久化,每个命令都会被追加到appendonly.aof中
  • AOF优势
    AOF的默认策略为每秒钟 fsync 一次,固然了也能够设置每一次命令执行一次,在默认配置下,Redis 仍然能够保持良好的性能,而且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,因此主线程能够继续努力地处理命令请求)。

Redis4.0支持同时开启 RDB 和 AOF,系统重启后,Redis 会优先使用 AOF 来恢复数据,这样丢失的数据会最少。

9.缓存雪崩、缓存穿透、缓存击穿问题及解决方案

9.1 缓存雪崩

  • 问题描述
    在同一时间缓存中的key出现大面积的失效,会致使全部的请求所有落在数据库上,短期内数据库没法承担这么多请求可能会崩掉
  • 解决方案
    在设置key的时候过时时间加上一个随机值;对于热点数据能够设置永不过时

9.2 缓存穿透

  • 问题描述
    通常是黑客故意去请求缓存中不存在的数据,致使全部的请求都落到数据库上,形成数据库短期内承受大量请求而崩掉。
  • 解决方案
    有不少种方法能够有效地解决缓存穿透问题,最多见的则是采用布隆过滤器,将全部可能存在的数据哈希到一个足够大的bitmap中,一个必定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法,若是一个查询返回的数据为空(不论是数 据不存在,仍是系统故障),咱们仍然把这个空结果进行缓存,但它的过时时间会很短,最长不超过五分钟。

9.3 缓存击穿

  • 问题描述 缓存击穿与缓存雪崩不一样的是缓存击穿是指一个Key很是热点,在不停地扛着大量的请求,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发直接落到了数据库上,就在这个Key的点上击穿了缓存
  • 解决方案
    1.热点key设置永不过时;
    2.获取加上互斥锁,若是缓存中为空,在获取数据的缓存接口加上互斥锁,经过递归来查询数据,当拿到锁的线程从数据库中查询出数据更新到缓存中,其余的线程也能够获取到

10 Redis的架构模式

10.1 单机版

单个节点redis,通常生产环境中不会使用

10.2 主从架构

经过持久化功能,Redis保证了即便在服务器重启的状况下也不会损失(或少许损失)数据,由于持久化会把内存中数据保存到硬盘上,重启会从硬盘上加载数据。 。可是因为数据是存储在一台服务器上的,若是这台服务器出现硬盘故障等问题,也会致使数据丢失。为了不单点故障,一般的作法是将数据库复制多个副本以部署在不一样的服务器上,这样即便有一台服务器出现故障,其余服务器依然能够继续提供服务。为此, Redis 提供了复制(replication)功能,能够实现当一台数据库中的数据更新后,自动将更新的数据同步到其余数据库上。

在复制的概念中,数据库分为两类,一类是主数据库(master),另外一类是从数据库(slave)。主数据库能够进行读写操做,当写操做致使数据变化时会自动将数据同步给从数据库。而从数据库通常是只读的,并接受主数据库同步过来的数据。一个主数据库能够拥有多个从数据库,而一个从数据库只能拥有一个主数据库。

redis的普通主从模式,能较好地避免单独故障问题,以及提出了读写分离,下降了Master节点的压力。互联网上大多数的对redis读写分离的教程,都是基于这一模式或架构下进行的。但实际上这一架构并不是是目前最好的redis高可用架构。

10.3 哨兵模式

当主数据库遇到异常中断服务后,开发者能够经过手动的方式选择一个从数据库来升格为主数据库,以使得系统可以继续提供服务。然而整个过程相对麻烦且须要人工介入,难以实现自动化。 为此,Redis 2.8开始提供了哨兵工具来实现自动化的系统监控和故障恢复功能。 哨兵的做用就是监控redis主、从数据库是否正常运行,主出现故障自动将从数据库转换为主数据库。

顾名思义,哨兵的做用就是监控Redis系统的运行情况。它的功能包括如下两个。

(1)监控主数据库和从数据库是否正常运行。
(2)主数据库出现故障时自动将从数据库转换为主数据库。

10.4 redis-cluster群集高可用架构

即便使用哨兵,redis每一个实例也是全量存储,每一个redis存储的内容都是完整的数据,浪费内存且有木桶效应。为了最大化利用内存,能够采用cluster群集,就是分布式存储。即每台redis存储不一样的内容。 采用redis-cluster架构正是知足这种分布式存储要求的集群的一种体现。redis-cluster架构中,被设计成共有16384个hash slot。每一个master分得一部分slot,其算法为:hash_slot = crc16(key) mod 16384 ,这就找到对应slot。采用hash slot的算法,其实是解决了redis-cluster架构下,有多个master节点的时候,数据如何分布到这些节点上去。

在redis-cluster架构中,redis-master节点通常用于接收读写,而redis-slave节点则通常只用于备份,其与对应的master拥有相同的slot集合,若某个redis-master意外失效,则再将其对应的slave进行升级为临时redis-master。在redis的官方文档中,对redis-cluster架构上,有这样的说明:在cluster架构下,默认的,通常redis-master用于接收读写,而redis-slave则用于备份,当有请求是在向slave发起时,会直接重定向到对应key所在的master来处理。但若是不介意读取的是redis-cluster中有可能过时的数据而且对写请求不感兴趣时,则亦可经过readonly命令,将slave设置成可读,而后经过slave获取相关的key,达到读写分离

参考文档:

Redis线程模型
Redis持久化RDB和AOF
redis架构演变与redis-cluster群集读写方案
一文看懂Redis的持久化原理
简明的图解Redis RDB持久化、AOF持久化

相关文章
相关标签/搜索