浅谈Redis架构

    REDIS是一个开源的、先进的键值存储系统。它一般能够被用做数据结构服务器,由于它的键能够包含字符串(string)、哈希值(hash)、列表(list)、集合(set)以及有序集合(sortedset)。并且Redis使用的是内存数据集合。根据你自身的使用状况,你能够定时将这些内存中的数据保存至磁盘中,或者将每一个命令都添加至日志中。你能够经过redis的项目主页了解它的更多功能。Redis最初的做者是Salvatore Sanfilippo,而且VMWare从2010年5月份开始资助该项目。目前,Redis已经被用在不少重要产品和服务之中,如:github、stackoverflow、Disqus、Guardian以及你访问的不少网页。git

    Redis是使用ANSI C标准编写的,能够在不依赖其余程序的状况下运行在大部分POSIX系统中,如:Linux、BSD以及Solaris。而从我有限的角度来看,redis的代码很是简单并且易于阅读;并且它的代码库不是很大(2.2版本大约为20k),同时它的内部结构在网站上都被很好的记录在文档中。在继续这篇文章以前我邀请你首先看下由做者本人最近写的他本身的发展哲学的声明。下面我引用一段其中我很是赞扬的话:github

咱们乐于优化。咱们坚信写代码是一项很是艰难的工做,而值得坚持的惟一方法就是享受写代码;当你再也不享受写代码的过程时,那么最好的作法是停一停。为了防止这种状况的发生,咱们会尽可能避免有下降redis开发乐趣的事情发生。redis

这篇文章将尝试这去总结我对帮助文档和源码的一些理解。Redis是一个Client/Server模式的系统,典型的调度图以下:服务器

Redis服务端是一个进程,该进程经过TCP协议和客户端进行会话。网络

虽然redis-cli是官方提供的客户端,可是第三方项目实现了其余语言的客户端,如:C++, C#, Clojure, Common Lisp, Erlang, Haskell, Java, JavaScript,Lua, Objective-C, Perl, PHP, Python, R, Ruby, Scala, Go以及Tcl。因为在官网上都有关于协议的说明文档,所以你也能够根据官网上的协议文档实现本身的协议。除此以外,redis的主从复制功能可能也是大多数人所须要的。数据结构

我设计了一个关于源代码的模块化视图以下:app

  1. redis 是服务端守护进程。它是由一个单一的redis.c文件组成,大约为6k。socket

  2. networking 网络功能的实现代码。尤为是基于事件的逻辑,能够经过epoll、kqueue以及select等系统调用实现。ide

  3. datastructure 标识服务器所使用的重要数据结构。相当重要的是例如sds.c表示redis编写的全部代码所使用的字符串模块化

  4. redis-cli 表示客户端命令行


Redis
是如何工做的

从其根原本看,redis是一个单线程的服务器。这意味着经过一个单独的线程使用事件模式如epoll、kqueue、select来读取传入的链接。当一个特定的时间生成一个文件描述符后,这个线程处理这些文件描述符并会写响应结果。这个UML序列图显示了一个命令被客户端接受后是如何被redis在内部处理的:

Redis使用自定义的时间库,该库抽象了低层面的socket管理。核心对象是eventLoop,它包含了已经被scoket I/O释放的事件。同时,aeApiPoll(eventLoop)检查全部的socket描述符来肯定是否还有网络处于激活状态。而在aeProcessEvents方法中,全部被释放的事件都会被检查并调用适当的处理程序。对于协议中的全部命令,redis会拦截全部命令并经过一个命令表单来查找合适的操做来执行。命令表单被定义在redis.c中,具体以下:

这个结构的第二个参数是要调用的方法的名称。例如,saveCommand方法实现以下:

addReply方法被用来推送相应结果至客户端。

以上内容快速回顾:

redis使用一个单独的线程来管理同步全部网络链接。redis实现了一个轻量级的事件库来抽线unix系统的一些系统调用(如epoll, select, kqueue)。在redis的邮件列表中,在推进使用新的事件库仍是依赖已有的开源库这个问题上有一个有趣的争论。

请求经过命令来完成。redis使用了一个命令列表,在从socket中读取到相关命令后经过该列表来找到并调用执行须要的操做。

基础数据结构是SDS字符串。

数据存储管理

Redis实例包括表明服务器状态的全局变量。例如在redis.c中的定义以下:

其中,变量redisDB的定义以下:

其中dict是redis模型中使用的内存数据结构。它在dict.c中定义,当你须要实现一个hashtable时,它可提供一系列所须要的方法,例如:

若是咱们来看一个最重要的命令-set command-命令,咱们会看到如下代码:

Redis启动原理

启动过程很是简单。如前所说,redis实例是由一组全局变量组成,并经过方法来访问这些变量。redis服务器main方法以下:

在读取完配置文件以后,initServer方法会被调用。该方法会初始化redis的全部全局变量。特别是它建立一组连接列表用于管理:

同时,它还建立最重要的数据结构:

它还初始化事件库来建立eventloop以及服务端socket。最终,进入主循环来管理客户端I/O:

aeProcessEvents就是在上一小节中分析的方法。

虚拟内存

Redis也支持虚拟内存:这意味着,当你的数据集不适合放在RAM中,redis能够支持回写在磁盘上。

Redis语言及工具概述

相关文章
相关标签/搜索