Redis常用知识

6 篇文章 0 订阅

一.redis常用知识

1、什么是 Redis?简述它的优缺点?

  Redis 的全称是:Remote Dictionary.Server,本质上是一个 Key-Value 类型的内存数据库,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据 flush 到硬盘上进行保存。因为是纯内存操作,Redis 的性能非常出色,每秒可以处理超过 10 万次读写操作,是已知性能最快的Key-Value DB。Redis 的出色之处不仅仅是性能,Redis 最大的魅力是支持保存多种数据结构,此外单个 value 的最大限制是 1GB,不像 memcached 只能保存 1MB 的数据,因此 Redis 可以用来实现很多有用的功能。比方说用他的 List 来做 FIFO 双向链表,实现一个轻量级的高性 能消息队列服务,用他的 Set 可以做高性能的 tag 系统等等。另外 Redis 也可以对存入的 Key-Value 设置 expire 时间,因此也可以被当作一 个功能加强版的memcached 来用。 Redis 的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此 Redis 适合的场景主要局限在较小数据量的高性能操作和运算上。

2、Redis 与 memcached 相比有哪些优势?
  • (1).memcached 所有的值均是简单的字符串,redis 作为其替代者,支持更为丰富的数据类型
  • (2).redis 的速度比 memcached 快很多 redis 的速度比 memcached 快很多.
  • (3).redis 可以持久化其数据 redis 可以持久化其数据
3、Redis 支持哪几种数据类型?

String、List、Set、Sorted Set、hashes

4、Redis 主要消耗什么物理资源?

内存。

5、Redis 有哪几种数据淘汰策略?
  • (1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。
  • (2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用,目前项目在用这种。
  • (3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。应该也没人用吧,你不删最少使用Key,去随机删。
  • (4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐
  • (5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐
  • (6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐
      redis采用的是定期删除+惰性删除策略(redis.conf的内存淘汰策略)。
     定期删除,redis默认每隔100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。
9、Redis 集群方案应该怎么做?都有哪些方案?
9.1.主从复制
  • 主从复制原理:
     从服务器连接主服务器,发送SYNC命令;
     主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
     主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
     从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
     主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
     从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;(从服务器初始化完成)
     主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令(从服务器初始化完成后的操作)

  • 主从复制优缺点:
    优点:
     支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
    为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成
     Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。
     Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
     Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据
    缺点:
     Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
     主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
     Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

9.2.哨兵模式

 当主服务器中断服务后,可以将一个从服务器升级为主服务器,以便继续提供服务,但是这个过程需要人工手动来操作。 为此,Redis 2.8中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。

哨兵的作用就是监控Redis系统的运行状况。它的功能包括以下两个。
(1)监控主服务器和从服务器是否正常运行。
(2)主服务器出现故障时自动将从服务器转换为主服务器。

  • 哨兵的工作方式:
     每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
    如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after- milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)
     如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态
     当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)
     在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。
     当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
     若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。

  • 哨兵模式的优缺点
    优点:
    哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
    主从可以自动切换,系统更健壮,可用性更高。
    缺点:
     Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

3.Redis-Cluster集群
 redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容。

Redis-Cluster采用无中心结构,它的特点如下:
 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
 节点的fail是通过集群中超过半数的节点检测失效时才生效。
 客户端与redis节点直连,不需要中间代理层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

  • 工作方式:
     在redis的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是cluster,可以理解为是一个集群管理的插件。当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
     为了保证高可用,redis-cluster集群引入了主从模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点ping一个主节点A时,如果半数以上的主节点与A通信超时,那么认为主节点A宕机了。如果主节点A和它的从节点A1都宕机了,那么该集群就无法再提供服务了。
10, Redis 哈希槽的概念?

Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key通过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。

11、Redis 集群会有写操作丢失吗?为什么?

Redis 并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。

12、Redis 集群之间是如何复制的?

异步复制

14、Redis 集群如何选择数据库?

Redis 集群目前无法做数据库选择,默认在 0 数据库。

15、Redis 中的管道有什么用?

一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应,这样就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。这就是管道(pipelining),是一种几十年来广泛使用的技术。例如许多 POP3 协议已经实现支持这个功能,大大加快了从服务器下载新邮件的过程。

16、怎么理解 Redis 事务?

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行,事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

17、Redis 如何做内存优化?

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的 key,而是应该把这个用户的所有信息存储到一张散列表里面。

18、使用过 Redis 分布式锁么,它是怎么实现的?

先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。如果在 setnx 之后执行 expire 之前进程意外 crash 或者要重启维护了,那会怎么样?set 指令有非常复杂的参数,这个应该是可以同时把 setnx 和 expire 合成一条指令来用的!

19、什么是缓存穿透?

缓存穿透,即黑客故意去请求缓存中不存在的数据,导致所有的请求都怼到数据库上,从而数据库连接异常

  • (1)利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试
  • (2)采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
  • (3)提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。
20、缓存雪崩,即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。
  • (1)给缓存的失效时间,加上一个随机值,避免集体失效。
  • (2)使用互斥锁,但是该方案吞吐量明显下降了。
  • (3)双缓存。我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。自己做缓存预热操作。然后细分以下几个小点:
    ​ I. 从缓存A读数据库,有则直接返回
    ​ II. A没有数据,直接从B读数据,直接返回,并且异步启动一个更新线程。
    ​ III. 更新线程同时更新缓存A和缓存B。
21、redisw为何如此之快
  • (1)完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
  • (2)数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;
  • (3)采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
  • (4)使用多路I/O复用模型,非阻塞IO;
  • (5)使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
  • (6) 以上几点都比较好理解,下边我们针对多路 I/O 复用模型进行简单的探讨:
      多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
      这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。
22、关于遍历
  • (1) keys * : 如果是线上的环境,不建议使用。 因为当redis中的key数量过多的时候, 执行keys* 会造成长时间的阻塞,导致后面的命令不能快速的执行。影响应用的性能。
  • (2) 使用渐进遍历 : scan 0 [count n] – 指定每次遍历键的数量
23、RDB持久化
  • (1)什么RDB持久化?
    RDB持久化, 是将redis当前进程的数据状态, 以一个快照文件的方式保存到磁盘。

  • (2)RDB 持久化触发的时机

    a. 手动触发
    save命令触发,会在进行生成快照文件的阶段,阻塞redis的主进程。 在这其间其他的命令无法执行。 那么,如果是线上环境,执行save会影响redis的性能。 【不建议使用】

    b. bgsave命令触发, 当主进程接收到bgsave之后, 会fork 一个子进程来处理RDB生成快照的任务。 阻塞的阶段,只是在fork的阶段, 这个时间很短,子进程完成RDB后,会通知主进程。

    c. 自动触发: 默认采用的是bgsave的方式。

  • (3)在redis.conf中的RDB自动触发时机:

    save 900 1 #900秒超过一个key被修改
    save 300 10 #300秒超过10个key被修改
    save 60 10000 #60秒超过一万条key被修改

  • (4)rdb文件相关配置

# The filename where to dump the DB
dbfilename dump.rdb   #默认生成快照文件的名字

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /var/lib/redis #快照文件保存的位置

  • (5)当我们重新去停止/启动redis服务的时候, 会自动生成RDB文件。 确保服务器宕机或断电的时候数据不丢失。
  • (6)RDB的优缺点
    a.优点 :
    ​ -由于RDB文件中保存的是当前进程数据的所有状态, 可以将RDB文件cp到远程服务器,完成远程的备份。
    ​ -redis进程加载RDB文件的速度比较高。
    ​ b. 缺点:
    ​ -redis对于不同版本的快照文件,压缩的二进制格式有区别。 当我们在不同版本间进行RDB备份时, 可能存—在新老版本兼容的问题。
    ​ -无法保证数据的及时备份。无法实现秒级备份。 在两次备份之间可能丢失数据。
24、AOF持久化机制
  • (1)什么是AOF?

​ AOF持久化是将当前进程的数据状态,以一个独立的命令日志的方式进行保存。未来redis会通过将AOF文件中的命令,再次执行一边,完成数据的恢复。

​ AOF机制可以更好的实现数据备份的实时性。

  • (2)开启AOF机制:

    默认redis的AOF是关闭的。
    开启: vi redis.conf 修改appendonly yes

appendonly no   # yes为开启

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"   #AOF文件的名字

  • (3)AOF 同步策略
# If unsure, use "everysec".

# appendfsync always  #每次收到命令立即写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec  #每秒强制写入磁盘一次,在性能和持久化方面做了折中,推荐使用
# appendfsync no      #完全依赖于os,性能最好,持久化没法保证

  • (4)AOF重写

    a. AOF重写的目的,减小AOF的文件。

    b. AOF重写后,aof文件会变小,清除一些无效的命令, 存在一些过期的数据,可以对一些命令进行合并

    c. 触发AOF重写的时机 :

    手动 :bgrewriteaof
    自动 :当同事满足一下两个条件出发

auto-aof-rewrite-percentage 100  #(当前AOF大小-上次重写式AOF大小)/上次重写式AOF大小
auto-aof-rewrite-min-size 64mb   #当前AOF文件大小的限制,默认最小为64mb的时候满足重写条件
```
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码出天空

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值