当前位置: 首页 > java >正文

Redis 客户端与服务器:银行的 “客户服务系统” 全流程

目录

一、Redis 客户端:银行的 “客户档案”

二、客户端关闭:银行的 “终止服务规则”

三、命令处理流程:柜员办理业务的 “标准步骤”

1. 接收申请单(读取命令请求)

2. 确认业务类型(查找命令)

3. 检查业务合法性(预备操作)

4. 办理业务(调用命令实现函数)

5. 收尾工作(执行后续工作)

6. 给客户回执(发送命令回复)

四、serverCron 函数:大堂经理的 “定期巡检”

五、服务器初始化:银行的 “开业准备流程”

六、总结:银行系统与 Redis 的对应逻辑


如果把 Redis 服务器比作一家高效运转的银行,那么客户端就是 “来办理业务的客户”,服务器的命令处理流程就是 “柜员办理业务的标准步骤”,而serverCron函数则是 “大堂经理的定期巡检”。我们用银行的场景来拆解这整套系统:

一、Redis 客户端:银行的 “客户档案”

每个来银行办理业务的客户,银行都会建立一份 “客户档案(redisClient结构体)”,记录客户的关键信息:

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. 收尾工作(执行后续工作)

  • 若业务耗时太长(慢查询),记录到 “慢业务日志”。
  • 更新该业务的 “办理次数” 和 “平均耗时”(callsmilliseconds属性)。
  • 把业务详情记到 “银行流水(AOF 缓冲区)”,同步给 “总行备份(从服务器)”。

6. 给客户回执(发送命令回复)

  • 柜员把办理结果写在 “回执单(输出缓冲区)”,等客户窗口空闲(套接字可写)时,把回执递给客户。

四、serverCron 函数:大堂经理的 “定期巡检”

银行大堂经理每 100 毫秒巡视一次(serverCron默认频率),处理日常维护,确保银行正常运转:

  1. 校准时钟:同步墙上的 “电子钟(unixtime秒级时间)” 和 “毫秒表(mstime)”,减少频繁看表(系统调用)的开销。
  2. 更新物品存放时间:每 10 秒更新一次 “储物柜最后使用时钟(lruclock)”,用于判断哪些物品长期无人取(LRU 内存回收)。
  3. 统计业务量:每 100 毫秒抽样统计 “每秒办理业务数”,估算银行繁忙程度。
  4. 记录最大客流量:若当前客户数创纪录,更新 “最高客流量(stat_peak_memory)”。
  5. 处理停业通知:若收到 “停业指令(SIGTERM信号)”,标记 “准备关门(shutdown_asap)”,下次巡视时执行关门。
  6. 维护客户秩序
    • 清退 “超时未办业务的客户”(检查lastinteraction,超过timeout则关闭客户端)。
    • 清理客户的 “废弃申请单”(输入缓冲区过大时重置,释放内存)。
  7. 安排备份工作:若 “流水账重写(BGREWRITEAOF)” 因 “账本快照(BGSAVE)” 排队,现在轮到它执行了。
  8. 检查备份进度:看看 “账本快照员(rdb_child_pid)” 和 “流水账重写员(aof_child_pid)” 是否在工作,是否完成。
  9. 同步流水账:把 “临时流水缓冲区(AOF 缓冲区)” 的内容写到 “正式流水册(AOF 文件)”。
  10. 清退取单超时客户:把 “回执单拿太久(输出缓冲区超限)” 的客户请离。
  11. 记录巡视次数:每次巡视后,“巡视计数器(cronloops)” 加 1,用于一些定时任务触发。

五、服务器初始化:银行的 “开业准备流程”

Redis 服务器从启动到接待客户,像银行开业前的准备:

  1. 布置场地(初始化服务器状态)

    • 设定 “银行编号(runid)”、“营业时间(默认配置)”、“业务窗口数量(端口)” 等基础信息(initServerConfig函数)。
    • 准备 “业务手册(命令表)”,把所有可办理的业务(SETGET等)录入。
  2. 加载个性化配置(载入配置选项)

    • 根据 “上级指示(命令行参数)” 和 “银行规章(配置文件)”,调整营业时间、窗口数量等(覆盖默认配置)。
  3. 准备设备(初始化数据结构)

    • 摆好 “客户排队表(server.clients链表)”、“账户档案柜(server.db数组)”。
    • 准备 “理财产品订阅簿(pubsub_channels字典)”、“慢业务记录本(slowlog)” 等。
  4. 恢复账目(还原数据库状态)

    • 开业前,根据 “纸质账本(RDB 文件)” 或 “历史流水(AOF 文件)”,把所有客户账户余额恢复到上次关门时的状态。

六、总结:银行系统与 Redis 的对应逻辑

整个 Redis 客户端与服务器的交互,就像银行的 “客户 - 柜员 - 大堂经理” 体系:

  • 客户端是 “客户”,带着命令请求来办理业务,有自己的档案信息。
  • 命令处理流程是 “柜员的标准化服务步骤”,从接收到反馈环环相扣。
  • serverCron是 “大堂经理的巡检”,确保银行资源合理分配、系统稳定运行。
  • 初始化过程是 “开业准备”,从场地布置到账目恢复,为服务客户做足准备。

这种设计让 Redis 既能高效处理 “客户业务(命令)”,又能通过 “巡检” 维持系统稳定,就像一家流程规范、运转高效的银行。

http://www.xdnf.cn/news/20003.html

相关文章:

  • LeetCode 面试经典 150_矩阵_螺旋矩阵(35_54_C++_中等)(按层模拟)
  • K8S容器POD内存快照导出分析处理方案
  • Nano-Banana使用教程
  • websocket的key和accept分别是多少个字节
  • Widget 生命周期
  • 【Python基础】 13 Rust 与 Python 注释对比笔记
  • 零基础两个月通关2025下半年软考!保姆级冲刺规划(附每日学习表)
  • 随时学英语5 逛生活超市
  • 25高教社杯数模国赛【C题顶流思路+问题解析】第三弹
  • 处理PostgreSQL中的磁盘I/O瓶颈
  • 从BERT到T5:为什么说T5是NLP的“大一统者”?
  • 一键成文,标准随行——文思助手智能写作助力政务提效
  • 常见的相机模型针孔/鱼眼(Pinhole,Mei,K
  • 从零构建一款开源在线客服系统:我的Go语言实战之旅
  • 对话A5图王:20年互联网老兵,从Web1.0到Web3.0,牛友会里藏着最真的创业情
  • 后端Long类型数据传给前端造成精度丢失
  • ReAct模式解读
  • Linux 编译 Android 版 QGroundControl 软件并运行到手机上
  • 东土正创AI交通服务器再获北京市批量应用订单
  • Agent Prompt工程:如何让智能体更“听话”?(实践指南)
  • 20250904 10:45_排查10.1.3.35新QMS系统RMAN备份失败问题(优化脚本里的环境配置,增加了check_oracle_env 函数)
  • openai-python v1.104.2版本发布:修复Web搜索工具类型别名问题
  • uni-app iOS 上架常见问题与解决方案,实战经验全解析
  • 2025数学建模国赛高教社杯C题思路代码文章助攻
  • Java对接Kafka的三国演义:三大主流客户端全景评测
  • 25高教社杯数模国赛【C题国一学长思路+问题分析】第二弹
  • 以数据与自动化驱动实验室变革:智能化管理整体规划
  • 救命!Shell用了100次还不懂底层?爆肝300行代码从0造“壳”,fork/exec/重定向全扒光,Linux系统编程直接开挂!
  • 【面试题】Prompt是如何生成的,优化目标是什么,任务是什么?
  • 服务器监控不用盯屏幕:Ward+Cpolar让异常告警主动找到你