redis

redis单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。

一、redis为什么这么快

使用内存、单线程、IO多路复用、内部数据结构

1.redis是单线程,没有使用现代多核CPU的多线程?

线程上下文切换、资源互斥访问需要加锁。代价大,复杂

2.IO多路复用模型:向服务端请求数据时,每个请求都有一个标记,有一个东西监视着标记,一旦可以响应数据,就去做操作。(类似电影院大厅的屏幕,有电影放完了就去打扫并换下一个影片)

IO阻塞模型:向服务端请求数据时,阻塞工作线程,等待响应

IO非阻塞模型:向服务端请求数据时,使用另一个线程去轮询问服务器有没有准备好数据,如果没有准备好,工作线程先去干别的工作。轮询线程一直问直到准备好了,跳出循环。

redis使用的io模型是多路复用模型

3.数据结构底层

二、持久化机制

Redis是一个基于内存的数据库,它的数据是存放在内存中,内存有个问题就是关闭服务或者断电会丢失。Redis的数据也支持写到硬盘中,这个过程就叫做持久化。

1.RDB

Redis提供如下2中持久化方式 RDB(Redis DataBase) :在指定的时间间隔内,定时的将 redis 存储的数据生成Snapshot快照并存储到磁盘等介质上;

触发rdb的时机:客户端下运行save或者bgsave

save命令会让主进程去执行持久化,这样就不能响应查询了,而且由于是向磁盘写,耗时长,一般在停机的时候使用。

bgsave命令fork一个子进程去执行持久化,主进程不受影响。

配置rdb,redis.conf配置文件中:

save 900 1 #表示在900秒内修改一次redis就执行一次bgsave命令

save " " #禁用rdb

持久化文件要保存的位置

持久化文件的名字

是否压缩,建议不开启,压缩会消耗cpu,磁盘不值钱。

问题:异步持久化,如果当redis子线程持久化的数据正常被父线程再修改的时候怎么办?

rdb内部采用COPY-ON-WRITE技术,用副本来替换原来内存中的数据

2.AOF

AOF(Append Of File) :将 redis 执行过的所有写指令记录下来,在下次 redis 重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。

恢复数据时,再次执行一遍日志文件。

刷盘策略  

always每次写入都先保存一下命令日志。

everysec一秒做一次日志报存

no同步硬盘由操作系统完成,通常是30秒


注意:aof文件可能记录对同一个key的多次操作,没有意义,而且很长 

解决??aof重写

触发时机:直接调用 bgrewriteaof 命令。

配置文件中:

auto-aof-rewrite-min-size 表示运行AOF重写时文件最小体积,默认为64MB

auto-aof-rewrite-percentage:代表当前AOF文件空间(aof_current_size)和上一次重写后AOF文件空间(aof_base_size)的比值

3.对比

AOF文件体积比较大

RDB数据不完整 60秒做一次持久化:可能数据丢失 ;AOF最多1秒做一次持久化。

AOF恢复慢,RDB恢复快。AOF需要重新执行那些命令。

三、问题

1.缓存雪崩

缓存中大量key同时失效,导致流量请求到db中,造成db负载压力过大挂掉,这种情况叫做缓存雪崩。

怎么避免? 分散key的过期时间。

2.缓存穿透

大量请求同时访问一个不存在的key,导致流量走到db。

怎么避免? 添加一个默认值null,可以使用布隆过滤器判断是不是存在

3.缓存击穿

大量请求同时访问一个过期的key,导致流量走到db。

怎么避免? 加分布式锁避免

四、架构

Redis 支持三种集群模式,分别为主从模式、哨兵模式和Cluster模式。

主从模式

在Redis的主从复制架构中,系统通过定义主库(master)和从库(slave)的角色,实现数据的高效同步和备份。

master的读写能力。当在master上执行任何改变数据的操作时,这些更改会自动且实时地同步到所有slave。

单向数据流:数据同步流是单向的,意味着数据只从master流向slave,确保了数据同步的一致性和可靠性。

slave的只读特性:slave通常被配置为只读模式,它们接收并存储从master传来的数据。这样设计主要是为了分散读取压力,从而提高系统的整体读取性能。

主slave的对应关系:一个master可以对应多个slave,形成一对多的关系。这种结构利于数据的冗余备份和读取负载的分散。相反,一个slave只能对应一个master,以保持数据同步的一致性。 slave的容错性:如果某个slave出现故障,它对系统其他部分的影响是最小的。即便在slave宕机的情况下,其它slave仍能继续提供读服务,master也能保持正常的读写操作。当故障的slave恢复后,它会自动从master同步缺失的数据。

master故障的影响:master的故障会导致Redis暂时无法处理新的写请求,但已连接的slave可以继续提供读服务。一旦master恢复,Redis会重新提供完整的读写服务。

master故障的应对机制:在当前的master发生故障时,系统不会自动在slave中选择一个新的master。这需要通过额外的高可用性解决方案来实现,例如使用Redis Sentinel或Redis Cluster来管理master的选举和故障转移。


全量同步(salve第一次连接master、salve宕机太久超过repl_backlog)

第一阶段:salve和master建立连接携带id,判断是不是第一次连接,如果是就返回版本信息。

第二阶段:执行bgsave,folk出一个进程,报存数据并发送给salve。在folk出的进程执行期间,主进程可能还会有数据存入。将存入的命令记录在一个文件中

第三阶段:发送缓存命令,salve执行缓存命令。

怎么判断是第一次连接?

salve会继承master的repID,如果id不一致说明是第一次建立连接。

增量同步 (salve断开又恢复,在repl_backlog找到offset偏移量位置的数据)

repl_backlog是一个环形数组,salve如果宕机太久就不能恢复了,就得去做全量同步。

哨兵机制

master挂了?哨兵监控集群,mater挂了选一个salve做master。原mater活了之后当salve。

1.作用

监控故障、故障转移、通知客户端那个是主节点那个是从节点

2.怎么检测节点没有挂?

心跳机制,每隔一段时间,ping一下,如果有响应就ok。如果超过半数的哨兵认为这个节点挂了,就客观认为下线了。

3.怎么选举新的主节点?

首先判断salve和redis断开的时间长度,如果超过指定值就没有选举权

判断salve配置文件中的salve-priority结点,优先级为0没有选举权,默认是1

判断salve运行id,越小优先级越高。

4.怎么进行故障转移

sentinel向选举上的节点发送slave no one 让它变成主节点

sentinel给其他的节点发送 slaveof ip 端口 ,这些节点成为新master的从节点

将故障结点强制标记为slave修改配置文件

分片集群

redis-cli -c -p 端口 集群机制启动redis客户端

1.哈希槽的概念

多个master,实现高并发写,每个master有几个slave,实现高并发的写。每个master被分配一段哈希槽,保存和获取redis值时,根据有效key(如果有{}根据{}里面的计算)计算hash值,根据hash值判断这个key存到那个master中。

发生故障时自动切换主节点。

2.一致性哈希算法

存数据:根据给节点分配的hash槽,将节点映射到哈希环上的某个位置。当存一个key时,计算该key的有效哈希。根据hash值找到哈希环的位置。顺时针找下一个节点就是这个数据要存入的节点。

新增节点:新增一个节点,计算哈希值,比如该节点在3和4之间。根据节点和值存储的映射关系,只需要修改4结点分配的哈希槽就行。无需修改全部结点的哈希槽,性能更好。

  • 16
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值