周期学习计划 Redis(2.1)

 

目录

前言

一、redis是什么?

二、redis他能不能和JVM一样跑满cpu?为什么用单线程的还那么redis快?

三、redis内部究竟是怎么干的?Reactor模式

四、redis的面试题

总结




前言

本文主要起因是最近感觉对架构师职位有了新的认知, 然后开始重新审视每一个技术.整个的博客围绕的更多是为什么来解析所有的问题.

推荐的几个地址:

https://blog.csdn.net/xiaoxiaole0313/article/details/108332577

https://blog.csdn.net/Forlogen/article/details/109298253

https://www.cnblogs.com/gz666666/p/12901507.html

https://mp.weixin.qq.com/s/Lf87PnraSm5UgxUhJ7fq5A

一、redis是什么?

redis是一种基于C语言编写的内存cach. 

Redis服务器时一个事件驱动程序,服务器主要处理如下的两类事件:

文件事件(file event):服务器和客户端、主服务器和从服务器之间的Socket连接都会产生相应的文件事件,服务器通过对事件的监听来决定执行的操作
时间事件(time event):Redis服务器内部存在一些定时的操作,由此而产生的为时间事件
这里请先记下来:

二、redis他能不能和JVM一样跑满cpu?为什么用单线程的还那么redis快?

  1. 首先说个结论,redis不能跑满cpu,因为他是单线程,JVM是单进程多线程的.一个程序被执行的最小单位是线程, 每一个线程只能在一个cpu里面执行.所以如果有一台四核服务器, redis最多只能利用一个核心.如果有多个请求进来也只能一条条的执行.而JVM可以分成多个线程,每个请求分配一个线程然后不同的线程可以被不同的cpu执行,
  2. 那为啥他还那么快:
  • 基于内存的存储,就是硬件上不一样.
  • 存储结构比较简单,不会像是mysql一样有join啥的
  • 用了多路复用

这时候我们说啥是多路复用,其实可以说就是NIO(异步非阻塞IO).多路复用解决的是线程等待和线程阻塞问题.听起来有点蒙,首先说最开始操作系统是没有NIO的,只有BIO.如果我们启动redis,假设这时候linux生成一个8888端口的进程,然后我们就可以通过ip:8888链接redis,各种get,set存取参数, 如果这个时候有一万个客户端链接来.然后这1万个人排成队,这时候因为我们只创建了一个线程,redis就只能一次服务一个人,干完了再干下一个.我盗了一幅图.

我们所有的client是不能够直接访问软件程序滴,,,,,,那么问题来了,如果是BIO(阻塞同步IO)的时候,epoll那个位置是干不完就的一直干(write/read).他是按照client列表执行的,假设说client2要存一个电影,redis呢已经接手client2.其他所有的client必须等到client2干完了才能接着干,如果传一半网络抖动吗卡起来......那有没有办法呢, 有的,就是多搞几个线程和进程,就是一帮redis去服务这一群client.但这个时候问题更多了,首先就是你创建了若干个进程,cpu就那么几个,你卡卡的切换一样也浪费时间,而且要是大家都在改一个值你是不是得加锁.这玩意是不是也费时间.

这个时候我们有了NIO,他的想法就是多少个链接其实redis呢也不咋太在意,每一个client的请求如果准备完全了,就会通过epoll主动的通知redis,这个可以了.然后redis开始干,这个干完了就下一个,那如果100个都同时完事了咋办呢,,,,,,,还是从前往后一个个的干.就这么简单.原来BIO呢是redis挨个linux保存的client的列表地址问,有活没有,不管活好没好,有就干活别的不管了,epoll变成了准备好的才干.

实现nio的几种方式:首先说select,poll,epoll都是NIO, BIO的是wirte和read.poll可以理j解为select的升级版,

  • select/poll:将之前传入的fd_set拷贝传出到用户态并返回就绪的文件描述符总数。用户态并不知道是哪些文件描述符处于就绪态,需要遍历来判断。

这里的fd_set说的是每一个client都有一个自己的.fd文件,然后形成的set.用户态说的是用户可以操作的内存区,也就是你得软件区.

  •  epoll的实现早期是一个哈希表,但是后来由于占用空间比较大,改为了红黑树和链表

其中链表中全部为活跃的链接,红黑树中放的是所有事件。两部分各司其职。这样一来,当收到内核的数据时,只需遍历链表中的数据就行了,而注册read事件或者write事件的时候,向红黑树中记录。

 

三、redis内部究竟是怎么干的?Reactor模式

又盗了一副图.首先说这个图和上面的不矛盾, 我们更多关注的是文件分派器开始.这部分往后是redis的内部逻辑细节.

文件分派器是单线程的,所以我们经常说的redis是单线程是这个意思!!,然后每一个事件处理器自己都是单线程的.(比如读写,这个就可以保证一次只读写一个)

SocketIO多路复用器文件事件分派器事件处理器队列组成

  • 连接应答处理器:用于对连接服务器的各个客户端进行应答
  • 命令请求处理器:用于接收客户端传来的命令请求
  • 回复处理器:用于向客户端返回命令的执行结果
  • 复制处理器:用于处理主从之间的复制操作

时间事件处理器
它主要用于处理Redis内部产生的一些时间事件,目前Redis中只存在周期性事件,它指每隔一段时间就会执行的事件。一个时间事件主要由如下三部分信息组成:

id:全局的唯一ID
when:毫秒级别的UNIX时间戳,记录事件到达的时间
timeProc:事件处理器
所有的时间事件都会放入一个无序链表中,每当时间事件执行器运行时,它就会遍历整个链表,查找所有已经到达的时间事件,最后调用相应的事件处理器。e

Reactor模型说的就是一个单线程负责接待准备好的网络请求, 拿到这个请求之后他就交给后面真正的小弟去处理业务了,也就是netty的boss线程和worker线程池.

四、redis的面试题

https://www.cnblogs.com/jasontec/p/9699242.html

https://blog.csdn.net/qq_35190492/article/details/102841400

总结

redis里面也是有的多线程的,这个指的是事件处理器. redis4开始在清除过期数据上采用了多线程.redis6在网络io上也可以开启多线程.主要就是更好的使用cpu,但是读写部分一直都是单线程,所以明白我们说的redis单线程都是redis的事件分配器(reactor模型)和读写事件的处理是单线程的.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值