AOF持久化
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
Redis还提供了AOF持久化功能,与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化通过保存Redis服务器所执行的写命令来记录数据库状态的:
notion image
 
notion image
事件和调度
type
status
date
slug
summary
tags
category
icon
password
Property

 
Redis服务器是一个事件驱动程序,服务器需要处理以下两类时间事件:
  • 文件事件(file event)Redis服务器通过嵌套字与客户端进行连接,文件事件就是服务器对嵌套字操作的抽象。服务器与客户端的通信会产生响应文件事件,服务器通过监听并处理这些事件来完成一系列网络通信操作;
  • 时间事件(time event)Redis服务器中的一些操作需要在给定事件点执行,而时间事件就是服务器对这类定时操作的抽象;
 

文件事件

Redis基于Reactor模式开发了自己的网络事件处理器, 这个处理器被称为文件事件处理器(file event handler):
  • 文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
客户端
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
 
Redis服务器是典型的一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。通过使用由I/O多路复用技术实现的文件事件处理器,Redis服务器使用单线程单进程的方式来处理命令请求,并与多个客户端进行网络通信。
对于每个服务器进行连接的客户端,服务器都为这些客户端建立了相应的redis.h/redisClient结构(客户端状态),这个结构保存了客户端当前的状态信息,以及执行相关功能时需要用到的数据结构。
Redis服务器状态结构的clients属性是一个链表,这个链表保存了所有与服务器连接的客户端的状态结构,对客户端执行批量操作,或者查找某个指定的客户端,都可以通过遍历clients链表来完成:
服务器
type
status
date
slug
summary
tags
category
icon
password
Property

Redis服务器负责与多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。
 

Redis 命令请求的执行过程

一个命令请求从发送到获得回复的过程中, 客户端和服务器需要完成一系列操作。如果使用客户端执行命令:SET KEY VALUE
从客户端发送 SET KEY VALUE 命令到获得回复 OK 期间, 客户端和服务器共需要执行以下操作:
  1. 客户端向服务器发送命令请求 SET KEY VALUE 
  1. 服务器接收并处理客户端发来的命令请求 SET KEY VALUE , 在数据库中进行设置操作, 并产生命令回复 OK 
  1. 服务器将命令回复 OK 发送给客户端
主从复制
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
AOF和RDB,这两个持久化技术保证了即使在服务器重启的情况下也不会丢失数据(或少量损失)。不过,由于数据都是存储在一台服务器上,如果出事就完犊子了:
  • 如果服务器发生了宕机,由于数据恢复是需要点时间,那么这个期间是无法服务新的请求的;
  • 如果这台服务器的硬盘出现了故障,可能数据就都丢失了。
要避免这种单点故障,最好的办法是将数据备份到其他服务器上,让这些服务器也可以对外提供服务,这样即使有一台服务器出现了故障,其他服务器依然可以继续提供服务。
notion image
这些服务器之间的数据如何保持一致性呢?数据的读写操作是否每台服务器都可以处理?
Redis提供了主从复制模式,这个模式可以保证多台服务器的数据一致性,且主从服务器之间采用的是「读写分离」的方式。
哨兵 Sentinel
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点(master)挂了,那么将没有主节点来服务客户端的写操作请求,也没有主节点给从节点(slave)进行数据同步了。
notion image
这时如果要恢复服务的话,需要人工介入,选择一个「从节点」切换为「主节点」,然后让其他从节点指向新的主节点,同时还需要通知上游那些连接Redis主节点的客户端,将其配置中的主节点 IP 地址更新为「新主节点」的 IP 地址。
这样也不太“智能”了,要是有一个节点能监控「主节点」的状态,当发现主节点挂了 ,它自动将一个「从节点」切换为「主节点」的话,那么可以节省很多事情。Redis 在 2.8 版本以后提供的哨兵(Sentinel)机制,它的作用是实现主从节点故障转移
SentinelRedis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
一个Sentinel系统监视服务器的例子
集群
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 

节点

一个Redis集群通常由多个节点(node)组成, 在刚开始的时候, 每个节点都是相互独立的, 它们都处于一个只包含自己的集群当中, 要组建一个真正可工作的集群, 必须将各个独立的节点连接起来, 构成一个包含多个节点的集群。
连接各个节点的工作可以使用CLUSTER MEET命令来完成:
向一个节点node发送 CLUSTER MEET命令, 可以让node节点与ipport 所指定的节点进行握手(handshake), 当握手成功时, node节点就会将 ip 和 port 所指定的节点添加到node节点当前所在的集群中。
 
假设现在有三个独立的节点 127.0.0.1:7000 、 127.0.0.1:7001 、 127.0.0.1:7002 , 首先使用客户端连上节点7000 , 通过发送CLUSTER NODE命令可以看到, 集群目前只包含 7000 自己一个节点:
发布与订阅
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
频道订阅(SUBSCRIBE、PUBLISH)
通过执行SUBSCRIBE命令,客户端可以订阅一个或多个频道,从而成为这些频道的订阅者(subscriber):每当有其他客户端使用PUBLISH命令向被订阅的频道发送消息(message)时,频道的所有订阅者都会收到这条消息。
假设A、B、C三个客户端都执行了命令SUBSCRIBE "news.it",那么这三个客户端就是"news.it"频道的订阅者:
notion image
如果这时某个客户端执行命令PUBLISH "news.it" "hello",向"news.it"频道发送消息"hello",那么"news.it"三个订阅者都将收到这条消息
notion image
模式订阅(PSUBSCRIBE)
事务
type
status
date
slug
summary
tags
category
icon
password
Property

 
Redis通过MULTIEXECWATCH等命令来实现事务(transaction)功能。
事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制。并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。Redis事务不支持回滚机制。
 

事务的实现

一个事务从开始到结束通常会经历以下三个阶段:
  1. 事务开始
  1. 命令入队
Lua
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
notion image
  • 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
  • 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
  • 其它特性
    Lua脚本
    type
    status
    date
    slug
    summary
    tags
    category
    icon
    password
    Property

    Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
     

    创建并修改 Lua 环境

    为了在Redis服务器中执行Lua脚本, Redis在服务器内嵌了一个Lua环境, 并对这个Lua环境进行了一系列修改, 从而确保这个Lua环境可以满足Redis服务器的需要。
    Redis 服务器创建并修改 Lua 环境的整个过程由以下步骤组成:
    1. 创建一个基础的Lua环境, 之后的所有修改都是针对这个环境进行的。
      1. 服务器首先调用LuaC API函数lua_open , 创建一个新的Lua环境。lua_open函数创建的只是一个基本的Lua环境, 为了让这个Lua环境可以满足Redis的操作要求, 接下来服务器将对这个Lua环境进行一系列修改。
    1. 载入多个函数库到Lua环境里面, 让Lua脚本可以使用这些函数库来进行数据操作。
      排序
      type
      status
      date
      slug
      summary
      tags
      category
      icon
      password
      Property

       
      命令格式:SORT <key>
      功能:对键key进行排序
      默认不带任何选项的SORT:
      • 只可以对包含数字键的键key进行排序
      • 默认是升序排序

      SORT <key> 命令的实现