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 的启动的主要内容,如果未能解决你的问题,请参考以下文章

无法从 yugabyte 数据库启动 redis-cli

解决redis集群./redis-cli 启动 Connection refused

本地redis服务的启动以及客户端的链接

Ubuntu18.04下安装redis数据库

Redis-cli - 正在运行的队列命令列表?

使用 redis-cli 搭建 Redis 集群