目录
一、Redis 客户端:银行的 “客户档案”
二、客户端关闭:银行的 “终止服务规则”
三、命令处理流程:柜员办理业务的 “标准步骤”
1. 接收申请单(读取命令请求)
2. 确认业务类型(查找命令)
3. 检查业务合法性(预备操作)
4. 办理业务(调用命令实现函数)
5. 收尾工作(执行后续工作)
6. 给客户回执(发送命令回复)
四、serverCron 函数:大堂经理的 “定期巡检”
五、服务器初始化:银行的 “开业准备流程”
六、总结:银行系统与 Redis 的对应逻辑
如果把 Redis 服务器比作一家高效运转的银行,那么客户端就是 “来办理业务的客户”,服务器的命令处理流程就是 “柜员办理业务的标准步骤”,而serverCron函数则是 “大堂经理的定期巡检”。我们用银行的场景来拆解这整套系统:
一、Redis 客户端:银行的 “客户档案”
每个来银行办理业务的客户,银行都会建立一份 “客户档案(redisClient结构体)”,记录客户的关键信息:
| name | 客户昵称(可选,默认无) | 用CLIENT SETNAME给客户贴个标签,方便识别 |
| fd | 客户的 “业务窗口编号” | 普通客户(网络连接)有编号(>0),内部模拟客户(伪客户端)无编号(-1) |
| flags | 客户身份标识(如 “VIP”“理财客户”) | 标记客户端角色(如从服务器、未完成同步的从节点等) |
| querybuf | 客户填写的 “业务申请单缓冲区” | 临时存放客户发送的命令请求(未解析前) |
| argv/argc | 申请单上的 “业务详情” 和 “参数数量” | 解析后的命令参数(如SET msg "hello"拆成argv = [SET, msg, "hello"],argc=3) |
| buf/bufpos | 柜员给客户的 “回执单缓冲区” | 存放命令回复内容,bufpos记录已写长度 |
| authenticated | 客户 “身份验证状态” | 0 = 未实名,1 = 已实名(未验证不能办业务) |
| ctime/lastinteraction | 客户 “开户时间” 和 “最后办理业务时间” | 用于判断客户是否 “休眠”(超时未操作) |
| obuf_soft_limit_reached_time | 客户 “取号排队超时起点” | 记录输出缓冲区首次超过软限制的时间,用于判断是否强制终止服务 |
二、客户端关闭:银行的 “终止服务规则”
银行会在以下情况拒绝为客户服务(关闭客户端):
- 客户离场:客户主动离开(进程退出),窗口自动关闭(fd连接断开)。
- 填错单据:客户提交的申请单格式错误(命令不符合协议),柜员拒收并请客户离开。
- 被管理员清退:大堂经理(CLIENT KILL命令)强制请走某些客户。
- 长时间不办业务:客户取号后超时未操作(超过timeout配置),视为放弃服务。
- 申请单太大:客户的业务申请单超过最大尺寸(输入缓冲区 > 1GB),柜员无法处理。
- 回执单太多拿不下:给客户的回执单超过限制(输出缓冲区超限):
- 硬限制:回执单堆成山(超硬限制),直接请客户离开。
- 软限制:回执单较多(超软限制),但客户还在等,记录开始等待时间;若超时仍未取走,强制请离。
三、命令处理流程:柜员办理业务的 “标准步骤”
客户到窗口递申请单(发送命令),柜员按以下步骤处理,对应 Redis 的命令执行流程:
1. 接收申请单(读取命令请求)
- 客户把填好的申请单(命令)递进窗口,柜员先临时放在 “待处理文件夹(querybuf输入缓冲区)”。
- 柜员解析申请单,提取 “业务类型” 和 “参数”(如 “存款 100 元” 拆成argv = [存款, 100],argc=2),写入客户档案。
2. 确认业务类型(查找命令)
- 柜员查 “业务手册(命令表command table)”,根据申请单的 “业务类型”(argv[0])找到对应的办理流程(redisCommand结构,包含实现函数)。
3. 检查业务合法性(预备操作)
- 柜员先做一系列检查,确保业务能正常办理:
- 业务类型是否存在(cmd是否为NULL)?
- 参数数量是否正确(如 “转账” 需要收款人、金额,缺一不可)?
- 银行现金是否充足(maxmemory限制,内存不足可能拒绝写命令)?
- 银行是否在维护(如数据载入中,只允许少数查询业务)?
- 客户是否在特殊状态(如正在订阅理财产品,只能办相关业务)?
- 若有监控(MONITOR),需同步记录业务详情给监控员。
4. 办理业务(调用命令实现函数)
- 按业务手册的流程办理(执行命令函数),比如 “存款” 就修改客户账户余额(更新 Redis 数据库)。
5. 收尾工作(执行后续工作)
- 若业务耗时太长(慢查询),记录到 “慢业务日志”。
- 更新该业务的 “办理次数” 和 “平均耗时”(calls和milliseconds属性)。
- 把业务详情记到 “银行流水(AOF 缓冲区)”,同步给 “总行备份(从服务器)”。
6. 给客户回执(发送命令回复)
- 柜员把办理结果写在 “回执单(输出缓冲区)”,等客户窗口空闲(套接字可写)时,把回执递给客户。
四、serverCron 函数:大堂经理的 “定期巡检”
银行大堂经理每 100 毫秒巡视一次(serverCron默认频率),处理日常维护,确保银行正常运转:
- 清退 “超时未办业务的客户”(检查lastinteraction,超过timeout则关闭客户端)。
- 清理客户的 “废弃申请单”(输入缓冲区过大时重置,释放内存)。
五、服务器初始化:银行的 “开业准备流程”
Redis 服务器从启动到接待客户,像银行开业前的准备:
布置场地(初始化服务器状态):
- 设定 “银行编号(runid)”、“营业时间(默认配置)”、“业务窗口数量(端口)” 等基础信息(initServerConfig函数)。
- 准备 “业务手册(命令表)”,把所有可办理的业务(SET、GET等)录入。
加载个性化配置(载入配置选项):
- 根据 “上级指示(命令行参数)” 和 “银行规章(配置文件)”,调整营业时间、窗口数量等(覆盖默认配置)。
准备设备(初始化数据结构):
- 摆好 “客户排队表(server.clients链表)”、“账户档案柜(server.db数组)”。
- 准备 “理财产品订阅簿(pubsub_channels字典)”、“慢业务记录本(slowlog)” 等。
恢复账目(还原数据库状态):
- 开业前,根据 “纸质账本(RDB 文件)” 或 “历史流水(AOF 文件)”,把所有客户账户余额恢复到上次关门时的状态。
六、总结:银行系统与 Redis 的对应逻辑
整个 Redis 客户端与服务器的交互,就像银行的 “客户 – 柜员 – 大堂经理” 体系:
- 客户端是 “客户”,带着命令请求来办理业务,有自己的档案信息。
- 命令处理流程是 “柜员的标准化服务步骤”,从接收到反馈环环相扣。
- serverCron是 “大堂经理的巡检”,确保银行资源合理分配、系统稳定运行。
- 初始化过程是 “开业准备”,从场地布置到账目恢复,为服务客户做足准备。
这种设计让 Redis 既能高效处理 “客户业务(命令)”,又能通过 “巡检” 维持系统稳定,就像一家流程规范、运转高效的银行。



