乐陵seo网站优化,wordpress用户聊天,广州沙河一起做网站的网址,网站建设目标论文1 redis的数据结构
2 redis的线程模型
1#xff09; Redis 采用单线程为什么还这么快
之所以 Redis 采用单线程#xff08;网络 I/O 和执行命令#xff09;那么快#xff0c;有如下几个原因#xff1a;
Redis 的大部分操作都在内存中完成#xff0c;并且采用了高效的…1 redis的数据结构
2 redis的线程模型
1 Redis 采用单线程为什么还这么快
之所以 Redis 采用单线程网络 I/O 和执行命令那么快有如下几个原因
Redis 的大部分操作都在内存中完成并且采用了高效的数据结构因此 Redis 瓶颈可能是机器的内存或者网络带宽而并非 CPU既然 CPU 不是瓶颈那么自然就采用单线程的解决方案了 Redis 采用单线程模型可以避免了多线程之间的竞争省去了多线程切换带来的时间和性能上的开销而且也不会导致死锁问题。CPU并不是制约Redis性能表现的瓶颈所在更多情况下是受到内存大小和网络I/O的限制所以 Redis 核心网络模型使用单线程并没有什么问题如果你想要使用服务的多核CPU可以在一台服务器上启动多个节点或者采用分片集群的方式。 Redis 采用了 I/O 多路复用机制处理大量的客户端 Socket 请求IO 多路复用机制是指一个线程处理多个 IO 流就是我们经常听到的 select/epoll 机制。简单来说在 Redis 只运行单线程的情况下该机制允许内核中同时存在多个监听 Socket 和已连接 Socket。内核会一直监听这些 Socket 上的连接请求或数据请求。一旦有请求到达就会交给 Redis 线程处理这就实现了一个 Redis 线程处理多个 IO 流的效果
2Redis 6.0 之后为什么引入了多线程
Redis 的主要工作大体分为两部分 1网络 I/O 2执行命令,一直是单线程模型
在 Redis 6.0 版本之后也采用了多个 I/O 线程来处理网络请求这是因为随着网络硬件的性能提升Redis 的性能瓶颈有时会出现在网络 I/O 的处理上。所以为了提高网络 I/O 的并行度Redis 6.0 对于网络 I/O 采用多线程来处理。但是对于命令的执行Redis 仍然使用单线程来处理所以大家不要误解 Redis 有多线程同时执行命令。
结论6.0的多线程部分是1网络IO的处理上对于执行命令上依然是单线程。
3 redis的持久化方式
Redis 如何实现数据不丢失
AOF日志每执行一条写操作命令就把该命令以追加的方式写入到一个文件里RDB快照将某一时刻的内存数据以二进制的方式写入磁盘混合持久化方式Redis 4.0 新增的方式集成了 AOF 和 RBD 的优点
Redis 的 AOFAppend-Only File是一种持久化方式它记录了 Redis 服务器接收到的写操作命令在服务器重启时可以通过重新执行 AOF 文件中的命令来恢复数据。 AOF 持久化的特点和工作原理 日志追加Redis 将接收到的写命令以追加的方式记录到 AOF 文件中新的命令会不断追加到文件末尾。 可读性AOF 文件是一个文本文件易于读取和理解。它记录了 Redis 服务器接收到的每个写命令。 数据恢复当 Redis 服务器重新启动时它会重新执行 AOF 文件中的命令从而恢复数据到重启前的状态。 同步方式Redis 提供了不同的 AOF 同步策略包括 always、everysec 和 no。always 表示每次写操作都会同步到 AOF 文件everysec 表示每秒同步一次而 no 表示不主动同步由操作系统来处理。 重写机制Redis 提供了 AOF 重写机制可以对 AOF 文件进行重写去除冗余的命令从而减小文件大小。AOF 重写是在后台进行的不会阻塞服务器的正常运行。 复制和传输AOF 文件可以被复制到其他 Redis 服务器上用于数据备份和迁移。
AOF 日志是在主进程中执行 重写 AOF 日志是在子进程中进行。
重写过程中主进程依然可以正常处理命令那问题来了重写 AOF 日志过程中如果主进程修改了已经存在 key-value那么会发生写时复制此时这个 key-value 数据在子进程的内存数据就跟主进程的内存数据不一致了这时要怎么办呢
为了解决这种数据不一致问题Redis 设置了一个 AOF 重写缓冲区这个缓冲区在创建 bgrewriteaof 子进程之后开始使用。
在重写 AOF 期间当 Redis 执行完一个写命令之后它会同时将这个写命令写入到 「AOF 缓冲区」和 「AOF 重写缓冲区」。 RDB持久化的特点和工作原理
因为 AOF 日志记录的是操作命令不是实际的数据所以用 AOF 方法做故障恢复时需要全量把日志都执行一遍一旦 AOF 日志非常多势必会造成 Redis 的恢复操作缓慢。 为了解决这个问题Redis 增加了 RDB 快照,Redis 的快照是全量快照也就是说每次执行快照都是把内存中的「所有数据」都记录到磁盘中。所以执行快照是一个比较重的操作如果频率太频繁可能会对 Redis 性能产生影响。如果频率太低服务器故障时丢失的数据会更多。 RDB生成方式
1在「主线程」里执行执行 save命令由于和执行操作命令在同一个线程所以如果写入 RDB 文件的时间太长会阻塞主线程
2会创建一个子进程来生成 RDB 文件执行 bgsave 命令会创建一个子进程来生成 RDB 文件这样可以避免主线程的阻塞 执行机制配置文件里配置隔多少时间修改多少次会触发
RDB 在执行快照的时候数据能修改吗 可以的执行 bgsave 过程中Redis 依然可以继续处理操作命令的也就是数据是能被修改的关键的技术就在于写时复制技术Copy-On-Write, COW。
执行 bgsave 命令的时候会通过 fork() 创建子进程此时子进程和父进程是共享同一片内存数据的因为创建子进程的时候会复制父进程的页表但是页表指向的物理内存还是一个此时如果主线程执行读操作则主线程和 bgsave 子进程互相不影响。如果主线程执行写操作则被修改的数据会复制一份副本然后 bgsave 子进程会把该副本数据写入 RDB 文件在这个过程中主线程仍然可以直接修改原来的数据。 混合持久化
优点混合持久化结合了 RDB 和 AOF 持久化的优点开头为 RDB 的格式使得 Redis 可以更快的启动同时结合 AOF 的优点有减低了大量数据丢失的风险。缺点AOF 文件中添加了 RDB 格式的内容使得 AOF 文件的可读性变得很差 兼容性差如果开启混合持久化那么此混合持久化 AOF 文件就不能用在 Redis 4.0 之前版本了。
4 redis的内存淘汰策略
内存淘汰策略是解决内存过大的问题当 Redis 的运行内存超过最大运行内存时就会触发内存淘汰策略 5 redis的过期删除策略
Redis 使用的过期删除策略是「惰性删除定期删除」删除的对象是已过期的 key。
惰性删除不主动删除被访问的时候检查是否到期到期了就删除会使得一直不被访问的数据一直存在占用内存
定期删除
Redis会将设置了过期时间的key放在一个独立的字典中定时遍历这个字典来删除过期的key遍历策略如下
1每秒进行10次过期扫描每次从过期字典中随机选出20个key 2删除20个key中已经过期的key 3如果过期key的比例超过1/4则进行步骤一 4每次扫描时间的上限默认不超过25ms避免线程卡死
因为Redis中过期的key是由主线程删除的为了不阻塞用户的请求所以删除过期key的时候是少量多次
6 redis的雪崩、击穿和穿透 雪崩:是指在某一时刻缓存中的存储的数据同时大量地失效而且这些数据都是经常被访问的数据比如热点文章热门商品等这样就会导致大量的请求都会落到数据库上造成数据库的压力瞬间增大从而导致服务器宕机形成一种“雪崩”效应。
击穿 是指某个热点数据在缓存中失效了而且这个数据也是经常被访问的数据这样就会导致大量的请求都会落到数据库上造成数据库的压力瞬间增大从而导致服务器宕机。
解决缓存击穿的方法有很多其中一种比较常见的方法是采用“互斥锁”和“逻辑过期时间”两种手段来解决。
互斥锁 是指在查询数据库时如果发现缓存中的数据已经失效那么就先获取一个互斥锁然后再去查询数据库这样一来只有一个线程去访问数据库将查询到的数据同步到缓存当中其他线程就直接从缓存中获取了就可以避免大量的请求都会落到数据库上。
缓存穿透 是指恶意的请求会故意查询数据库不存在的数据而这些数据在Redis缓存中也不存在这样就会导致大量的请求都会落到数据库上造成数据库的压力瞬间增大从而导致服务器宕机。
解决缓存穿透的方法有很多其中一种比较常见的方法是采用“缓存空对象”和“BloomFilter布隆过滤器”两种手段来解决。
缓存空对象 是指在查询数据库时如果发现查询的数据不存在那么就将这个空对象也缓存起来这样一来下次再查询这个不存在的数据时就可以直接在缓存中获取到空对象而不需要去数据库中查询。
BloomFilter布隆过滤器
逻辑过期时间 是指在查询数据库时如果发现缓存中的数据已经失效那么就先将数据库中的数据缓存起来但是不将这个数据的过期时间设置为实际的过期时间而是将过期时间设置为一个较短的时间这样一来就可以避免缓存中的数据一直都是“冷”数据。
7 redis的高可用
实现 高可用 的技术主要包括 持久化、复制、哨兵 和 集群持久化上面已经提到主要是RDB和AOF复制哨兵和集群是redis部署的模式来提高服务的高可用。
redis常见部署方式
主从复制
提高读性能实现数据冗余。一旦 主节点宕机从节点 晋升成 主节点同时需要修改 应用方 的 主节点地址还需要命令所有 从节点 去 复制 新的主节点整个过程需要 人工干预。 哨兵机制
1监控PING 2通知 (订阅/发布) 3自动故障转移选主/半数以上
主观下线
客观下线 集群的数据分片
Redis Cluster 方案采用哈希槽Hash Slot来处理数据和节点之间的映射关系。在 Redis Cluster 方案中一个切片集群共有 16384 个哈希槽这些哈希槽类似于数据分区每个键值对都会根据它的 key被映射到一个哈希槽中具体执行过程分为两大步
这些哈希槽怎么被映射到具体的 Redis 节点上的呢有两种方案
平均分配 在使用 cluster create 命令创建 Redis 集群时Redis 会自动把所有哈希槽平均分布到集群节点上。比如集群中有 9 个节点则每个节点上槽的个数为 16384/9 个。手动分配 可以使用 cluster meet 命令手动建立节点间的连接组成集群再使用 cluster addslots 命令指定每个节点上的哈希槽个数。 相关知识拓扑图