Redis数据库基础(一)

本文介绍了Redis的基础知识,包括Redis的优缺点、使用Redis作为缓存的原因、Redis与map/guava的区别、与memcached的不同、Redis的线程模型以及常见数据结构的应用场景。此外,还讨论了Redis的性能问题及解决方案、持久化机制的选择、如何扩容以及实现异步队列的方法。
摘要由CSDN通过智能技术生成

1. 什么是redis?有什么优缺点?

  • 简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向。是一个开源的高性能非关系型(NoSQL)的键值对数据库。
  • 另外,redis 也经常用来做分布式锁
  • Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。
  • redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。

优缺点
(1)优点
读写速度快、支持持久化、数据结构丰富、支持主从复制。

(2)缺点
受物理内存的限制、不具备自动容错和恢复功能、较难支持在线扩容

2.为什么要用 redis(为什么要用缓存)?

主要实现“高性能”和“高并发

  • 高性能。假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变的之后,同步改变缓存中相应的数据即可
  • 高并发。直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。

3.为什么要用 Redis 而不用 map/guava 做缓存?

缓存分为本地缓存分布式缓存

以 Java 为例,使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 jvm 的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。

使用 redis 或 memcached 之类的称为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性。缺点是需要保持 redis 或 memcached服务的高可用,整个程序架构上较为复杂。

4.redis 和 memcached 的区别

大概下面三种:

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型,redis不仅仅支持String,同时还提供list,set,zset,hash等数据结构的存储

(2) redis的速度比memcached快很多

(3) redis可以持久化其数据,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中。

5.redis 的线程模型

redis 内部使用文件事件处理器 file event handler,这个文件事件处理器是单线程的,所以 redis 才叫做单线程的模型。它采用 IO 多路复用机制同时监听多个 socket,根据 socket 上的事件来选择对应的事件处理器进行处理。

文件事件处理器的结构包含 4 个部分:

  • 多个 socket
  • IO 多路复用程序
  • 文件事件分派器
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

多个 socket 可能会并发产生不同的操作,每个操作对应不同的文件事件,但是 IO 多路复用程序会监听多个 socket,会将 socket 产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理。

6.redis 常见数据结构以及使用场景分析

(1) String
String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。 常规key-value缓存应用; 常规计数:微博数,粉丝数等

(2) Hash
hash 是一个 string 类型的 field 和 value 的映射表,其实就是一个hashmap,hash 特别适合用于存储对象,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值。 比如我们可以 hash 数据结构来存储用户信息,商品信息等等
在这里插入图片描述
(3)List
list 就是双向链表,Redis list 的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表,消息列表等功能都可以用Redis的 list 结构来实现。

(4)Set
set 对外提供的功能与list类似是一个列表的功能,特殊之处在于 set 是可以自动排重的。当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。可以基于 set 轻易实现交集、并集、差集的操作

Redis可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。这个过程也就是求交集的过程。

(5)Sorted Set
和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列

举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息,适合使用 Redis 中的 Sorted Set 结构进行存储。

7.Redis常见性能问题和解决方案?

(1)Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化。

(2)如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

(3)为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。

(4)尽量避免在压力较大的主库上增加从库

(5)Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。

(6)为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变。

8.Redis 的持久化机制是什么?各自的优缺点?

很多时候我们需要持久化数据也就是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机器、机器故障之后恢复数据),或者是为了防止系统故障而将数据备份到一个远程位置。

Redis 提供两种持久化机制 RDB(快照(snapshotting),默认) 和 AOF(只追加文件(append-only file)) 机制

RDB

RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。

redis.conf配置文件中默认有此下配置:
在这里插入图片描述

优点:

1、只有一个文件 dump.rdb,方便持久化。
2、容灾性好,一个文件可以保存到安全的磁盘。
3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能。
4.相对于数据集大时,比 AOF 的启动效率更高。

缺点:数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)

AOF
与快照持久化相比,AOF持久化 的实时性更好。开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。

优点:数据安全、可以解决数据一致性问题。

缺点:AOF 文件比 RDB 文件大,且恢复速度慢、比 rdb 启动效率低。

9.如何选择合适的持久化方式

(1)应该同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。

(2)如果允许部分数据丢失,可以使用RDB方式,并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此之外,使用RDB还可以避免AOF程序的bug。

(3)如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式。

10.Redis怎么扩容?

(1)如果Redis被当做缓存使用时,使用一致性哈希实现动态扩容缩容。

(2)如果Redis被当做一个持久化存储使用,使用Redis集群进行扩容。

11.假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?

使用keys指令可以扫出指定模式的key列表。

查找以 runoob 为开头的 key:

redis 127.0.0.1:6379> KEYS runoob*
1) "runoob3"
2) "runoob1"
3) "runoob2"

如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?

redis有一个关键的特性,redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。

12.Redis如何实现异步队列?

使用list类型保存数据信息,rpush生产消息,lpop消费消息,当lpop没有消息时,可以sleep一段时间,然后再检查有没有信息,如果不想sleep的话,可以使用blpop, 在没有信息的时候,会一直阻塞,直到信息的到来。redis可以通过pub/sub主题订阅模式实现一个生产者,多个消费者,当然也存在一定的缺点,当消费者下线时,生产的消息会丢失。

Redis如何实现延时队列?

使用sortedset,使用时间戳做score, 消息内容作为key,调用zadd来生产消息,消费者使用zrangbyscore获取n秒之前的数据做轮询处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值