18 redis-cli 的启动
Posted 蓝风9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了18 redis-cli 的启动相关的知识,希望对你有一定的参考价值。
前言
相关介绍主要围绕着 redis-cli 服务的启动相关
redis-cli 的启动, 是执行 redis-cli.c 的 int main(int argc, char **argv), 我们这里看的是常用的 repl 的情况下的服务的启动流程
本文的相关代码 拷贝自 redis-6.2.0
代码来自于 https://redis.io/
初始化服务配置
这里主要是初始化 redis-cli 的默认配置, 如果不带任何参数的话, 会使用这些默认配置
加载配置
解析用户输入的参数, 从系统环境变量中解析参数[REDIS_CLI_AUTH_ENV, REDIS_CLI_CLUSTER_YES_ENV]
初始化 随机种子
解析参数, 覆盖参数关联的配置信息
对于 version, help 等命令是输出 version, help 相关信息 之后退出 redis-cli
各个 Mode
这里各个 mode, 就请参见 help 的信息了, 描述的非常清晰
--stat Print rolling stats about server: mem, clients, ...
--latency Enter a special mode continuously sampling latency.
If you use this mode in an interactive session it runs
forever displaying real-time stats. Otherwise if --raw or
--csv is specified, or if you redirect the output to a non
TTY, it samples the latency for 1 second (you can use
-i to change the interval), then produces a single output
and exits.
--latency-history Like --latency but tracking latency changes over time.
Default time interval is 15 sec. Change it using -i.
--latency-dist Shows latency as a spectrum, requires xterm 256 colors.
Default time interval is 1 sec. Change it using -i.
--lru-test <keys> Simulate a cache workload with an 80-20 distribution.
--replica Simulate a replica showing commands received from the master.
--rdb <filename> Transfer an RDB dump from remote server to local file.
--pipe Transfer raw Redis protocol from stdin to server.
--pipe-timeout <n> In --pipe mode, abort with error if after sending all data.
no reply is received within <n> seconds.
Default timeout: 30. Use 0 to wait forever.
--bigkeys Sample Redis keys looking for keys with many elements (complexity).
--memkeys Sample Redis keys looking for keys consuming a lot of memory.
--memkeys-samples <n> Sample Redis keys looking for keys consuming a lot of memory.
And define number of key elements to sample
--hotkeys Sample Redis keys looking for hot keys.
only works when maxmemory-policy is *lfu.
--scan List all keys using the SCAN command.
--pattern <pat> Keys pattern when using the --scan, --bigkeys or --hotkeys
options (default: *).
--intrinsic-latency <sec> Run a test to measure intrinsic system latency.
The test will run for the specified amount of seconds.
--eval <file> Send an EVAL command using the Lua script at <file>.
--ldb Used with --eval enable the Redis Lua debugger.
--ldb-sync-mode Like --ldb but uses the synchronous Lua debugger, in
this mode the server is blocked and script changes are
not rolled back from the server memory.
--cluster <command> [args...] [opts...]
Cluster Manager command and arguments (see below).
--verbose Verbose mode.
比较常用的 --stat 可以监控 redis-server 的状态信息
--bigkeys, --memkeys 可以监控 redis-server 中元素较多的 key, 内存占用较大的 key
最常用的默认的 repl 模式, 就是连接 redis-server 和 redis-server 进行 repl 交互, 也是我们这里 主要要去看的东西
repl 模式
首先是和 redis-server 创建连接, 然后在进行 repl[read-eval-print-loop]
cliConnect
连接给定的 host, port 或者 socket
如果需要 auth, 发送 auth 请求
如果需要 切换 db, 发送 select 请求
如果需要切换协议, 发送 hello 请求
repl
1. redis-cli 的初始化, linenoise 上下文的初始化
cliInitHelp 里面初始化的是当前版本的 redis-cli 支持的相关的 group, command 列表的信息
cliIntegrateHelp 里面初始化的是当前 redis-cli 不支持的, 但是连接的目标 redis-server 支持的这部分 command, 整合到 command 列表里面
linenoiseSetCompletionCallback(completionCallback) : 是用户从 redis-cli 输入命令的一部分之后, 按 tab 自动补全命令的功能
[输入 he 之后键入 tabe]
linenoiseSetHintsCallback(hintsCallback) : 用户输入了 命令 + 参数 的时候, redis-cli 提示的完整的 命令 + 参数 格式
[输入 set name]
linenoiseHistoryLoad 从 redisCliHistory 文件中加载历史命令信息
cliLoadPreferences 从 redisCliRc 文件中加载客户端的配置信息[hints]
2. 接受用户的输入
输出给用户的提示信息, 并接受用户的输入
解析用户的输入为 argc, argv, 用户认证相关命令约束为 dangerous 命令
添加历史命令到 linenioseHistory, redisCliHisotry 文件中
3. redis-cli 处理命令
如果没有拿到参数, 输出 "Invliad argument(s)"
如果是 exit, quit 命令, 直接退出 redis-cli
如果是 ":" 开头的命令, 客户端偏好相关设置, 目前支持 ":set hints", ":set nohints"
如果是 "connect" 命令, 连接给定的 ip, port 暴露服务的 redis-serverr
如果是 "clear" 清理 屏幕输入的命令 "\\x1b[H\\x1b[2J"
否则 发送命令给 redis-server, 并接受 redis-server 的返回 输出到 redis-cli 的控制台
4. redis-cli 和 redis-server 交互
发送命令给 redis-server
如果出现问题, 补偿重新连接保存的 redis-server, 再重新发送命令
4.1 处理 help 命令, help + command 或者 help + @group
对于一部分特殊的命令, 更新输出格式
4.2 重复 repeat 次
发送 argc, argv 给 redis-server[涉及到基于 redis 协议的数据传输]
读取 redis-server 返回的数据 [涉及到基于 redis 协议的数据解析], 并输出响应的结果 反馈给用户
一部分 redis-cli 需要处理的额外业务, select 记录 db, multi/exec/discard 记录 in_multi 等等
4.2.1 将命令基于 redis 协议封装
这个就很简单了, multi bulk 格式的命令封装, "*$len\\r\\n\\$$len1\\r\\n$arg1\\r\\n\\$$len2\\r\\n$arg2\\r\\n"
4.2.2 发送命令到 redis-cli
将基于 redis 协议封装的命令, 复制到 c->obuf
redisBufferWrite 写出 c->obuf 的数据到 redis-server
然后后面 读取 redis-server 的响应
4.2.3 读取 redis-server 的响应
首先是根据 第一个字节 确定响应的类型
再根据 后面的数据, 解析对象
我们这里 get name, redis-server 返回的是 "$5\\r\\nzerry\\r\\n", 对应于这里的处理室 processBlukItem
读取字符串的长度 5, 然后在根据 后面的 "zerry" 创建字符串 封装成 redisReply
createStringObject[函数在 redisContext 中] 字符串封装成为 redisReply
4.2.4 输出 redisReply
这里会格式化 reply, 并输出到 redis-cli, 也就是我们在 redis-cli 中看到的 结果的渲染
比如我们这里的 string "zerry", 是直接格式化为 "zerry\\r\\n", 其他的场景请参见 具体的实现
具体协议的数据可以参见 基本说明 里面 一次命令交互的数据
完
以上是关于18 redis-cli 的启动的主要内容,如果未能解决你的问题,请参考以下文章