Redis基础知识总结

一、初识Redis

Redis是什么?
Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库。与传统数据库不同的是,Redis 的数据是存在内存中的,所以读写速度非常快,被广泛应用于缓存方向。Redis可以将数据写入磁盘中,保证了数据的安全不丢失,而且Redis的操作是原子性的。

Redis优缺点?
优点:

  • 基于内存操作,内存读写速度快。
  • 支持多种数据类型,包括String、Hash、List、Set、ZSet等。
  • 支持持久化。Redis支持RDB和AOF两种持久化机制,持久化功能可以有效地避免数据丢失问题。
  • 支持事务。Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
  • 支持主从复制。主节点会自动将数据同步到从节点,可以进行读写分离。
  • Redis命令的处理是单线程的。Redis6.0引入了多线程,需要注意的是,多线程用于处理网络数据的读写和协议解析,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多路复用(multiplexing)程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
  • 当被监听的套接 字准备好执行连接accept、read、write、close等操作时, 与操作相对应的文件事件就会产生, 这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

虽然文件事件处理器以单线程方式运行, 但通过使用 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数据库。

特性:

  • 键值型,value支持多种不同数据结构,功能丰富
  • 单线程,每个命令具备原子性(6.0以后支持多线程主要对网络请求方面使用多线程)
  • 低延迟,速度快(基于内存、IO多路复用、良好的编码)
  • 支持数据持久化
  • 支持主从集群,分片集群
  • 支持多语言客户端(Java、python、)
1. Redis 安装

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
2. 启动Redis

默认安装在/usr/local/bin目录下,该目录以及默认配置到环境变量,因此可以在任意目录下运行这些命令。其中

  • redis-cli:是redis提供的命令行客户端
  • redis-server:是redis的服务端启动脚本
  • redis-sentinel:是redis的哨兵启动脚本
2.1 默认启动

执行 redis-server即可

2.2 后台启动

指定配置文件:如果要让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

2.3 开机自启动
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服务
3. redis的客户端
3.1 redis的命令行客户端

./redis-cli -h 127.0.0.1 -p 6379 -a Passw0rd

redis-cli启动

./redis-cli 输入auth +空格+ 刚才设置的密码`

3.2 图形化桌面客户端

安装连接:

https://github.com/uglide/RedisDesktopManager 没有提供window版的

https://github.com/lework/RedisDesktopManager-Windows/releases 这个是Windows版的

二、分布式缓存

由于单节点Redis的问题:由于Redis是内存存储服务器重启/宕机可能会丢失数据

单节点redis的并发能力问题:虽然单节点的redis的并发能力不错,但是无法满足如618这样的高并发场景

单节点redis故障恢复问题 :如果redis宕机,则服务器不可用,需要一种自动的故障恢复手段

单节点redis的存储能力问题:内存存储的数据量难以满足海量数据要求

  • 数据丢失问题、
  • 并发能力问题、
  • 存储能力问题、
  • 故障恢复问题
1.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慢一些。

哪种持久化方式更好,取决于具体的使用场景和需求:

  • 如果对数据完整性要求较高,可以选择AOF持久化方式。AOF可以提供更高的数据安全性,能够尽量减少数据丢失的风险。
  • 如果对备份和恢复速度要求较高,并且可以容忍一定程度的数据丢失,可以选择RDB持久化方式。RDB文件紧凑,备份和恢复速度相对较快。
  • 在某些场景下,也可以同时使用两种持久化方式,以充分利用它们的优势,并根据具体情况进行配置。

总而言之,RDB和AOF都有各自的优缺点,选择哪种持久化方式更好需要根据具体的需求和场景来决定。

Redis提供了两种持久化方案:RDB(Redis Database)和AOF(Append Only File),它们可以同时使用,也可以单独选择其中一种。

RDB持久化:
RDB是Redis默认的持久化方式,它会将内存中的数据以二进制形式保存到硬盘上。在配置文件redis.conf中,可以通过以下参数来设置RDB持久化:
    a. save <seconds> <changes>:表示经过指定的秒数和指定的写操作次数后,自动触发RDB持久化。例如 save 900 1 表示900秒内有至少1个键被修改时触发RDB持久化。
    b. dbfilename <filename>:表示指定保存RDB文件的文件名,默认为"dump.rdb"。
    c. dir <directory>:表示指定保存RDB文件的目录,默认为Redis启动的当前目录。
    d. stop-writes-on-bgsave-error yes/no:当RDB持久化出现错误时,是否停止写入操作,默认为"yes"。
AOF持久化:
AOF持久化会将每个写操作追加到一个日志文件中,通过重新执行日志文件中的写操作来恢复数据。在配置文件redis.conf中,可以通过以下参数来设置AOF持久化:
    a. appendonly yes:表示开启AOF持久化,默认为"no"。
    b. appendfilename <filename>:表示指定保存AOF文件的文件名,默认为"appendonly.aof"。
    c. appendfsync <option>:表示指定何时将写操作同步到磁盘,有三个选项可选:
        always:每个写操作都同步到磁盘,安全性最高,但性能最差。
        everysec:每秒同步一次,平衡了安全性和性能。
        no:让操作系统来决定同步频率,性能最好,但安全性较低。
    d. auto-aof-rewrite-percentage <percentage>:在AOF文件大小超过上一次重写文件大小的百分比时,自动触发AOF文件重写,默认为100。
    e. auto-aof-rewrite-min-size <size>:在AOF文件大小超过上一次重写文件大小的固定值时,自动触发AOF文件重写,默认为64mb。
以上是RDB和AOF持久化的基本配置方式,根据实际需求可以进行相应的调整。另外,在修改配置文件后,需要重启Redis服务器使配置生效。

三、消息队列

消息队列(message Queue),字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色:

  • 消息队列:存储和管理消息,也被称为消息代理(Message Broker)
  • 生产者:发送消息到消息队列
  • 消费者:从消息队列获取消息并处理消息

redis提供了三种不同的方式来实现消息队列:

  • list结构:基于list结构模型消息队列
  • PubSub:基本的点对点消息队列
  • Stream:比较完善的消息队列模型
1. 基于list结构模拟消息队列

消息队列(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)

四、redis中的一些问题解决

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)是三种常见的缓存相关问题。

  1. 穿透:穿透指的是当一个请求查询一个不存在于缓存中的数据时,这个请求会直接访问数据库或其他后端服务,而不经过缓存。由于该数据在缓存中不存在,所以对于每次请求都会导致对后端资源的直接访问,增加了后端的负载压力。解决穿透问题的方法是使用缓存布隆过滤器(Bloom Filter)或简单的null值缓存,即将不存在的数据在缓存中保存一个特殊的值,如null,从而避免对后端资源的无谓访问。
  2. 击穿:击穿指的是在缓存中存在某个热点数据,但该数据突然失效,此时大量的请求同时涌入,导致请求直接访问后端服务,造成后端压力剧增。解决击穿问题的方法是使用互斥锁(Mutex Lock)或分布式锁,即在缓存失效时,通过加锁保证只有一个请求重新加载数据到缓存,其他请求等待并直接从缓存中获取数据。
  3. 雪崩:雪崩指的是当缓存中的大量数据同时失效或者缓存服务不可用时,所有的请求都会直接访问后端服务,导致后端服务瞬时的负载过大,甚至引起服务崩溃。解决雪崩问题的方法主要有两个方面:
    • 建立缓存的高可用架构,如使用 Redis 的主从复制、哨兵模式或集群模式,确保缓存服务的稳定性和可靠性。
    • 设置合理的缓存过期时间,并采用不同的过期时间策略,如加入随机值或设置过期时间的削峰策略,避免大量缓存同时失效造成的压力集中。
A. 穿透就是访问了一个数据库中没有的key,由于数据库中没有,在Redis中也就没有缓存,每次请求都会会直接查询数据库。这样就有被攻击的风险,解决的办法可以在查询数据库之后往Redis中存入一个null值。但是这样做也有坏处,就是如果一旦缓存的null值没有失效,而时间数据库已经更新了该key,就会导致查询到脏数据。于是我们可以借助布隆过滤器来进行拦截。
B. 击穿就是在一个热点数据刚好失效时,大量的请求直接访问到了数据库,造成数据库的压力剧增。解决的方法,可以设置热点数据永不过期。
C. 雪崩就是大量的热点数据,设置了相同的过期时间,在同一时刻失效,导致大量请求访问到数据库,可能会导致数据库宕机。解决的方法,可以对过期时间设置一个随机值。

总结来说,穿透、击穿和雪崩是在缓存应用中常见的问题,需要针对不同场景采取相应的解决方法,以提高缓存的命中率和系统的稳定性。
就是访问了一个数据库中没有的key,由于数据库中没有,在Redis中也就没有缓存,每次请求都会会直接查询数据库。这样就有被攻击的风险,解决的办法可以在查询数据库之后往Redis中存入一个null值。但是这样做也有坏处,就是如果一旦缓存的null值没有失效,而时间数据库已经更新了该key,就会导致查询到脏数据。于是我们可以借助布隆过滤器来进行拦截。
B. 击穿就是在一个热点数据刚好失效时,大量的请求直接访问到了数据库,造成数据库的压力剧增。解决的方法,可以设置热点数据永不过期。
C. 雪崩就是大量的热点数据,设置了相同的过期时间,在同一时刻失效,导致大量请求访问到数据库,可能会导致数据库宕机。解决的方法,可以对过期时间设置一个随机值。


总结来说,穿透、击穿和雪崩是在缓存应用中常见的问题,需要针对不同场景采取相应的解决方法,以提高缓存的命中率和系统的稳定性。
  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值