通过 Redis-cli 高效操作 Redis 数据 – wiki基地


Redis-cli 利器:高效操作 Redis 数据的深度指南

Redis,作为一款高性能的内存键值数据库,凭借其闪电般的读写速度、丰富的数据结构和灵活的应用场景,在现代软件架构中扮演着至关重要的角色。无论是缓存、消息队列、排行榜还是分布式锁,Redis 都能游刃有余。而 redis-cli (Redis Command Line Interface),作为 Redis 官方提供的命令行工具,是与 Redis 服务进行交互最直接、最便捷的方式。掌握 redis-cli 的高效使用技巧,不仅能提升开发和运维效率,更能深入理解 Redis 的内部机制,从而更好地优化应用性能。

本文将深入探讨如何通过 redis-cli 高效地操作 Redis 数据,涵盖基础连接、常用命令、数据结构选择、效率优化技巧、高级功能以及最佳实践,旨在为读者提供一份全面而实用的 redis-cli 使用指南。

一、 基础入门:连接与交互

redis-cli 的使用始于连接到 Redis 服务器。最简单的连接方式是在命令行直接输入 redis-cli,它会尝试连接到本地(127.0.0.1)的默认端口(6379)。

bash
$ redis-cli
127.0.0.1:6379>

如果 Redis 服务器位于不同的主机或使用了非默认端口,可以通过 -h-p 参数指定:

bash
$ redis-cli -h your_redis_host -p your_redis_port
your_redis_host:your_redis_port>

如果 Redis 服务器设置了密码认证,可以使用 -a 参数或在连接后使用 AUTH 命令进行认证:

“`bash

使用 -a 参数

$ redis-cli -h your_redis_host -p your_redis_port -a your_password

连接后使用 AUTH 命令

$ redis-cli -h your_redis_host -p your_redis_port
your_redis_host:your_redis_port> AUTH your_password
OK
your_redis_host:your_redis_port>
“`

连接成功后,redis-cli 会进入交互模式,提示符显示当前连接的主机和端口。此时,你可以输入 Redis 命令并按回车执行。

常用基础命令示例:

  1. PING: 测试服务器是否在线,正常会返回 PONG
    bash
    127.0.0.1:6379> PING
    PONG
  2. SET key value [EX seconds] [PX milliseconds] [NX|XX]: 设置键值对。
    • EX seconds: 设置键的过期时间(秒)。
    • PX milliseconds: 设置键的过期时间(毫秒)。
    • NX: 只在键不存在时设置。
    • XX: 只在键已存在时设置。
      bash
      127.0.0.1:6379> SET user:1:name Alice EX 3600
      OK
  3. GET key: 获取键的值。如果键不存在,返回 (nil)
    bash
    127.0.0.1:6379> GET user:1:name
    "Alice"
  4. DEL key [key ...]: 删除一个或多个键。返回成功删除的键的数量。
    bash
    127.0.0.1:6379> DEL user:1:name
    (integer) 1
  5. EXISTS key [key ...]: 检查一个或多个键是否存在。返回存在的键的数量。
    bash
    127.0.0.1:6379> EXISTS user:1:name
    (integer) 0
  6. TTL key: 获取键的剩余生存时间(秒)。-1 表示永不过期,-2 表示键不存在。
    bash
    127.0.0.1:6379> SET temp_key "hello" EX 60
    OK
    127.0.0.1:6379> TTL temp_key
    (integer) 58
  7. TYPE key: 返回键存储的值的类型(string, list, set, zset, hash, stream)。
    bash
    127.0.0.1:6379> TYPE temp_key
    string

交互模式特性:

  • 命令历史: 使用上下箭头键可以浏览之前执行过的命令。
  • 自动补全: 输入命令或键名的一部分,按 Tab 键可以尝试自动补全。这对于长命令和复杂的键名非常有用。
  • 清晰的响应: redis-cli 会根据 Redis 返回的数据类型,以易于阅读的格式显示结果(如字符串、整数、数组等)。

二、 深入数据结构:选择与高效操作

Redis 的强大之处在于其支持多种复杂的数据结构。理解并根据场景选择合适的数据结构,是高效使用 Redis 的关键。redis-cli 提供了操作这些数据结构的完整命令集。

1. Strings (字符串)

  • 用途: 最基础的类型,可以是文本、序列化的 JSON、二进制数据等。常用于缓存、计数器。
  • 高效操作:

    • INCR key / DECR key: 原子地增加/减少整数值。非常适合实现计数器、限流器。
    • INCRBY key increment / DECRBY key decrement: 原子地增加/减少指定的整数值。
    • APPEND key value: 将值追加到现有字符串末尾。
    • GETSET key value: 设置新值并返回旧值,原子操作。
    • MSET key value [key value ...] / MGET key [key ...]: 批量设置/获取多个键值,显著减少网络往返次数 (RTT),提升效率。相比于循环执行 SET/GETMSET/MGET 效率高得多。

    “`bash

    批量设置

    127.0.0.1:6379> MSET product:1:name “Laptop” product:1:price 999 product:2:name “Mouse”
    OK

    批量获取

    127.0.0.1:6379> MGET product:1:name product:2:name non_existent_key
    1) “Laptop”
    2) “Mouse”
    3) (nil)

    原子计数

    127.0.0.1:6379> SET counter 100
    OK
    127.0.0.1:6379> INCR counter
    (integer) 101
    “`

2. Hashes (哈希)

  • 用途: 存储对象结构,一个键包含多个字段和值的映射。适合存储用户信息、商品属性等。
  • 高效操作:

    • HSET key field value [field value ...]: 设置一个或多个字段值。
    • HGET key field: 获取指定字段的值。
    • HMSET key field value [field value ...] (已不推荐,建议使用 HSET): 批量设置字段值。
    • HMGET key field [field ...]: 批量获取多个字段的值。减少 RTT。
    • HGETALL key: 获取所有字段和值。注意: 对于包含大量字段的哈希,HGETALL 可能导致性能问题,应谨慎使用。
    • HKEYS key / HVALS key: 获取所有字段名/字段值。
    • HLEN key: 获取字段数量。
    • HINCRBY key field increment: 原子地增加哈希中指定字段的整数值。
    • HSCAN key cursor [MATCH pattern] [COUNT count]: 增量迭代哈希的字段,避免 HGETALL 对大哈希的性能影响。

    bash
    127.0.0.1:6379> HSET user:1 id 1 name "Bob" email "[email protected]"
    (integer) 3
    127.0.0.1:6379> HMGET user:1 name email age
    1) "Bob"
    2) "[email protected]"
    3) (nil)
    127.0.0.1:6379> HINCRBY user:1 visits 1
    (integer) 1

    效率考量: 相比于将对象的每个属性存储为单独的 String 键(如 user:1:id, user:1:name),使用 Hash 可以更节省内存(特别是字段较多时,Redis 内部有优化),并且逻辑上更聚合。批量操作 (HMGET, HSET) 比多次单字段操作更高效。

3. Lists (列表)

  • 用途: 有序的字符串列表,支持两端插入和弹出。常用于实现消息队列、任务列表、最新动态等。
  • 高效操作:

    • LPUSH key element [element ...] / RPUSH key element [element ...]: 从左/右端插入一个或多个元素。批量插入效率更高。
    • LPOP key [count] / RPOP key [count]: 从左/右端弹出一个或多个元素。
    • LLEN key: 获取列表长度。
    • LRANGE key start stop: 获取指定范围内的元素。LRANGE key 0 -1 获取所有元素,但需注意列表大小,避免一次获取过多数据。
    • LTRIM key start stop: 修剪列表,只保留指定范围内的元素。常用于限制列表长度。
    • BLPOP key [key ...] timeout / BRPOP key [key ...] timeout: 阻塞式弹出操作。如果列表为空,连接会阻塞直到有元素可弹出或超时。这是实现可靠消息队列的关键,避免了客户端轮询,极大提高了效率和实时性。timeout 为 0 表示无限期阻塞。

    “`bash

    模拟消息队列

    127.0.0.1:6379> LPUSH tasks “task1” “task2” “task3”
    (integer) 3
    127.0.0.1:6379> RPOP tasks
    “task1”

    阻塞获取任务,等待 10 秒

    127.0.0.1:6379> BRPOP tasks 10
    1) “tasks”
    2) “task2”

    限制列表只保留最新的 5 个元素

    127.0.0.1:6379> LPUSH recent_items “item_new”
    (integer) 6 # 假设之前已有 5 个
    127.0.0.1:6379> LTRIM recent_items 0 4
    OK
    “`

4. Sets (集合)

  • 用途: 无序的、唯一的字符串集合。常用于标签、好友关系、去重统计等。
  • 高效操作:

    • SADD key member [member ...]: 向集合添加一个或多个成员。重复成员会被忽略。
    • SREM key member [member ...]: 移除一个或多个成员。
    • SMEMBERS key: 获取集合所有成员。注意: 对大集合慎用。
    • SISMEMBER key member: 判断成员是否存在于集合中。O(1) 复杂度,非常高效。
    • SCARD key: 获取集合的基数(成员数量)。
    • SPOP key [count]: 随机移除并返回一个或多个成员。
    • SRANDMEMBER key [count]: 随机返回一个或多个成员,但不移除。
    • SINTER key [key ...] / SUNION key [key ...] / SDIFF key [key ...]: 计算集合的交集、并集、差集。服务器端计算,效率远高于客户端获取所有成员再计算。
    • SINTERSTORE destination key [key ...]: 计算交集并将结果存入新集合。
    • SSCAN key cursor [MATCH pattern] [COUNT count]: 增量迭代集合成员,避免 SMEMBERS 对大集合的影响。

    “`bash
    127.0.0.1:6379> SADD tags:post:1 “redis” “database” “nosql”
    (integer) 3
    127.0.0.1:6379> SADD tags:post:2 “redis” “cache” “performance”
    (integer) 3
    127.0.0.1:6379> SISMEMBER tags:post:1 “java”
    (integer) 0

    查找同时拥有 “redis” 和 “database” 标签的文章 (假设文章 ID 存在于集合中)

    实际应用中可能需要更复杂的结构,这里仅作集合运算示例

    127.0.0.1:6379> SINTER tags:post:1 tags:post:2
    1) “redis”
    “`

5. Sorted Sets (有序集合 / Zsets)

  • 用途: 类似于集合,但每个成员都关联一个 score (浮点数),并根据 score 排序。常用于排行榜、带权重的任务队列、范围查找。
  • 高效操作:

    • ZADD key [NX|XX] [CH] [INCR] score member [score member ...]: 添加或更新一个或多个成员及其分数。INCR 可用于原子增加分数。
    • ZREM key member [member ...]: 移除一个或多个成员。
    • ZCARD key: 获取成员数量。
    • ZSCORE key member: 获取成员的分数。
    • ZRANGE key start stop [WITHSCORES]: 按分数从低到高获取指定排名范围的成员。
    • ZREVRANGE key start stop [WITHSCORES]: 按分数从高到低获取指定排名范围的成员。
    • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]: 按分数范围获取成员。
    • ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]: 按分数范围逆序获取成员。
    • ZRANK key member / ZREVRANK key member: 获取成员的排名(从 0 开始)。
    • ZCOUNT key min max: 获取指定分数范围内的成员数量。
    • ZINCRBY key increment member: 原子地增加成员的分数。
    • ZSCAN key cursor [MATCH pattern] [COUNT count]: 增量迭代有序集合成员。

    “`bash

    实现游戏排行榜

    127.0.0.1:6379> ZADD leaderboard 1500 “Alice” 2100 “Bob” 1800 “Charlie”
    (integer) 3

    Bob 又得了 100 分

    127.0.0.1:6379> ZINCRBY leaderboard 100 “Bob”
    “2200”

    获取排名前 2 的玩家及其分数

    127.0.0.1:6379> ZREVRANGE leaderboard 0 1 WITHSCORES
    1) “Bob”
    2) “2200”
    3) “Charlie”
    4) “1800”

    获取 Alice 的排名

    127.0.0.1:6379> ZREVRANK leaderboard “Alice”
    (integer) 2
    ``
    **效率考量**: Zset 的大部分操作复杂度为 O(log N),其中 N 是成员数量。这使得它在处理大量有序数据时依然高效。范围查询 (
    ZRANGEBYSCORE`) 是其强大特性之一。

三、 提升效率的核心武器:Pipelining、Lua 脚本与 SCAN

仅仅掌握基础命令和数据结构操作是不够的,要真正高效地使用 redis-cli(以及任何 Redis 客户端),必须利用 Redis 提供的高级特性来优化交互过程。

1. Pipelining (管道)

  • 原理: 客户端可以将多个命令一次性发送给服务器,而无需等待每个命令的响应。服务器处理完所有命令后,将所有响应一次性返回给客户端。
  • 优势: 大幅减少网络往返时延 (RTT)。对于需要执行大量连续命令的场景(如批量导入、复杂事务的预处理),效果极其显著。
  • redis-cli 中的使用: 可以通过 Unix 管道将命令文件传递给 redis-cli--pipe 模式。

    “`bash

    创建一个包含命令的文本文件 (e.g., commands.txt)

    commands.txt 内容:

    SET key1 value1

    INCR counter

    LPUSH mylist item1

    SADD myset member1

    使用管道执行

    $ cat commands.txt | redis-cli –pipe
    All data transferred. Waiting for the last reply…
    Last reply received from server.
    errors: 0, replies: 4
    ``–pipe` 模式会以原始 Redis 协议格式发送命令,并解析响应。这种方式比在交互模式下逐条输入命令快得多。

2. Lua 脚本 (EVAL / EVALSHA)

  • 原理: 将一段 Lua 脚本发送到 Redis 服务器执行。脚本可以包含多个 Redis 命令,这些命令会作为一个原子操作执行。
  • 优势:
    • 原子性: 保证脚本内的所有命令要么全部成功,要么全部失败,不会出现中间状态。这对于实现复杂的原子操作(如 CAS – Check-And-Set)至关重要。
    • 减少网络开销: 将多次网络交互合并为一次脚本执行,降低延迟。
    • 复用性: 脚本可以被缓存(通过 SCRIPT LOAD 获取 SHA1 校验和),之后使用 EVALSHA 加上 SHA1 值执行,避免了每次传输整个脚本。
  • redis-cli 中的使用:

    • EVAL "lua-script" numkeys key [key ...] arg [arg ...]: 执行 Lua 脚本。numkeys 指定脚本中 KEYS 数组的参数数量。

    “`bash

    示例:原子地获取并增加计数器,仅当其值小于某个阈值时

    127.0.0.1:6379> EVAL “local current = redis.call(‘GET’, KEYS[1]); if current == false or tonumber(current) < tonumber(ARGV[1]) then return redis.call(‘INCR’, KEYS[1]) else return current end” 1 my_counter 10
    (integer) 1 # 假设 my_counter 不存在或小于 10,执行 INCR 并返回新值
    ``
    * **
    SCRIPT LOAD “lua-script”**: 加载脚本到服务器缓存,返回 SHA1 值。
    * **
    EVALSHA sha1 numkeys key [key …] arg [arg …]`**: 通过 SHA1 值执行已缓存的脚本。

    bash
    127.0.0.1:6379> SCRIPT LOAD "return redis.call('GET', KEYS[1])"
    "sha1-hash-string"
    127.0.0.1:6379> EVALSHA sha1-hash-string 1 some_key
    "value_of_some_key"

    Lua 脚本是 Redis 实现复杂逻辑和保证原子性的强大工具,熟练使用能极大提升应用逻辑的健壮性和效率。

3. 迭代器 (SCAN, HSCAN, SSCAN, ZSCAN)

  • 问题: KEYS pattern 命令会遍历整个键空间,SMEMBERS, HGETALL 等命令会一次性返回所有成员/字段。在数据量大时,这些操作会阻塞 Redis 服务器,影响性能,甚至导致服务不可用。
  • 解决方案: SCAN 及其家族命令提供了基于游标的增量迭代方式。每次调用只返回一部分数据和一个新的游标,客户端通过传递上一次返回的游标来继续迭代,直到游标返回 0 为止。
  • 优势:
    • 非阻塞: 不会长时间阻塞服务器。
    • 可控性: 可以通过 COUNT 参数建议每次迭代返回的元素数量(但不是精确保证)。
    • 适用于大数据集: 安全地遍历海量数据。
  • redis-cli 中的使用:

    “`bash

    迭代所有键

    127.0.0.1:6379> SCAN 0 MATCH user: COUNT 100
    1) “17” # 下一个游标
    2) 1) “user:1”
    2) “user:2”
    … (最多 100 个匹配的键)
    127.0.0.1:6379> SCAN 17 MATCH user:
    COUNT 100
    1) “0” # 游标为 0,表示迭代完成
    2) 1) “user:101”

    迭代哈希 user:1 的字段

    127.0.0.1:6379> HSCAN user:1 0 COUNT 10
    1) “5”
    2) 1) “name”
    2) “Bob”
    3) “email”
    4) “[email protected]

    迭代集合 tags:post:1 的成员

    127.0.0.1:6379> SSCAN tags:post:1 0 MATCH data*

    迭代有序集合 leaderboard 的成员

    127.0.0.1:6379> ZSCAN leaderboard 0 COUNT 50

    ``
    在生产环境中,**强烈推荐使用
    SCAN系列命令替代KEYSSMEMBERSHGETALL` 等可能引起阻塞的操作**。

四、 redis-cli 进阶技巧与监控

除了基本操作和效率优化,redis-cli 还提供了一些实用功能,帮助开发者和运维人员更好地管理和监控 Redis。

  • MONITOR: 实时打印服务器接收到的所有命令请求。非常适合调试和理解应用与 Redis 的交互模式。注意:MONITOR 会显著增加服务器负载,且输出大量信息,仅建议在开发或调试环境短时间使用,切勿在生产环境长时间开启。
    bash
    $ redis-cli MONITOR
    OK
    1678886400.123456 [0 127.0.0.1:12345] "SET" "mykey" "myvalue"
    1678886401.654321 [0 127.0.0.1:54321] "GET" "mykey"
    ...
  • SLOWLOG GET [count]: 获取 Redis 慢查询日志。慢查询日志记录了执行时间超过指定阈值(通过 slowlog-log-slower-than 配置)的命令。这是排查性能瓶颈的重要工具。
    bash
    127.0.0.1:6379> SLOWLOG GET 2
    1) 1) (integer) 14 # 唯一日志 ID
    2) (integer) 1678886500 # 命令执行时的时间戳
    3) (integer) 15768 # 命令执行耗时 (微秒)
    4) 1) "KEYS" # 命令及参数
    2) "*"
    5) "127.0.0.1:12345" # 客户端地址
    6) "client-name" # 客户端名称 (如果设置了)
    2) ... (下一条慢日志)

    可以使用 SLOWLOG LEN 获取日志条数,SLOWLOG RESET 清空日志。
  • INFO [section]: 获取 Redis 服务器的各种信息和统计数据。不带参数返回所有信息,可以指定 section (如 memory, cpu, stats, replication, clients, cluster 等) 获取特定部分信息。这是监控 Redis 状态和性能的关键命令。
    bash
    127.0.0.1:6379> INFO memory
    # Memory
    used_memory:1048576
    used_memory_human:1.00M
    ...
    mem_fragmentation_ratio:1.03
    ...
  • CLIENT LIST: 列出所有连接到服务器的客户端信息。有助于排查连接数问题或识别异常连接。
  • --raw / --no-raw: 控制输出格式。--raw 模式输出原始的、未经美化的字符串,适合脚本处理。默认是美化输出。
  • --csv: 以 CSV 格式输出结果,方便导入电子表格或进行数据分析。
  • --latency / --latency-history / --latency-dist: 测试与服务器的网络延迟。
  • -r <repeat> -i <interval>: 重复执行命令。例如 redis-cli -r 10 -i 1 PING 会每秒执行一次 PING,共执行 10 次。适合简单监控。
  • --cluster call <node-id> <command> [args...]: 在 Redis Cluster 模式下,向指定节点发送命令。
  • -c (Cluster Mode): 连接到 Redis Cluster 时启用。redis-cli 会自动处理 -MOVED-ASK 重定向,将命令发送到正确的节点。

五、 高效使用 redis-cli 的最佳实践

  1. 理解数据结构和命令复杂度: 根据业务场景选择最合适的数据结构。了解常用命令的时间复杂度(大部分可以在 Redis 官网文档查到),避免在性能敏感路径上使用高复杂度命令(如 KEYS, SMEMBERS, HGETALL 对大数据集)。
  2. 优先使用批量操作: 对于多个键的操作,尽量使用 MSET, MGET, DEL key1 key2 ... 等批量命令,减少网络开销。
  3. 利用 Pipelining: 对于需要连续执行大量命令的场景,使用 --pipe 模式或客户端库提供的 Pipelining 功能。
  4. 拥抱 Lua 脚本: 对于需要原子性保证或包含复杂逻辑的操作,使用 Lua 脚本在服务器端执行。记得使用 EVALSHA 复用缓存脚本。
  5. 安全迭代: 在遍历键空间或大集合/哈希/有序集合时,坚决使用 SCAN, HSCAN, SSCAN, ZSCAN,避免阻塞服务器。
  6. 合理设置过期时间 (TTL): 对于缓存数据,设置合理的过期时间,避免内存无限增长。使用 EXPIRE, PEXPIRESET 命令的 EX/PX 选项。
  7. 监控与分析: 定期使用 INFO 查看服务器状态,关注 used_memory, fragmentation_ratio, connected_clients, instantaneous_ops_per_sec 等指标。使用 SLOWLOG 发现并优化慢查询。
  8. 谨慎使用 MONITOR: 只在必要时短时间使用,切勿在生产环境长时间开启。
  9. 管理连接: 应用层面应使用连接池来复用连接,避免频繁创建和销毁连接。通过 CLIENT LIST 监控连接情况。
  10. 保持 redis-cli 更新: 新版本的 redis-cli 可能包含性能改进、新功能和 bug 修复。

六、 结语

redis-cli 不仅仅是一个简单的命令行工具,它是深入理解和高效驾驭 Redis 的一把瑞士军刀。从基础的连接交互,到熟练运用各种数据结构,再到掌握 Pipelining、Lua 脚本、SCAN 迭代等高级效率技巧,以及利用监控命令洞察 Redis 内部状态,每一步都关乎我们能否充分发挥 Redis 的强大性能。

通过本文的详细阐述,希望读者能够更加自信和高效地使用 redis-cli 进行 Redis 数据操作、管理和调试。请记住,选择正确的工具和方法,理解其背后的原理,并结合实际场景不断实践和优化,是通往高效 Redis 应用的必经之路。将 redis-cli 用好、用精,你将能更从容地应对各种数据挑战,构建出更加健壮和高性能的系统。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部