Redis是什么?
Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库。与传统数据库不同的是,Redis 的数据是存在内存中的,所以读写速度非常快,被广泛应用于缓存方向。Redis可以将数据写入磁盘中,保证了数据的安全不丢失,而且Redis的操作是原子性的。
Redis优缺点?
优点:
缺点:
Redis为什么这么快?
基于内存:Redis是使用内存存储,没有磁盘IO上的开销。数据存在内存中,读写速度快。
IO多路复用模型:Redis 采用 IO 多路复用技术。Redis 使用单线程来轮询描述符,将数据库的操作都转换成了事件,不在网络I/O上浪费过多的时间。
IO多路复用模型是一种高效处理多个IO任务的方法,它允许单个进程或线程同时监听多个IO事件,从而实现并发处理IO操作。
在传统的IO模型中,当一个IO操作阻塞时,整个进程或线程都会被阻塞,无法进行其他任务。而采用IO多路复用模型后,可以同时监听多个IO事件,当任意一个IO事件可读或可写时,系统会通知进程或线程进行相应的处理,而不需要等待所有IO操作都完成。
理解IO多路复用模型可以从以下几个方面入手:
1. 多路:指的是可以同时处理多个IO事件,例如可同时监听多个文件描述符或套接字。
2. 复用:指的是利用一个线程或进程来处理多个IO事件,提高系统资源利用率。
3. 非阻塞:在采用IO多路复用模型时,IO操作通常采用非阻塞模式,即非阻塞地向内核发起IO请求并立即返回,这样可以避免因一个IO操作阻塞导致整个进程或线程被阻塞。
通过使用IO多路复用模型,可以极大地提高系统的并发性能和响应速度。常见的IO多路复用技术有select、poll、epoll等,它们在不同的操作系统中实现方式略有差异,但都提供了一种高效的IO事件监听机制,适用于各种类型的网络编程和文件操作场景
讲讲Redis的线程模型?
Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。
虽然文件事件处理器以单线程方式运行, 但通过使用 I/O 多路复用程序来监听多个套接字, 文件事件处理器既实现了高性能的网络通信模型, 又可以很好地与 redis 服务器中其他同样以单线程方式运行的模块进行对接, 这保持了 Redis 内部单线程设计的简单性。
原文链接:https://blog.csdn.net/weixin_39158966/article/details/130027764
为什么选择使用Redis,Redis有什么好处?
Redis是一款基于内存的key-value数据库,它的查询效率非常高,读可以达到每秒10万次,写可以达到8万次左右。
Redis还支持丰富的数据结构:String、list、set、ZSet、hash,单个value可以存储1G数据
Redis还可以对存入的key-value设置过期时间
Redis诞生于2009年全称是Remote Dictionary Server,远程词典服务器,是一个基于内存的键值对型NoSQL数据库。
特性:
https://redis.io/download
注意这个网页有下载链接,页面往下拉有教程,但此教程未必适用。
【下载解压进目录】
$ wget https://download.redis.io/releases/redis-6.2.6.tar.gz
$ tar xzf redis-6.2.6.tar.gz
$ cd redis-6.2.6
$ make && make install
默认安装在/usr/local/bin目录下,该目录以及默认配置到环境变量,因此可以在任意目录下运行这些命令。其中
执行 redis-server即可
指定配置文件:如果要让redis以后台方式启动,则必须修改redis的配置文件,就在我们之前解压的redis安装包下(/usr/local/redis),名字叫redis.conf:
vi redis.conf
使用"/"+关键字 enter键 查找关键字位置
1. 第一步先备份这个配置文件,
cp redis.conf redis.conf.bak
2. 然后修改redis.conf文件中的一些配置
a. 后台启动设置:
# 允许访问的地址,默认是127.0.0.1,会导致只能本地访问;修改为0.0.0.0则可以在任意IP访问,生产模式下不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可以后台运行
daemonize yes
# 密码,设置后访问redis必须输入密码
requirepass 123321
b. 其他设置
# 监听的端口 默认是6379
port 其他端口
# 工作目录,默认当前目录,也就是运行redis-server时的目录,日志、持久化等文件会保存在这个目录下
dir .
# 数据库数量 设置为1,代表只使用一个数据库,默认有十六个数据库,编号0-15
database 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"
执行 redis-server redis.conf 即可启动redis
通过 ps -ef |grep redis 查看
杀死进程 kill -9 端口
停止服务 redis-cli -u 123321 shutdown
1. 新建一个系统服务文件:
vim /etc/systemd/system/redis.service
然后将下面内容添加到新创建的文件里
[Unit]
Description=redis-server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/redis-6.2.6/redis.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
2. 重新加载系统服务使其生效
systemctl daemon-reload
然后可以通过
systemctl start redis 启动redis服务
systemctl status redis 查看redis服务状态
systemctl stop redis 停止redis服务
systemctl restart redis 重启redis服务
systemctl enable redis 设置开机自启动redis服务
./redis-cli -h 127.0.0.1 -p 6379 -a Passw0rd
redis-cli启动
./redis-cli
输入auth +空格+ 刚才设置的密码`
安装连接:
https://github.com/uglide/RedisDesktopManager 没有提供window版的
https://github.com/lework/RedisDesktopManager-Windows/releases 这个是Windows版的
由于单节点Redis的问题:由于Redis是内存存储服务器重启/宕机可能会丢失数据
单节点redis的并发能力问题:虽然单节点的redis的并发能力不错,但是无法满足如618这样的高并发场景
单节点redis故障恢复问题 :如果redis宕机,则服务器不可用,需要一种自动的故障恢复手段
单节点redis的存储能力问题:内存存储的数据量难以满足海量数据要求
RDB持久化
RDB全程Redis Database Backup file(redis数据备份文件),也被叫做redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。
快照文件称为RDB文件,默认是保存在当前运行目录
redis-cli
127.0.0.1:6379>save
127.0.0.1:6379>bgsave 后台异步执行 开启子进程执行RDB,避免主进程受到影响
bgsave开始会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入rdb
总结:
1. RDB方式bgsave的基本流程?
a.fork主进程得到子进程,共享内存空间
b.子进程读取内存数据并写入新的RDB文件
c.用新的RDB文件替换旧的RDB文件
2.RDB会在什么时候执行?save 60 1000代表啥含义?
a.默认是服务停止时
b.代表60秒内至少执行1000次修改则触发RDB
3.RDB的缺点?
a.最新的数据会丢失
b.RDB执行间隔时间长,两次RDB之间写入数据有丢失的风险
c.fork子进程,压缩,写出RDB文件都比较耗时
AOF持久化00
AOF全称为Append Only File(追加文件)。Redis处理的每个写命令都会记录在AOF文件,可以看作是命令日志文件
AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF
# 是否开启AOF功能,默认是no
appendonly yes
# AOF文件名称
appendfilename "appendonly.aof"
AOF的命令记录的频率也可以通过redis.conf文件来配置:
# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always 【这种方案:写内存同时写磁盘,数据安全得到了保障,但是性能差】
# 写命令执行完成先放入AOF缓冲区,然后表示每隔一秒将缓冲区数据写道AOF文件,是默认方案
appendfsync everysec 性能高,但是出现宕机情况会丢失一秒内的数据
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no 性能最高,数据安全性差还不如 RDB
Redis中的RDB(Redis Database)和AOF(Append-only File)是两种持久化机制,用于将数据写入硬盘以便在重启后恢复数据。它们有以下区别:
RDB:RDB是一种快照式持久化方式,将Redis的数据在某个时间点上进行快照并保存到硬盘上的文件中。RDB文件是二进制格式,包含了Redis在某个时间点上的数据和状态信息。RDB的优点是文件紧凑,适合用于备份和恢复。而缺点是在系统崩溃时可能会有数据丢失的风险,因为它是定期进行快照操作的,所以如果发生崩溃,最后一次快照之后的数据将丢失。
AOF:AOF是一种追加日志文件的方式,将每个写操作追加到文件末尾。通过重新执行AOF文件中的写操作,可以完全恢复Redis的状态。AOF文件以文本格式存储,可以方便地进行查看和修改。AOF的优点是能够提供更高的数据安全性,因为它是将每个写操作追加到文件中,所以即使系统崩溃,也可以通过重新执行AOF文件中的写操作来恢复数据。而缺点是AOF文件相对较大,对于大型数据库来说,AOF的恢复速度可能会比RDB慢一些。
哪种持久化方式更好,取决于具体的使用场景和需求:
总而言之,RDB和AOF都有各自的优缺点,选择哪种持久化方式更好需要根据具体的需求和场景来决定。
Redis提供了两种持久化方案:RDB(Redis Database)和AOF(Append Only File),它们可以同时使用,也可以单独选择其中一种。
RDB持久化:
RDB是Redis默认的持久化方式,它会将内存中的数据以二进制形式保存到硬盘上。在配置文件redis.conf中,可以通过以下参数来设置RDB持久化:
a. save :表示经过指定的秒数和指定的写操作次数后,自动触发RDB持久化。例如 save 900 1 表示900秒内有至少1个键被修改时触发RDB持久化。
b. dbfilename :表示指定保存RDB文件的文件名,默认为"dump.rdb"。
c. dir :表示指定保存RDB文件的目录,默认为Redis启动的当前目录。
d. stop-writes-on-bgsave-error yes/no:当RDB持久化出现错误时,是否停止写入操作,默认为"yes"。
AOF持久化:
AOF持久化会将每个写操作追加到一个日志文件中,通过重新执行日志文件中的写操作来恢复数据。在配置文件redis.conf中,可以通过以下参数来设置AOF持久化:
a. appendonly yes:表示开启AOF持久化,默认为"no"。
b. appendfilename :表示指定保存AOF文件的文件名,默认为"appendonly.aof"。
c. appendfsync
消息队列(message Queue),字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色:
redis提供了三种不同的方式来实现消息队列:
消息队列(Message Queue),Redis的list数据结构是一个双向链表,很容易模拟出队列效果
# 创建一个空的列表作为消息队列
message_queue = []
# 将消息添加到队列中(发送消息)
def send_message(message):
message_queue.append(message)
# 从队列中取出消息(接收消息)
def receive_message():
if len(message_queue) > 0:
message = message_queue.pop(0)
return message
else:
return None
# 测试代码
send_message("消息1")
send_message("消息2")
msg = receive_message()
print("接收到的消息:", msg)
msg = receive_message()
print("接收到的消息:", msg)
1、说一下Redis的删除策略和淘汰策略
定时删除 在设置key过期时间(setex)的同时,设置一个定时器,在key过期时直接删除。缺点是占用CPU会比较多
惰性删除 设置key过期时间之后不去管他,当使用key的时候检查key是否过期。对CPU非常友好,缺点是无法删除某些不使用的过期键
定期删除 对key进行定期抽检,删除过期的key。是比较折中的办法,缺点是比较难确定执行的频率,并且有脏数据的风险,可能会查 到一些没有及时删除的过期key。
Redis中采用定期删除+惰性删除,检查时间定为每秒10次。
淘汰策略:即使有了删除策略,也有可能数据量过多,内存都被占满了。这时Redis就可以按照一定的规则将数据从内存中删除掉,常见的淘汰策略有
noeviction(默认) 不删除任何数据,内存不足则报错
volatile-lru 设置了过期时间的key,淘汰最久没使用的数据(least recently used)
volatile-lfu 设置了过期时间的key,淘汰最近使用频率较低的key(least frequently used)
volatile-ttl 淘汰即将过期的key
volatile-random 随机淘汰
allkeys-lru 所有key,淘汰最久没使用的key
allkeys-lfu 所有key,淘汰最近使用频率较低的key
allkeys-random 随机淘汰
原文链接:https://blog.csdn.net/krusehou/article/details/129005418
2、在 Redis 中,穿透(Cache Penetration)、击穿(Cache Breakdown)和雪崩(Cache Avalanche)是三种常见的缓存相关问题。
A. 穿透就是访问了一个数据库中没有的key,由于数据库中没有,在Redis中也就没有缓存,每次请求都会会直接查询数据库。这样就有被攻击的风险,解决的办法可以在查询数据库之后往Redis中存入一个null值。但是这样做也有坏处,就是如果一旦缓存的null值没有失效,而时间数据库已经更新了该key,就会导致查询到脏数据。于是我们可以借助布隆过滤器来进行拦截。
B. 击穿就是在一个热点数据刚好失效时,大量的请求直接访问到了数据库,造成数据库的压力剧增。解决的方法,可以设置热点数据永不过期。
C. 雪崩就是大量的热点数据,设置了相同的过期时间,在同一时刻失效,导致大量请求访问到数据库,可能会导致数据库宕机。解决的方法,可以对过期时间设置一个随机值。
总结来说,穿透、击穿和雪崩是在缓存应用中常见的问题,需要针对不同场景采取相应的解决方法,以提高缓存的命中率和系统的稳定性。
就是访问了一个数据库中没有的key,由于数据库中没有,在Redis中也就没有缓存,每次请求都会会直接查询数据库。这样就有被攻击的风险,解决的办法可以在查询数据库之后往Redis中存入一个null值。但是这样做也有坏处,就是如果一旦缓存的null值没有失效,而时间数据库已经更新了该key,就会导致查询到脏数据。于是我们可以借助布隆过滤器来进行拦截。
B. 击穿就是在一个热点数据刚好失效时,大量的请求直接访问到了数据库,造成数据库的压力剧增。解决的方法,可以设置热点数据永不过期。
C. 雪崩就是大量的热点数据,设置了相同的过期时间,在同一时刻失效,导致大量请求访问到数据库,可能会导致数据库宕机。解决的方法,可以对过期时间设置一个随机值。
总结来说,穿透、击穿和雪崩是在缓存应用中常见的问题,需要针对不同场景采取相应的解决方法,以提高缓存的命中率和系统的稳定性。