求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code
会员   
订购 | 案例 | 建模扩展语言 | 模型框架 | 学习资源 | 培训&咨询 | 解决方案 | 用户组 | 客户专区 | 联系我们
  379 次浏览  6 次
模型库 > 模型库
模型库简介  

在线模型库
WebEA
学习资料
模型框架
产品购买
MaaS服务

Redis的架构模型(UML +EA建模)

作者: 俎涛 (火龙果科技)

Redis的架构模型(UML +EA建模)
作者: 俎涛 (火龙果科技)
 

1.前言

   Redis(Remote Dictionary Server,远程字典服务器)的目的是提供一个可以快速存取的内存key-value数据库。Redis读写速度非常快,每秒可以处理超过10万次读写操作。Redis被广泛应用于缓存,另外,Redis也经常用来做分布式锁。Redis还支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。Redis的代码开源,采用ANSI C语言编写,并提供多种语言的API。

   为了让读者更好的理解Redis的设计,我们基于Redis的源码、Redis的用户指南、说明文档,采用建模语言UML和建模工具EA对redis进行了模型逆向,并发布到ModelCenter,内容如下:

欢迎访问:Redis架构模型,下面对其中的内容进行简要介绍。

2. 用例模型

为了有效地应用Redis,需要了解Redis有什么功能,以及这些功能如何使用,这就可以采用UML/Sys ML的用例图,如下是Redis的用例模型:

图. Redis 的用例模型(Sys ML/UML 用例图)

3.软件组件模型

Redis的软件组件模型描述了Redis的组件构成以及组件之间的关系,如下是采用UML组件图建模的Redis的软件组件模型。

图. Reds 的整体软件组件模型(UML组件图))
  • Redis-cli : Redis 的命令行客户端组件,提供客户端访问接口。
  • Redis-Server : redis 的服务端服务组件,提供 redis 的内存数据服务。
  • AOF : Append Only File ,就是基于日志的数据持久化机制,将每一个收到的写命令都通过 write 函数追加到文件中,
  • RDB : Redis DataBase ,就是基于数据快照的持久化机制,在指定的时间间隔内将内存中的数据集快照写入磁盘。这种方式是就是将内存中数据以快照的方式写入到二进制文件中 , 默认的文件名为 dump.rdb 。
  • hiredis : redis 的 C 语言版本客户端代码
  • jemalloc :代替 glibc 库的内存分配器
  • linenoise :代替 readline ,命令行解析工具
  • lua :支持次 hilua 脚本代码的解释器。
  • redis-benchmark : redis 自带的压力测试工具,可以模拟 多个客户端同时发出 多个请求。
  • tests : 这个目录里面是用于功能模块测试和单元测试的代码。这些子目录中的测试代码使用了 Tcl 语言(通用的脚本语言)进行编写,主要目的就是方便进行测试。 Redis 实现的测试代码可以分成四部分:
    • unit :单元测试,
    • Cluster :集群测试。
    • Sentinel :哨兵功能测试
    • Integration :集成测试
    • 提供测试支持的: modules , helpers , support , asserts 。
  • Utils: 这个目录里面是在 Redis 开发过程中的一些辅助性功能,包括用于创建 Redis Cluster 的脚本、用于测试 LRU 算法效果的程序,以及可视化 rehash 过程的程序。

4. 代码模型

Redis的源码主要包括如下几部分:

代码目录 说明
deps 包含了 Redis 依赖的第三方代码库。
src 这个目录里面包含了 Redis 所有功能模块的代码文件,还提供了 module 示例代码。
tests 提供了各种测试的代码和脚本,包括:单元测试、集成测试、哨兵测试、集群测试。
utils 包括一些在 Redis 开发过程中的辅助性功能,包括用于创建 Redis Cluster 的脚本、用于测试 LRU 算法效果的程序,以及可视化 rehash 过程的程序。

deps 目录中的代码

包含了 Redis 依赖的第三方代码库,具体内容如下:

  • hiredis : Redis 的 C 语言版本客户端代码 hiredis
  • jemalloc : 内存分配器代码(用来替换 glibc 库的内存分配器)
  • linenoise : readline 功能的替代代码 linenoise ,
  • lua : lua 脚本代码。
  • hdr_histogram ,用于生成每个命令的延迟跟踪直方图。

这部分代码的一个显著特点,就是它们可以独立于 Redis src 目录下的功能源码进行编译,也就是说,它们可以独立于 Redis 存在和发展。

Redis 的 src 目录

这个目录里面包含了 Redis 所有功能模块的代码文件,其中还有一个 modules 子目录,其中包含了一个实现 Redis module 的示例代码。下面对 src 中的主要内容做模型逆向和介绍。

数据类型

Redis 提供了丰富的键值对类型,其中包括了 String 、 List 、 Hash 、 Set 、 Sorted Set 、位图、 HyperLogLog 、 Geo 等

核心数据结构如下:

  • String : sds.c ,底层数据结构 SDS 。涉及代码 t_string.c 、 sds.c
  • List :双向链表( adlist.c )、 ziplist 、 quicklist 作为 List 的底层实现。涉及代码 t_list.c 、 ziplist.c 、 adlist.c 、 quicklist.c
  • Hash :数据结构底层实现为一个字典 ( dict ) ,当数据量比较小,或者单个元素比较小时,底层用 ziplist 存储( ziplist.c )。涉及代码 t_hash.c 、 ziplist.c 、 dict.c
  • Set :数据结构底层实现为一个 value 为 null 的字典 (dict) ,当数据可以用整型表示时, Set 集合将被编码为 intset 数据结构 (intset.c) 。涉及代码 t_set.c 、 intset.c
  • Sorted Set :实现代码在 t_zset.c ,数据结构底层实现为 字典 (dict) + 跳表 (skiplist) , 当数据比较少时,用 ziplist 编码结构存储。涉及代码 t_zset.c 、 ziplist.c 、 dict.c
  • 位图: bitops.c
  • HyperLogLog : HyperLogLog.c
  • Geo : geo.c 、 geohash.c 、 geohash_helper.c
  • Stream :时序数据, t_stream.c 、 rax.c 、 listpack.c

如下是 String 的代码逆向的类图:

服务器实例

  • server.c : Redis 在运行时是一个网络服务器实例, server.c 包含服务器实例的初始化和主体控制流程, Redis main 入口函数也是在 server.c 中
  • ae.c , ae_epoll.c , ae_evport.c , ae_kqueue.c , ae_select.c :提供事件驱动网络框架。 ae_select.c 和 ae_epoll.c 文件,分别使用了 select 和 epoll 这两种机制,实现 IO 多路复用; ae_evport.c 对应 Solaris 上的 IO 复用函数 evport ; ae_kqueue.c 对应 macOS 或 FreeBSD 上的 IO 复用函数 kqueue ; ae.c 实现了 Reactor 模型
  • anet.c :对 TCP 网络通信的 Socket 连接、设置等操作进行了封装,在 Redis Cluster 创建和主从复制的过程中,会被调用并用于建立 TCP 连接
  • networking.c :客户端的创建、消息回复

代码逆向类如下:

redis 数据库操作接口

redis 提供了数据库操作接口,实现了对键值对的新增、查询、修改和删除等操作接口,对应的代码主要在: db.c 。如下是逆向代码获得类图:

内存管理:

Redis 的内存管理主要功能有内存分配、内存回收和数据替换:

  • 内存分配: zmalloc.c , Redis 支持使用不同的内存分配器,包括 glibc 库提供的默认分配器 tcmalloc 、第三方库提供的 jemalloc
  • 内存回收: expire.c ,支持设置过期 key ,并针对过期 key 可以使用不同删除策略; lazyfree.c ,实现了异步删除 key ,回收内存
  • 数据替换: evict.c ,如果内存满了,可以根据 LRU 、 LFU 等算法清除不需要的数据

核心的代码对应类图如下:

数据持久化、主从赋值和集群服务:

Redis 可以对数据做持久化保存,在此基础上还实现了主从复制机制,集群服务功能。

  • 数据持久化实现:内存快照 RDB 和 AOF 日志,分别实现在了 rdb.h/rdb.c 和 aof.c 中。以及对这两类文件的检查功能 ( 宕机导致未能完整保持 ) ,对应的代码文件分别是 redis-check-rdb.c 和 redis-check-aof.c
  • 主从复制功能实现: replication.c
  • 集群服务是通过 Redis Cluster 来实现的,代码为 cluster.c

对应代码逆向的类图如下:

Redis 还实现了一些用于支持系统运维的辅助功能。例如 操作延迟监控和慢命令的日志

  • latency.c :实现了操作延迟监控的功能,便于运维人员查看分析不同操作的延迟产生来源
  • slowlog.c :实现了慢命令的记录功能,便于运维人员查找运行过慢的操作命令

对应代码逆向的类图如下:

5.部署模型

Redis 的应用的典型不模型如下所示:

在客户端部署 redis-cli 组件,通过 redis-cli 组件访问 redis master 服务器,在 redismaster 服务节点上 运行有 redis-server 提供相应的数据服务,对于持久化的数据,提供 2 种存储机制: RDB 个 AOF ,为了提高数据处理的性能支持,提供 redis-slave 节点服务。

6.运行过程模型

客户端请求到服务处理的过程

Redis 的客户端请求到服务端处理的过程视图如下:

为了提供响应的灵活性, Redis 的请求处理采用基于事件的异步处理模型,客户端的请求会产生对应的事件,事件会排入 IO 多路复用程序处理,不同的事件会触发对应的事件处理器处理。

Server 的主任务交互过程

Server.main() 是 redis 的主任务启动过程,采用 CodeEngineer 对 main 函数进行逆向顺序图如下所示:

如果希望了解Redis 架构模型详细信息,请浏览 《 模型库:Redis架构模型 》

如果希望进一步学习 SysML 或 UML 有关的建模课程和工具,欢迎访问:

如果您希望了解更多信息:

  • 欢迎访问建模者频道 http://modeler.org.cn/
  • 也欢迎直接联系我们 zhgx@uml.net.cn ,010-62670969
379 次浏览  6 次