【计算基础|Redis01】【上手】安装连接、配置与通用命令

【计算基础|Redis01】【上手】安装连接、配置与通用命令

很多人学 Redis 的第一步就走错:直接 docker run 起个容器,然后对着 redis-cli 瞎敲一通,连密码怎么带、中文为什么是一串十六进制、KEYS * 能不能在生产用都不知道,就急着上业务。Redis 上手其实半天就够,但安装、连接、配置、key 的通用命令这几块是地基,地基不牢后面全是玄学。

这篇把"把 Redis 跑起来 → 连上 → 看懂配置 → 用通用命令操作 key → 事务和发布订阅"整条链路在 Docker 里真跑一遍,每条命令都给语法→实例→预期输出→易错点,照着敲就能干活。所有输出来自 Redis 7.4 真实实例。

环境:Docker Desktop,官方镜像 redis:7(实跑版本 redis-server / redis-cli 7.4.11),macOS。容器内端口仍是 6379;为避免和本机其他容器冲突,我把宿主机端口映成了 16379,你照着敲用默认 6379 即可。


一、Docker 起一个 Redis:别装系统包

结论先给:学习和开发一律用 Docker 起 Redis ,别 apt install / brew install------版本不好控、删不干净、和生产对不上。一条命令的事。

1.1 最简启动

bash 复制代码
docker run -d --name redis7 -p 6379:6379 redis:7
部分 含义
-d 后台运行
--name redis7 容器名,后面 docker exec 靠它找容器
-p 6379:6379 宿主机 6379 → 容器内 6379
redis:7 用 7.x 最新稳定版(实跑为 7.4.11),生产建议锁小版本如 redis:7.4

进容器里用自带的 redis-cli 连:

bash 复制代码
docker exec -it redis7 redis-cli

-it 是开交互式终端。进去后就是 127.0.0.1:6379> 的提示符,直接敲命令。不想进交互,也可以一条一条地跑(本文后面的输出都这么采):

bash 复制代码
docker exec redis7 redis-cli PING
text 复制代码
PONG

✅ 成功标志 :PING 返回 PONG。这是 Redis 的心跳,以后"连上没"一律先敲 PING。

1.2 看日志、看版本

bash 复制代码
docker logs redis7                 # 看启动日志
docker exec redis7 redis-cli --version
docker exec redis7 redis-cli INFO server | grep -E "redis_version|tcp_port|uptime_in_days"

实跑输出:

text 复制代码
redis-cli 7.4.11

# INFO server 截取
redis_version:7.4.11
os:Linux 7.0.14-linuxkit aarch64
tcp_port:6379
uptime_in_days:0

🔴 排障第一步永远是这三样:docker logs 看是不是启动就崩了,INFO server 看版本/端口/运行时长。连不上时别瞎猜,先看日志。

1.3 带密码启动(生产必做)

裸奔的 Redis 谁都能连,生产等于把数据库挂在公网上。加密码:

bash 复制代码
docker run -d --name redis7 -p 6379:6379 redis:7 --requirepass redis123

注意 redis:7 后面的 --requirepass redis123 是传给 redis-server 的参数,不是 docker 的参数。

连的时候带密码:

bash 复制代码
docker exec -it redis7 redis-cli -a redis123

不带密码直接操作会被拒:

text 复制代码
NOAUTH Authentication required.

⚠️ -a 的坑 :密码会出现在进程列表里(ps 能看到)。实跑有警告:

text 复制代码
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

更安全的做法是用环境变量 REDISCLI_AUTH,命令行里完全不出现密码:

bash 复制代码
docker exec -e REDISCLI_AUTH=redis123 -it redis7 redis-cli

实跑:

bash 复制代码
docker exec -e REDISCLI_AUTH=redis123 redis-cli PING     # PONG,且无警告

1.4 远程连接参数

redis-cli 默认连 127.0.0.1:6379,连远程机器用 -h(host)和 -p(port):

bash 复制代码
redis-cli -h 192.168.1.10 -p 6379 -a redis123

1.5 --raw:中文不乱码的关键

交互式 redis-cli 里,中文等非 ASCII 字节默认会转义成十六进制 显示(比如 \xe5\xbc\xa0),看起来像乱码。加 --raw 就按原样输出:

bash 复制代码
docker exec redis7 redis-cli --raw GET user:1

本文是通过脚本批量抓输出(非 TTY),中文直出。你自己在终端里交互时,遇到一串 \x.. 别慌,加 --raw 即可。


二、配置:redis.conf 在哪、怎么改、改完生不生效

结论:Redis 的配置有三种改法------启动时指定配置文件、命令行参数、运行时 CONFIG SET 。前两种重启后还在,CONFIG SET 立刻生效但重启丢失,要持久化得 CONFIG REWRITE。

2.1 配置文件位置

官方 redis:7 镜像默认不带 redis.conf (启动参数就是 redis-server,全用默认值)。实跑验证:

bash 复制代码
docker exec redis7 sh -c 'ls /usr/local/etc/redis/redis.conf /etc/redis/redis.conf'
text 复制代码
ls: cannot access '/usr/local/etc/redis/redis.conf': No such file or directory
ls: cannot access '/etc/redis/redis.conf': No such file or directory

所以 Docker 里一般这么干:把宿主机的 redis.conf 挂进容器,再用它启动:

bash 复制代码
docker run -d --name redis7 -p 6379:6379 \
  -v /my/redis.conf:/usr/local/etc/redis/redis.conf \
  redis:7 redis-server /usr/local/etc/redis/redis.conf

最后那个参数就是"用这份配置启动"。

2.2 常用配置项速查表

配置项 作用 默认值(实跑) 动态生效?
port 监听端口 6379 否,重启
bind 绑定网卡 * -::*(容器内) 否
protected-mode 保护模式 容器内 no 是
requirepass 访问密码 空 是
daemonize 是否后台守护 no(容器内别开) 否
maxmemory 最大内存上限 0(不限) 是
maxmemory-policy 内存满了的淘汰策略 noeviction(不淘汰,写报错) 是
appendonly 是否开启 AOF 持久化 no 是
save RDB 快照规则 默认 3600s/1 次等 是
databases 逻辑库个数 16 否,重启
logfile 日志文件路径 空(打 stdout) 否
timeout 空闲连接秒数断开 0(不断) 是
tcp-keepalive TCP 保活秒 300 是

2.3 运行时查看与修改(CONFIG 命令)

不用重启、不用改文件,在线看、在线改:

bash 复制代码
# 查看:CONFIG GET 参数名(支持 * 通配)
docker exec redis7 redis-cli CONFIG GET maxmemory
docker exec redis7 redis-cli CONFIG GET maxmemory-policy
text 复制代码
maxmemory
0
maxmemory-policy
noeviction

动态修改(立刻生效):

bash 复制代码
docker exec redis7 redis-cli CONFIG SET maxmemory 104857600
docker exec redis7 redis-cli CONFIG GET maxmemory
text 复制代码
OK
maxmemory
104857600

⚠️ 不是所有参数 CONFIG SET 都完全生效 。比如 appendonly yes 实跑返回 OK(会后台开始写 AOF),但像 port、databases 这类必须重启。改之前查上表或官方文档。

想把这次运行时的改动写回配置文件 ,用 CONFIG REWRITE:

bash 复制代码
docker exec redis7 redis-cli CONFIG REWRITE
text 复制代码
ERR The server is running without a config file

🔴 上面这行报错是预期内 ------官方镜像没挂配置文件,Redis 不知道往哪写。只有当你是"用 redis.conf 启动"的,REWRITE 才有用。别看到报错以为坏了。


三、通用 key 命令:所有数据类型共用的那批

Redis 是个大 key-value 仓库,下面这些命令不管你的 value 是字符串还是集合都能用,是日常用得最多的。

3.1 基本读写与删除

命令 语法 作用 返回
SET SET key value 写 OK
GET GET key 读 值 / 不存在返回空
DEL DEL key [key...] 删 删掉的个数
EXISTS EXISTS key 判断存在 1 存在 / 0 不存在

实跑:

bash 复制代码
docker exec redis7 redis-cli SET name "redis"
docker exec redis7 redis-cli GET name
docker exec redis7 redis-cli SET tmp 1
docker exec redis7 redis-cli EXISTS tmp     # 1
docker exec redis7 redis-cli DEL tmp         # (integer) 1
docker exec redis7 redis-cli EXISTS tmp      # 0
text 复制代码
OK
redis
OK
1
1
0

3.2 过期时间:EXPIRE / TTL / PERSIST

这是 Redis 当缓存的命根子------key 到点自动删。

命令 语法 作用
EXPIRE EXPIRE key seconds 设 N 秒后过期
PEXPIRE PEXPIRE key ms 毫秒版
TTL TTL key 查剩余秒数
PERSIST PERSIST key 取消过期,变成永久

实跑:

bash 复制代码
docker exec redis7 redis-cli SET session:1 "user=alice"
docker exec redis7 redis-cli EXPIRE session:1 60    # 返回 1 表示设置成功
docker exec redis7 redis-cli TTL session:1          # 60
docker exec redis7 redis-cli PERSIST session:1      # 1 表示成功取消
docker exec redis7 redis-cli TTL session:1          # -1
text 复制代码
OK
1
60
1
-1

🔴 TTL 返回值三态 :>0 剩余秒数;-1 永久不过期;-2 key 不存在。写代码时别只判"有没有",要分清 -1 和 -2。

3.3 TYPE:看 key 是什么类型

bash 复制代码
docker exec redis7 redis-cli SET strkey "hello"
docker exec redis7 redis-cli TYPE strkey       # string
docker exec redis7 redis-cli LPUSH listkey a b c
docker exec redis7 redis-cli TYPE listkey      # list
text 复制代码
OK
string
list

⚠️ 对不存在的 key,TYPE 返回 none。

3.4 KEYS vs SCAN:千万别在生产用 KEYS

命令 语法 说明
KEYS KEYS pattern 一把梭返回所有匹配 key,O(N),阻塞
SCAN SCAN cursor [MATCH p] [COUNT n] 增量游标遍历,不阻塞
bash 复制代码
docker exec redis7 redis-cli MSET user:1 "张三" user:2 "李四" user:3 "王五" order:1001 "paid"
docker exec redis7 redis-cli KEYS "user:*"
text 复制代码
user:1
user:2
user:3

⚠️ KEYS * 在生产是事故级命令 。Redis 单线程,库里有几百万 key 时,KEYS 一把全扫,期间整个 Redis 卡死、所有请求超时。线上要遍历一律用 SCAN:

bash 复制代码
docker exec redis7 redis-cli SCAN 0 MATCH "user:*" COUNT 10
text 复制代码
0
user:3
user:2
user:1

SCAN 的返回第一行是下一轮的游标 。这次返回 0 表示遍历完了;如果不是 0,就把这个游标作为下一次 SCAN 的入参接着遍历,直到游标回 0。COUNT 10 是"建议每次扫 10 个",不是"只返回 10 个"的硬限制。

3.5 RENAME、DBSIZE

bash 复制代码
docker exec redis7 redis-cli RENAME strkey strkey_renamed
docker exec redis7 redis-cli GET strkey_renamed    # hello
docker exec redis7 redis-cli DBSIZE                # 当前库 key 总数

⚠️ RENAME 的 newkey 如果已存在,会被静默覆盖,先确认目标名不撞车。

3.6 SELECT 多逻辑库

Redis 自带"数据库分库",默认 16 个(0~15),用 SELECT 切换:

bash 复制代码
docker exec redis7 redis-cli SET dbmark "in-db0"     # 在 db0
docker exec redis7 redis-cli -n 5 SELECT 5
docker exec redis7 redis-cli -n 5 SET mark5 "yes"
docker exec redis7 redis-cli -n 5 GET mark5           # yes
docker exec redis7 redis-cli -n 0 GET dbmark         # in-db0

实跑还试了越界的 16 号库:

bash 复制代码
docker exec redis7 redis-cli -n 16 SELECT 16
text 复制代码
ERR DB index is out of range

⚠️ 三个坑:

  1. 默认就 16 个库,SELECT 16 直接报 DB index is out of range(实跑如上)。
  2. 生产基本不用多库做隔离 ------它不是真正的隔离,一个 RDB/AOF 文件全装下,一个 FLUSHALL 全没。隔离用独立实例。
  3. 🔴 Redis Cluster 模式只允许用 db0,SELECT 别的库直接报错。

3.7 FLUSHDB / FLUSHALL:高危,看着敲

bash 复制代码
FLUSHDB     # 清空当前库
FLUSHALL    # 清空所有库

⚠️ 这俩删数据不可恢复,没有二次确认 。本文只在沙箱容器里演示。生产环境建议直接在配置里 rename-command FLUSHALL "" 把它禁掉,防止手滑。


四、事务:MULTI / EXEC / DISCARD

很多人以为 Redis 事务像 MySQL 那样"要么全成要么全回滚"。不是。 Redis 事务是"把命令打包,一次性顺序执行",它的原子性和你想的不一样。

4.1 正常事务

bash 复制代码
MULTI            # 开事务,之后的命令先入队,不立刻执行
SET a 1
INCR counter
GET counter
EXEC             # 一次性把队列里的命令全执行
text 复制代码
OK
QUEUED
QUEUED
QUEUED
OK
11
11

QUEUED 表示"入队成功,先存着"。EXEC 后才真正执行,返回每步结果(OK、11、11)。

4.2 两种错误:一种全拒,一种不回滚

🔴 Redis 事务不提供回滚,分两种情况:

① 入队时就语法错(命令都不认识)→ EXEC 整体拒绝:

bash 复制代码
MULTI
SET a 1
BADCOMMAND x     # 这命令不存在
EXEC
text 复制代码
OK
QUEUED
ERR unknown command 'BADCOMMAND', with args beginning with: 'x'

EXECABORT Transaction discarded because of previous errors.

② 入队时语法对、运行时才出错 → 不回滚,前面成功的照样生效:

bash 复制代码
SET mykey 5
MULTI
SET mykey "hello"   # 语法对,入队成功
INCR mykey          # 运行时才发现"hello"不是整数,报错
GET mykey
EXEC
text 复制代码
OK
QUEUED
QUEUED
QUEUED
OK                  # SET 真的生效了
ERR value is not an integer or out of range   # INCR 失败
hello               # mykey 被改成了 hello,没有回滚!

⚠️ 看最后一行:SET mykey "hello" 成功了,INCR 失败了,但 SET 没有被回滚。这就是 Redis 事务和关系数据库最大的区别------它只管"命令要么排队要么不排",运行期错误它不负责回滚。想要"出错撤销"得靠 Lua 脚本(后面的篇章讲)。

4.3 DISCARD:放弃事务

bash 复制代码
MULTI
SET x 1
DISCARD        # 不入队了,整个事务取消
EXISTS x       # 0,x 根本没写进去
text 复制代码
OK
QUEUED
OK
0

4.4 WATCH:乐观锁

WATCH key 在事务前盯一个 key。从 WATCH 到 EXEC 之间,只要这个 key 被任何客户端改过,这次 EXEC 就放弃执行(返回 nil),常用于"先读再写"的并发场景。

实跑:A 连接 WATCH stock 后,B 连接把 stock 从 100 改成 50,A 再 MULTI / DECRBY stock 10 / EXEC:

text 复制代码
OK                  # A: WATCH stock
--- B 客户端把 stock 改成 50 ---
OK                  # B: SET stock 50
OK                  # A: MULTI
QUEUED              # A: DECRBY 入队
                    # EXEC 返回空(nil) ------ 事务被放弃
50                  # 最终 GET stock = 50,DECRBY 没执行

🔴 结论:EXEC 返回空 = 监视期间 key 被别人动过,你的"读-改-写"要重试。这就是 Redis 版的乐观锁。


五、发布订阅:PUBLISH / SUBSCRIBE

就是个"广播":一个频道,订阅了的人都能收到消息。

终端 A 订阅:

bash 复制代码
redis-cli SUBSCRIBE news
text 复制代码
subscribe
news
1

终端 B 发布:

bash 复制代码
redis-cli PUBLISH news "hello-redis"
redis-cli PUBLISH news "second message"
text 复制代码
1
1

终端 A 立刻收到:

text 复制代码
message
news
hello-redis
message
news
second message

PUBLISH 返回 1 表示这条消息发给了 1 个订阅者。

⚠️ Pub/Sub 不是消息队列 :消息发出去就完了,不持久化。订阅者中途断线、或者发布时没在线,这条消息就永久丢了,收不到补发。要可靠投递用 List(做简单队列)或专门的 MQ(Kafka/RocketMQ),Redis Stream 才是它家的正经消息流方案(后面篇章讲)。


六、可视化:RedisInsight

命令行看久了眼花,官方有个免费可视化工具 RedisInsight,一眼看清 key、内存、命令曲线:

bash 复制代码
docker run -d --name redisinsight -p 8001:8001 redis/redisinsight:latest

浏览器打开 http://localhost:8001,添加连接填 host=宿主机IP/容器名, port=6379, 密码(如有),就能图形化浏览 key、看内存占用、慢查询。本地调试用它比纯命令行舒服得多。


七、一次跑通:完整实操脚本

把本篇串起来,你可以照这个顺序在容器里过一遍:

bash 复制代码
# 起容器
docker run -d --name redis7 -p 6379:6379 redis:7
docker exec -it redis7 redis-cli

# 进去后依次敲
PING                                  # PONG
SET session:1 "user=alice"            # OK
EXPIRE session:1 60                   # 1
TTL session:1                         # 60
TYPE session:1                        # string
SCAN 0 MATCH "*" COUNT 10             # 增量遍历
MULTI
SET a 1
INCR counter
EXEC                                  # 事务执行
# 另开一个终端:
#   redis-cli SUBSCRIBE news
# 本终端:PUBLISH news "hello"       # 发布
CONFIG GET maxmemory                  # 看配置

能一路敲通、输出和本文对得上,01 就算过关了。


总结:你真正需要记住的 10 件事

  1. 学习用 Docker 起 Redis:docker run -d --name redis7 -p 6379:6379 redis:7,进去 docker exec -it redis7 redis-cli。
  2. 连不上先 PING(PONG)、docker logs、INFO server 看版本端口。
  3. 生产必加密码 --requirepass,客户端用 REDISCLI_AUTH 环境变量别用 -a(密码进进程列表)。
  4. 中文显示成 \x.. 是没加 --raw,交互时带上就好。
  5. 配置三种改法:配置文件启动 / 命令行参数 / CONFIG SET;运行时改了要 CONFIG REWRITE 才持久化。
  6. KEYS * 生产禁用(阻塞),遍历用 SCAN 游标;FLUSHALL/FLUSHDB 高危。
  7. TTL 三态:>0 剩余、-1 永久、-2 不存在。
  8. 多库 SELECT 0~15,Cluster 只许 db0,别拿它做隔离。
  9. Redis 事务 = MULTI 入队 + EXEC 一次性执行,运行期错误不回滚 ;WATCH 是乐观锁,key 被改则 EXEC 放弃。
  10. Pub/Sub 消息不持久化、断线即丢,不是可靠消息队列。

验证清单

  • 能用 Docker 起一个 Redis 7 容器,并 PING 出 PONG
  • 能起一个带密码的实例,并用 REDISCLI_AUTH 免警告连上
  • 会用 INFO server 说出当前 redis 版本和端口
  • 会用 CONFIG GET/SET 在线查看并修改 maxmemory
  • 能完成 SET → EXPIRE → TTL → PERSIST 全流程,并说清 -1/-2 的区别
  • 知道为什么生产不能用 KEYS *,会用 SCAN 遍历
  • 能复现"事务里运行期错误不回滚"(SET 成功、INCR 失败但 SET 不撤销)
  • 能开两个终端演示一次 Pub/Sub,并说清它为什么不是 MQ
  • 能启动 RedisInsight 并连上自己的容器

参考资源


下一篇《【上手】五大数据类型命令逐条实操》:String / List / Hash / Set / ZSet 每条命令配语法→实例→输出→易错点,并用五个真实业务场景(库存扣减、消息队列、用户对象、共同关注、排行榜)把它们串起来跑一遍。

相关推荐
geovindu1 小时前
Pivoting and Unpivoting Data in SQL using postgreSQL 18
大数据·数据库·数据仓库·sql·postgresql·数据库开发·数据库架构
我命由我123451 小时前
6-3.Python 异常处理 - 异常处理进阶(else 块与 finally 块、异常传递、自定义异常)
开发语言·前端·数据库·后端·python·学习·java-ee
深入云栈1 小时前
Netty 4.2.x 源码深度解析 (二十一):Pipeline 事件传播 —— Inbound 与 Outbound 的双向流转
java·后端·架构
Elastic 中国社区官方博客1 小时前
Elastic 重大事件功能如何将 100 条日志样本转化为检测规则
大数据·运维·数据库·人工智能·elasticsearch·搜索引擎
adinnet20261 小时前
持续智能问数:多轮对话状态管理、下钻钻取与经营驾驶舱的演进
javascript·数据库·人工智能
卷无止境1 小时前
长篇写作 Skill 横向盘点:从单文件指令到多智能体流水线
后端·python
斯维赤2 小时前
微信步数的10点定时推送,看似简单,实则暗藏玄机
java·后端
RobinDevNotes2 小时前
crontab 管不住时,该上 Airflow 了
后端
系统集成-鹰翔2 小时前
ERP接口月度统计少了零单月份:SQLite分组与最近三个月均值排查
javascript·数据库·经验分享·后端