本篇锤子将和大家一起学习redis的基础知识,文章中只会学一些重要的基础信息,对于redis的详细了解可以浏览redis的官网

Redis是一个开源基于内存的数据结构存储。可以用作数据库、缓存和消息代理。它支持多种数据结构,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)、位图(Bitmaps)、HyperLogLog、带有半径查询的地理空间索引(geospatial indexes with radius queries)、流(Streams)。Redis内置了副本机制,支持Lua脚本,采用LRU算法作为淘汰算法、支持事务和不同级别数据持久化到磁盘策略,并提供了哨兵机制(Sentinel )和redis集群自动分区机制两种方式来保证服务高可用性

NoSQL(Not-Only SQL)泛指非关系性数据库。与之相对应的就是关系型数据库,随着互联网的发展,网络用户群体越来越大,数据量的激增以及复杂多变的应用场景,传统的关系型数据库已经暴露出了很多难以克服的问题,比如数据库的高并发读写,海量数据的高效率存储和访问,多变的数据结构等,这些问题的解决方案仅仅使用传统关系型数据库已经无法满足了,于是作为关系型数据库的补充,非关系型数据就扮演了另一个角色来解决这些关系型数据库无法解决的问题。

从图中我们可以简单了解到,非关系型数据库擅长于高并发场景下的数据读写,适合存储大数据量的数据,同时也易于拓展,但是对数据一致性要求高的数据存储时非关系型数据库是不适用的,像银行的交易系统的账户信息,电商平台的支付订单信息等大部分都还是采用关系型数据库来存储。所以在现有的大部分应用中,都是采用关系型数据库和非关系型数据库结合的一种组合来满足复杂的业务场景。

redis作为非关系型数据库的一种,属于键值型数据存储,因为redis支持高并发的快速数据访问,所以在生产中多用来作为缓存使用,以提高数据读取效率,提高整个应用程序的并发性能。redis主要有以下特点

支持持久化操作,支持用AOF和RDB两种数据持久化策略把数据持久化到磁盘

支持两种高可用方式:哨兵机制(master-slave模式)和redis cluster高可用

说到redis的线程模型,大部分朋友可能都听说过redis是单线程模型,但其实这个说法是不准确的,整个redis服务当然不可能是一个单线程的,仅仅是因为redis的文件事件分派器是单线程消费事件队列的,所以很多人会称Redis是单线程模型。其实在redis服务中还有ServerSocket监听、IO多路复用程序等,这些模块都至少需要一个线程来工作,所以在学习的时候,我是不会直接称呼redis是单线程模型,这样会让不是很了解redis的朋友产生误会,不能理解一个线程怎么实现的整个服务,这里仅做一个说明,避免读者朋友误会,接下来是正文

整个处理模型由4部分组成:多个套接字、IO多路复用器、文件事件分派器、文件事件处理器

首先,在redis服务启动后,服务中会有一个ServerSocket来负责监听服务端口

有一个客户端连接到Redis的监听端口,客户端与服务端建立通信在服务端会生成一个Socket,这个Socket是与客户端进行数据交换的通道

通信建立后,端口监听程序将Socket进行业务封装交给IO多路复用程序,

IO多路复用程序根据自己的逻辑(不同的多路复用实现,具体操作不一样)会对每个客户端通信的消息进行监听,根据客户端发送过来不同的请求消息,将消息与通信封装成不同的事件,再将事件放入事件队列。

文件事件分派器消费事件队列,从队列中出队一个事件,则根据事件类型不同,将事件交由不同的事件处理器处理(这个过程是单线程的),处理完一个事件后,再去队列出队下一个,重复下去….

当客户端断开与服务端的通信时,IO多路复用器检测到与客户端的通信已断开,也就将该客户端信息移除,就不再监听该客户端信息了

以上是一个简略的描述过程,对非阻塞IO有一定了解的朋友或许会看的更明白一些,其核心就是IO多路复用与事件队列的单线程消费。

常见的IO多路复用器有select、epoll、kqueue等,Redis的IO多路复用程序是通过包装这些常见的IO多路复用器来实现的,下面简单说一下多路复用IO

多路复用IO有时也被称为事件驱动IO,而IO多路复用器就是多路复用IO的实现,其代表实现有select、epoll、kqueue(上面也提到过),使用这些IO多路复用器的好处在于单个process就可以同时处理多个网络连接的IO,这样合理的使用多个IO多路复用器就可以较小资源实现高并发网络编程。通俗的理解IO多路复用器就是利用单个线程或者少量线程,管理大量的Socket通信,从而减少了因为IO等待(阻塞IO下,当对方操作数据时,当前线程就处于阻塞等待状态)带来的资源浪费。

在这三个代表性的IO多路复用器中,select是采用轮询机制来检测多个Socket中是否有数据交互产生,而epoll和kqueue则是使用的callback的方式。当Socket比较多的时候,select要通过遍历每个Socket来完成调度,不论当前活跃的Socket有多少,都会全部遍历一遍,这种设计会导致CPU时间的浪费,所以在后面的epoll和kqueue多路复用器中就换了另外一种方式,它们会给Socket注册回调函数,当Socket活跃的时候,会自动完成数据处理相关操作,这样就避免了轮询代理的CPU时间浪费

Redis有两种持久化策略RDB(Redis DataBase)和AOF(Append Only File),这两只持久化策略可以选择单独使用,也可以结合使用,当然也可以不使用。如果在redis中不使用持久化,则redis的中缓存的数据的生命时长最长就是redis运行的时间,即redis停止后缓存的数据就全部丢失了

RDB持久化是以指定的时间间隔执行数据集的时间点快照,通俗讲就是每隔一段时间,redis会把把内存中的数据写入磁盘的临时文件,作为快照,等需要恢复的时候再把快照文件读进内存

AOF持久化是记录服务器接收到的每个写入操作,这些操作将在服务器启动时再次加载,重建原始数据集,命令的记录以追加的方式,使用的格式与Redis协议本身的格式相同,Redis能够在日志太大的时候重写这些记录文件

Hash是一个键对应多个属性和value,大小无限制(视内存大小而定),包含操作如下:

List类型即列表类型,redis中的list实现是基于链表,包含操作如下:

Zset类型,有序集合类型,使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注