1.redis的引入
计算机中读写速度最快的是CPU,其次是运行内存,最后是磁盘;在后端开发中,用的最多的MySql数据库,是基于磁盘的;而redis(Remote Dctionary Server)是基于内存的,两者都是数据库,但是他们的读写方式却不相同,因此在应用的时候可以根据实际需求去使用。
2.redis的数据类型
在实际应用中,redis通常为一些高频率的查询操作的读写数据作为一个缓存,缓存的目的其一是为了降低MySql数据库的负担,其二是为了提高整体的性能;在redis中数据的存储主要是以Key-Value键值对的形式存在,类似于Java中的Map集合;redis主要存储的数据类型包含了String、List、Hash、Set、Zset、HyperLogLog(类似统计活跃用户的情况)、bitmap(二进制,主要应用于一些企业上班打卡的业务)。
3.redis的线程模型
如图所示,redis中有自己的一个基于Reactor模式的网络时间处理器,主要有套接字、I/O多路复用技术、文件事件分派器、事件处理器组成。
3.1 套接字
套接字,个人理解,主要是对请求端的请求进行一层封装,做好执行连接、写去、读取、关闭操作的一些准备后,产生一个文件事件,传递给I/O多路复用程序。
3.2 I/O多路复用
I/O 多路复用技术例子:
- 第一种:安排一个老师,按顺序逐个检查。先检查A,然后是B,之后是C、D。。。这中间如果有一个学生卡住,全班都会被耽误。这种模式就好比,你用循环挨个处理socket,根本不具有并发能力。这种方式只需要一个老师,但是耗时时间会比较长。
- 第二种:安排30个老师,每个老师检查一个学生的作业。 这种类似于为每一个socket创建一个进程或者线程处理连接。这种方式需要30个老师(最消耗资源),但是速度最快。
- 第三种:安排一个老师,站在讲台上,谁解答完谁举手。这时C、D举手,表示他们作业做完了,老师下去依次检查C、D的答案,然后继续回到讲台上等。此时E、A又举手,然后去处理E和A。这种方式可以在最小的资源消耗的情况下,最快的处理完任务。
从上述三个例子中,可以看出每个方法的的执行效率和执行时间的差异,而I/O多路复用就是应用的第三种模式,类似于Linux中的select、poll和epoll(由epoll去监听socket注册的fd,在根据每个socket中的消息到达,调用select、poll,而整个过程中,socket都应采用非阻塞模式,整个过程只在调用select、poll、epoll这些调用的时候才会阻塞,收发客户消息是不会阻塞的,整个进程或者线程就被充分利用起来,这就是事件驱动,也就是reactor模式);
3.3 文件事件分派器
文件事件分派器主要是将由套接字产生的文件事件,根据其时间类型分派给不同的事件处理器。
3.4 事件处理器
整个文件事件的处理流程主要是以下几步: 1.将文件事件和命令请求处理器关联-连接应答处理器 2.读取对应服务器内存中Key-value值,将文件事件和命令回复处理器关联-命令请求处理器 3.对服务器进行操作回复,解除文件事件和命令回复处理器的关联-命令回复处理器
highlight: arduino-light
从redis的线程模型可以看出,redis是一个单进程、单线程的,因此不需要没有像CPU在处理多进程、多线程情况时,需要进行上下文切换、锁等问题,因此redis的读写效率是极快的。
服务端请求数据,在redis端的执行流程示意图: