数据库面试(四)--- Redis

Redis概述

Redis(Remote Dictionary Server,远程字典服务),是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对(key/value)数据库。
优点

  • 读写性能优异,读110000次/s,写81000次/s,支持数据持久化,支持事务
  • 数据类型丰富,除了支持string类型的value,还支持hash、set、zset、list等
  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离

缺点

  • Redis适用的场景主要局限在较小数据量的高性能操作和运算上
  • 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或手动切换前端的IP才能恢复
  • 较难支持在线扩容,在集群容量达到上限时在线扩容会很复杂

Redis为什么这么快

  • 完全基于内存,绝大部分请求时纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,优势就是查找和操作的时间复杂度都是O(1)
  • 数据结构简单,对数据操作也简单
  • 采用单线程,便面临不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题
  • 使用多路I/O复用模型,非阻塞I/O

Redis数据类型

String
存储字符串、整数或浮点数,可对整个字符串或部分执行操作,对整数和浮点数执行自增自减操作,用于简单的键值对缓存
List
存储列表,可从两端压入或弹出元素,保留一个范围内的元素,用于存储一些列表型的数据结构,比如粉丝列表、评论列表等
Set
存储无序集合,可进行添加、获取、移除单个元素,检查一个元素是否存在于集合内,计算交集、并集、差集等,用于交并集的操作,比如把两个人的粉丝列表整合成一个
Hash
存储包含键值对的无序散列表,可进行添加、获取、移除单个键值对,获取所有键值对,检查某个键是否存在等,用于操作结构化的数据
Zset
存储有序集合,可进行添加、获取、删除元素,根据分值范围或成员来获取元素,计算一个键的排名等,用于去重排序,如获取排名前几名的用户

Redis使用场景

计数器
可以对 String 进行自增自减运算,从而实现计数器功能。
Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量
缓存
将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。
会话缓存
可以使用 Redis 来统一存储多台应用服务器的会话信息。当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。
查找表
例如 DNS 记录就很适合使用 Redis 进行存储。查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为 缓存不作为可靠的数据来源。
消息队列
List 是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息。不过最好使用 Kafka、RabbitMQ 等消息中间件。
分布式锁实现
在分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步。可以使用 Redis 自带的 SETNX 命令实现分布式锁,除此之外,还可以使用官方提供的 RedLock 分布式锁实现。
其他
Set 可以实现交集、并集等操作,从而实现共同好友等功能。ZSet 可以实现有序性操作,从而实现排行榜等功能。

Redis持久化

持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制
RDB(Redis DataBase)
RDB是Redis默认的持久化方式。在指定的时间间隔内对数据进行快照存储,保存的是dump.rdb文件。通过配置文件中的save参数来定义快照的周期。
在这里插入图片描述
优点:

  • 适合大规模的数据恢复
  • 最大化redis的性能。RDB在保存RDB文件时父进程唯一需要的就是fork出一个子进程,接下来的工作全部由子进程做,父进程不需要再做其他IO操作,所以可以最大化redis的性能
  • 对数据完整性和一致性要求不高

缺点:

  • 在一定间隔时间做一次备份,如果redis发生故障,会丢失最后一次快照后的所有修改
  • Fork的时候,内存中的数据被复制了一份,大致2倍的膨胀性需要考虑

AOF(Append Only File)
将Redis执行的每次写命令记录到单独的日志文件中,只许追加文件但不可以改写文件。当重启Redis会重新将持久化的日志中文件恢复数据(将根据日志文件的内容将写指令从前到后执行一次以完成恢复)。保存的是appendonly.aof文件。
在这里插入图片描述
Rewrite
随着服务器写请求的增多,AOF 文件会越来越大。Redis 提供了一种重写机制,能够去除 AOF 文件中的冗余写命令。
重写原理:AOF文件持续增大而过大时,会fork出一条新进程来将文件重写,遍历新进程的内存中数据,每条记录有一条Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件。Redis会记录上次重写时的aof文件大小,默认配置是当aof文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
优点:

  • 数据安全,aof可以配置appendfsync属性来保证数据完整性
  • 可以在aof文件体积过大时自动的在后台对aof文件进行重写

缺点:

  • AOF文件的体积通常要大于RDB文件的体积
  • AOF的速度可能会慢于RDB

如何选择持久化方式

  • 如果只希望数据在服务器运行的时候存在,可以不适用任何持久化方式
  • RDB的数据不实时,同时开启两种持久化方式的情况下,当 Redis 重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
  • 不建议只使用AOF,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),同时RDB恢复数据集的速度也比AOF的速度要快,而且不会有AOF可能潜在的bug。

Redis事务

Redis可以一次执行多个命令,本质是一组命令的集合。一个事务中所有命令都会被序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞。
总结来说,redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令

Redis事务命令

  • MULTI 标记一个事务的开始
  • EXEC 执行事务
  • WATCH key[key,…] 监视一个或多个key,如果在事务执行之前这个key被其他命令锁改动,那么事务将被打断
  • UNWATCH 取消WATCH命令对多有key的监视
  • DISCARD 取消事务,放弃执行事务内的所有命令
    Redis是单进程程序,并且它保证在执行事务时,不会对事务进行中断,事务可以运行直到执行完所有事务队列中的命令为止。因此,Redis的事务是总是带有隔离性的。

Redis的主从复制

主机数据更新后根据配置和策略,自动同步到从机的master/slaver机制,一主多从,主以写为主,从以读为主。能够做到读写分离、也可以很轻松实现水平扩容,支撑读高并发。
核心机制

  • 一个master node是可以配置多个slave node的(一主多从)
  • slave node 也可以连接其他的slave node(薪火相传)
  • salve node做复制的时候,不会block master node 的正常工作
  • salve node主要用来进行横向扩容,做读写分离,可以提高读的吞吐量

过程原理

  • slave启动成功连接到master后会发送一个SYNC命令
  • master接收到命令后会开始在后台保存快照(RDB持久化过程),并将期间接收到的写命令缓存起来
  • 当快照完成后,master会将快照文件和所有缓存的写命令发送给slave(完全同步、全量复制)
  • 之后,master每当接收到写命令时就会将命令发送给slave,从而保证数据的一致性(增量复制)
  • 只要重新连接master,一次完全同步(全量复制)将被自动执行
    在这里插入图片描述

NoSQL

CAP
C:Consistency 一致性
A:Availability 可用性
P: Partition Tolerance 分区容忍性

BASE
Basically Available 基本可用
Soft State软状态
Eventually Consistent 最终一致性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值