Redis知识体系
2024-11-28 17:25:52 7 举报
AI智能生成
涵盖Redis的基本字符串、可持久化、高可用总结
作者其他创作
大纲/内容
Redis特性
基于内存:数据直接存入内存中,查询速度快
键值型数据库:key为string类型,value类型多样,包括String、Hash、List、Set、SortedSet等。
单线程模型:核心的网络IO和键值对读写由单线程完成,避免线程切换和竞态消耗
低延迟:基于非阻塞的IO多路复用机制,响应速度快
支持数据持久化:通过RDB和AOF两种方式实现
支持主从集群、分片集群:提高数据可用性和扩展性
Redis常用数据类型以及使用场景
Redis特性
快:
1、基于内存操作,操作不需要跟磁盘交互
2、本身就是k-v结构,类似于hashMap,所以查询速度接近O(1)
3. 同时redis自己底层数据结构支持,比如跳表、SDS
4. 命令执行是单线程,同时通信采用多路复用
5. lO多路复用,单个线程中通过记录跟踪每一个sock(I/O流) 的状态来 <br>管理多个I/O流 。
IO多路复用的定义跟原理
定义:IO多路复用模型允许一个线程处理多个输入/输出通道。当某个通道有数据可读或可写时,该线程会被通知,然后执行相应的操作
工作原理:利用一种机制同时监视多个文件描述符,以查看它们是否就绪(读/写/异常),然后进行读写操作。这种技术允许多个连接同时被处理,而不需要为每个连接创建一个新的线程或进程。
实现机制
select模型:使用select函数来监听多个文件描述符(包括网络连接),一旦有一个或多个文件描述符就绪,就会通知Redis进行相应的IO操作
poll模型:与select类似,但性能更优。它使用poll函数来监听并处理多个文件描述符
epoll模型:只适用于Linux系统,在高并发场景下性能最好。它使用epoll函数来监听多个文件描述符,并使用事件驱动的方式处理IO操作。
优点与应用
优点
提高并发处理能力:通过IO多路复用,Redis能够使用一个线程来管理多个客户端连接,减少了线程创建和销毁的开销,提高了资源利用率和系统吞吐量。
减少延迟:IO多路复用减少了等待IO操作完成的时间,因为它允许线程在多个连接之间快速切换,而不是阻塞等待单个连接的IO操作完成
简化系统设计:不需要为每个客户端请求创建独立的线程或进程,简化了系统设计和维护的复杂性
应用:IO多路复用特别适合于高并发、大量连接的应用程序,如Redis这样的内存数据库服务器。通过使用IO多路复用,Redis能够同时处理多个客户端请求,从而提高了并发处理能力和系统的性能。
其他特性
更丰富的数据类型 ,虽然都是k、v结构, value可以存储很多的数据类 <br>型
完善的内存管理机制、保证数据一致性:持久化机制、过期策略
支持多种编程语言
高可用,集群、保证高可用
常用数据类型
Strings
基本指令
批量设置:mset huihui niubi huihui1 222
批量获取:mget huihui huihui1
获取长度:strlen huihui
值递增:incr intkey
如果不存在这个key设置成功,存在设置失败(分布式锁):setnx k1 1
应用场景
缓存相关场景 缓存、 token(跟过期属性完美契合)
线程安全的计数场景 (软限流、分布式ID等)
List
存储有序的字符串列表,元素可以重复。列表的最大长度为 2^32 - 1 个元 <br>素(4294967295,每个列表超过 40 亿个元素)。
基本指令
左右添加元素 lpush queue a <br>lpush queue b c
右边添加元素 Rpush queue d e
左右弹出第一条 lpop queue <br>rpop queue
左右弹出第一条,并设置超时,直到有数据弹出或者超时blpop queue 10 <br>brpop queue 10
取值 lindex queue 0 <br>lrange queue 0 -1
使用场景
用户消息时间线<br>因为list是有序的 所以我们可以先进先出 先进后出的列表都可以做
消息队列<br>List提供了两个阻塞的弹出操作:BLPOP/BRPOP,可以设置超时时间。 <br>BLPOP:BLPOP key1 timeout 移出并获取列表的第一个元素, 如果列表<br>没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
Hash
基本指令
hset h1 f 6 <br>hset h1 e 5<br>hmset h1 a 1 b 2 c 3 d 4 <br>hget h1 a<br>hmget h1 a b c d <br>hkeys h1<br>hvals h1 <br>hgetall h1<br>hincrby h1 a 10 给某个字段添加值
hexists h1 y 查询key中file是否存在 <br>hdel h1 a<br>hlen h1
应用场景
1. 存储对象类的数据(官网说的) 比如一个对象下有多个字段
2. 统计类的数据 我可以对单个统计数据进行单独操作
set
String类型的无序集合,最大存储数量 2^32-1(40 亿左右)。 并且他们的 <br>添加、删除元素的时间都是O(1)。
基本指令
添加一个或者多个元素:sadd huihuiset a b c d e f g
获取所有元素: smembers huihuiset
获取所有元素的个数:scard huihuiset
随机获取一个元素:srandmember huihuiset
应用场景
抽奖 spop跟srandmember 随机弹出或者获取元素
<br>点赞、签到等 sadd 集合存储
交集并集 关注等场景
zset
有序的set,每个元素有个score。
基本指令
批量添加:zadd z1 10 a 20 b 30 d 40 c
根据分数从低到高:zrange z1 0 -1 withscores
根据分数从高到低:zrevrange z1 0 -1 withscores
根据分数范围获取值:zrangebyscore z1 20 30
移除元素:zrem z1 a
应用场景
排行榜
BitMap
位图不是实际的数据类型,而是String类型中定义的一种面向位的操作,所 <br>以这个位图的最大长度是512M。<br>可以容纳最少2^32 不同的位。可以在不同的位置设置0或者1
基本指令
设置位的值:setbit permission 5 1 //把位5设置为1
获取位的值:getbit permission 5 //得到位5的值
获取key的为1的个数:bitcount permission //获取位为1的总数
获取多个bitmap的位操作,比如& | ====bitop AND hbit bitkey permission //获取bitkey与permission <br>的&运算 并且赋值给hbit
应用场景
实时的统计数据
统计一个网站一天有多少用户访问
存储与ID相关的节省空间并且高性能的 是或者否的值<br>用户权限 : 可以用不同的位来代表不同的权限 如果有权限设置为1 <br>否则设置为0 这样我们就能很高效的拿到用户是否有相关权限。
总结:redis常用的5种数据类型以及使用场景!<br>(5)String 缓存(性能提升、token存储),计数场景(软限流)等等<br>(6)Hash 有子键filed 购物车等场景<br>(7)List 有序集合,元素可以重复 队列,有序列表 阻塞队列<br>(8)Set 无序集合,元素不可重复 关注点赞,抽奖 、集合类相关操作<br>(9)ZSet 有序集合,元素不可重复 排行榜
持久化
RDB快照
RDB持久化是Redis默认的持久化方式,它会将内存的数据快照写入二进制文件,这个文件称为RDB文件。RDB持久化实现和数据恢复主要依靠两个核心函数:rdbSave和rdbLoad。rdbSave函数将数据快照写入到RDB文件,rdbLoad函数将数据从文件加载到内存。
RDB持久化触发机制
save命令:执行SAVE命令时,Redis服务器会阻塞客户端命令,直到rdbSave函数完成RDB文件的创建。由于这种方式会阻塞Redis服务器,导致无法处理其他客户端请求,因此在线上环境中一般不推荐使用
bgsave命令:BGSAVE命令通过主线程的fork创建一个子进程来执行rdbSave函数,而父进程(Redis服务器主进程)正常处理客户端的请求。这样Redis持久化操作就不会影响到正常的服务提供。子进程遍历Redis内存中所有的键值对,并使用rdbSaveObject等函数将每个对象进行二进制序列化写入到RDB文件。序列化过程中,Redis会对数据进行压缩,以加快写入文件的速度,并减少文件体积。RDB文件创建完成后,子进程会向父进程发送信号,通知父进程RDB文件创建完成
自动触发:自动触发可以在redis.conf配置文件中设置,当满足特定的条件时,会自动触发持久化。触发后,底层调用的其实是bgsave命令。条件包括:900秒(15分钟)内至少有1个key的值发生变化;300秒(5分钟)内至少有10个key的值发生变化;60秒(1分钟)内至少有10000个key的值发生变化。
优点:
恢复速度快:由于RDB文件是一个紧凑的二进制文件,文件体积小,加载速度快。因此恢复数据的速度比AOF快
文件体积小:RDB文件在写入前进行了压缩,因此文件体积小,有利于文件传输和备份
适合灾备恢复:RDB文件体积小,适合文件传输到其他存储介质上,非常适合用于灾备恢复
缺点:
数据丢失风险:若Redis在两次RDB持久化之间发生故障,则最后一次RDB持久化后的数据就会丢失(数据不一致)
内存占用:在fork创建的子进程进行RDB持久化过程中,子进程会占用与父进程相同的内存资源,可能会导致Redis性能下降
版本兼容:RDB文件为一个二进制文件,不同版本的Redis之间可能存在兼容性问题
AOF
AOF持久化机制是通过记录Redis服务器所执行的写命令来记录数据库状态。AOF文件以追加的方式记录Redis所执行过的所有修改的命令,将每一条修改命令记录进文件appendonly.aof中(先写入os cache,每隔一段时间fsync到磁盘)。Redis服务重启时会重新执行AOF文件中的命令来实现数据恢复到内存中
功能实现分为:命令追加、文件写入、文件同步、文件重写、重启加载
命令追加:当AOF持久化开启时,服务器在执行完一个写命令后,Redis不会直接阻塞服务器来等待AOF文件写入完成。Redis采用异步写入策略,会将这个命令以RESP协议格式追加到AOF缓冲区(aof_buf,一个内存中的数据结构)中
文件写入:Redis服务器进程是一个事件循环,在每个事件循环结束前,会使用后台一个线程(或进程)会调用flushAppendOnlyFile函数将AOF缓冲区(aof_buf)中的命令内容写到AOF文件中。这个后台过程不会阻塞Redis主线程处理新的命令
文件同步:AOF文件会根据appendfsync参数设置的持久化策略同步到磁盘。appendfsync的参数包括
always:每次有新命令写入到AOF缓冲区时,执行一次fsync将命令追加到AOF文件中,非常慢,也非常安全
everysec:每次写命令写入到aof_buf后,每隔一秒同步到磁盘(默认设置推荐),足够快并且在故障时只会丢失1秒的数据
no:每次写命令写入到aof_buf后,从不fsync,将数据交给操作系统来处理,更快,也更不安全
文件重写:随着服务器运行时间增加,AOF文件会越来越大,这会影响Redis重启时间。因此Redis提供了AOF重写机制,通过创建一个新的AOF文件来替代旧文件,新文件只包含恢复当前数据集所需的最小命令集。重写过程也是异步进行的,并且不会阻塞Redis处理新命令。重写操作由后台子进程进行,不阻塞主进程处理客户端的命令。重写期间,新的写命令会被同时追加到现有AOF文件和重写文件的AOF缓存区(aof_buf)中。重写完成后,主进程会将重写缓存区中的命令追加到新的AOF文件中,并替代旧文件
重启加载:Redis重启后,会加载AOF文件,并重新执行文件中写命令来恢复内存数据
优点
数据完整性高:AOF文件包含了每个写操作的详细记录,提供了更好的数据恢复能力
灵活性高:可以通过配置appendfsync参数来平衡数据安全和写入性能
缺点
写入性能损失:每个写操作都需要被追加到AOF缓冲区和写入磁盘,可能会增加写入操作的延迟
AOF文件可能过大:随着服务器运行时间的增加,AOF文件会越来越大,影响Redis的重启时间和性能。不过,Redis提供了AOF重写机制来优化AOF文件的大小
混合持久化
为了兼顾RDB快照和AOF日志的优点,Redis还提供了混合持久化策略。在这种策略下,可以同时启用RDB快照和AOF日志,以实现更好的数据保护和恢复能力。混合持久化的实现方式是在AOF文件的开头添加一个RDB格式的数据快照,然后将后续的写操作以AOF的格式追加到文件尾部。这样,在Redis重启时,可以先加载RDB快照快速恢复大部分数据,然后再重放AOF日志中的写操作来恢复剩余的数据
优点
恢复速度快:由于结合了RDB快照的快速加载特性,混合持久化在恢复数据时速度更快
数据完整性高:通过结合AOF日志的详细记录特性,混合持久化提供了更高的数据完整性
各种持久化的适用场景
RDB快照
数据量较大:当Redis数据库中存储的数据量较大时,使用RDB快照可以生成一个紧凑的二进制文件,该文件包含了数据库在某个时间点的数据快照
对数据完整性要求不高:如果对数据一致性要求不是特别高,可以容忍少量的数据丢失,RDB快照是一个很好的选择。因为RDB是基于时间间隔的持久化,可能在两次快照之间会有数据丢失
需要快速恢复:由于RDB文件是压缩的二进制文件,恢复时速度较快,适用于需要快速恢复数据的场景
AOF日志持久化适用场景
对数据完整性要求高:如果应用程序对数据一致性要求非常高,不能容忍数据丢失,那么应该选择AOF日志持久化。因为AOF记录了每个写操作命令,通过重新执行这些命令可以恢复数据到最新状态
可以接受性能损耗:AOF日志持久化在写入性能方面可能会有一些损失,因为每个写操作都需要被追加到AOF缓冲区和写入磁盘。因此,如果应用程序可以接受一定的性能损耗,那么可以选择AOF日志持久化
混合持久化适用场景
对数据安全性和性能要求均高:如果应用程序既需要确保数据的安全性,又需要保证Redis的性能,那么可以选择混合持久化。混合持久化在恢复数据时,可以先加载RDB快照快速恢复大部分数据,然后再重放AOF日志中的写操作来恢复剩余的数据
需要快速恢复数据并减少故障恢复时间:混合持久化可以缩短Redis的启动时间,因为RDB快照提供了数据的快速加载,而AOF日志则确保了数据的完整性
提高主从同步效率:在主从复制场景中,混合持久化可以提高主从同步的效率,因为从节点可以先加载RDB快照快速同步大部分数据,然后再通过AOF日志同步增量数据
高可用:集群与分布式
主从架构
工作原理
如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个PSYNC<br>命令给master请求复制数据。<br>master收到PSYNC命令后,会在后台进行数据持久化通过bgsave生成最新的rdb快照文件,持久化期<br>间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完<br>毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后<br>再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。<br>当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多<br>个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送<br>给多个并发连接的slave。
哨兵
Redis Cluster集群
Redis Cluster是Redis官方提供的分布式集群解决方案,它可以将多个Redis节点组成一个分布式集群,实现数据的分布式存储和处理。该模式旨在满足大规模数据存储需求,同时提高系统的可用性和稳定性
特性
数据分片
Redis Cluster采用分片技术,将键值对分散存储在多个节点中
它预先分配了16384个哈希槽(slots),每个节点负责维护一部分哈希槽,并在这些哈希槽上存储对应的键值对
客户端发送命令时,Redis Cluster会根据键名计算哈希值,并将哈希值映射到一个对应的哈希槽上,然后将命令转发到负责该哈希槽的节点上进行处理
高可用
Redis Cluster支持主从复制和故障转移
每个分片都有一个主节点和多个从节点,主节点负责处理写操作,而从节点负责复制主节点的数据并处理读请求
当主节点出现故障时,Redis Cluster会自动从可用的从节点中提升一个新的主节点,从而确保数据的可用性和服务的连续性
可扩展
Redis Cluster支持动态扩展,可以在需要时添加新的节点
集群管理软件redis-trib负责节点的添加、删除和数据迁移等操作,从而简化了集群管理的工作
工作原理
节点互联:<br>所有Redis节点使用PING-PONG机制进行互联,通过心跳检测来维护节点间的连接状态。<br>集群中某个节点的失效,需要整个集群中超过半数的节点监测都失效才算真正的失效。<br>客户端连接:<br>客户端不需要中间代理层(proxy),可以直接连接集群中的任意一个可用节点。<br>客户端发送命令时,接收命令的节点会根据键名计算出命令要处理的数据库键属于哪个哈希槽。如果刚好是当前槽,则节点直接执行命令;否则,节点会返回一个MOVED错误,指引客户端转向至正确的节点。<br>数据迁移:<br>Redis Cluster的重新分片操作可以将任意数量已经指派给某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且相关槽所属的键值对也会从源节点被移动到目标节点。<br>该过程可以在线进行,由redis-trib负责执行,包括准备迁移、获取键名、迁移键值对和更新集群状态等步骤。
优缺点
优点:<br>数据分布均衡,能够动态调整数据分布。<br>无中心架构,提高了系统的可扩展性和可用性。<br>提供了集群管理工具redis-trib,简化了集群管理的工作。
缺点:数据通过异步复制,不保证数据的强一致性。<br>客户端实现相对复杂,需要处理MOVED和ASK等重定向错误。<br>不支持跨节点的事务,只支持单节点的事务。<br>部分Redis命令在集群模式下不支持,如KEYS、SCAN等命令
0 条评论
下一页