目录
- 一,基础概念
- 二,安装部署Redis
- 三,Redis常见命令
- [四、Python 操作 Redis](#四、Python 操作 Redis)
-
- [4.1 Redis 连接方式](#4.1 Redis 连接方式)
-
- [4.1.1 单连接](#4.1.1 单连接)
- [4.1.2 连接池(生产环境首选)](#4.1.2 连接池(生产环境首选))
- [4.2 数据操作](#4.2 数据操作)
-
- [4.2.1 String 字符串](#4.2.1 String 字符串)
- [4.2.2 Hash 哈希](#4.2.2 Hash 哈希)
- [4.2.3 List 列表](#4.2.3 List 列表)
- [4.2.4 Set 集合](#4.2.4 Set 集合)
- [4.2.5 ZSet 有序集合](#4.2.5 ZSet 有序集合)
- [五、Redis 核心高级特性](#五、Redis 核心高级特性)
-
- [5.1 管道 Pipeline(优化批量IO)](#5.1 管道 Pipeline(优化批量IO))
- [5.2 事务 Transaction(保证原子性)](#5.2 事务 Transaction(保证原子性))
一,基础概念
sql与nosql
| 特性 | SQL(关系型数据库) | NoSQL(非关系型数据库) |
|---|---|---|
| 数据结构 | 结构化 (Structured) | 非结构化 |
| 数据关联 | 关联的 (Relational) | 无关联的 |
| 查询方式 | SQL查询 | 非SQL |
| 事务特性 | ACID | BASE |
- 关系型数据库要求预先定义严格的表结构(Schema),如字段类型、长度等,插入的数据必要按照预定义的格式;而NoSQL则非常灵活,可以存储键值对、文档、图等不同形态的数据,且插入数据没有严格的约束。
- ACID强调事务的强一致性,而BASE则追求高可用性和最终一致性,更适合大规模分布式系统
redis特征
redis是基于内存存储的高性能nosql数据库,其核心特性如下:
- 丰富的键值类型:Value不仅仅是字符串,还支持多种数据结构。
- 单线程与原子性:所有命令在一个线程中顺序执行,确保了单个命令的原子性。
- 极致性能:基于内存操作、I/O多路复用和高效编码,延迟极低
- 持久化支持:可以将内存中的数据异步保存到磁盘,防止数据丢失
- 高可用与扩展:支持主从复制、分片集群,满足高并发场景。
二,安装部署Redis
我是在centos7通过docker部署的redis,当然你也可以用原生方式部署,本篇博客讲解的docker部署是基于熟悉docker的朋友,对新手不是很友好,对docker不熟悉的朋友可以看下我的讲解docker的博客或者其他方式部署Redis。
-
拉取镜像,我这里用的是6.2.6版本,需要其他版本,直接指定版本号即可。
```bash docker pull redis:6.2.6 ``` -
如果docker配置的镜像源、镜像加速器等配置失效,镜像拉取不下来,直接在这个网站上拉取docker国内镜像源,找到指定版本,拉倒最下面,有相应的拉取命令,直接执行即可。

-
创建data和config宿主机数据卷目录,在config目录中创建redis.conf配置文件,在配置文件中按需配置,一个比较常用的配置内容如下:
bashbind 0.0.0.0 # 保护模式,如果设置了密码和绑定,可以关闭。但建议保持开启,并确保设置了密码。 protected-mode no # 服务端口 port 6379 # 设置访问密码,请修改为你的强密码 requirepass zcdjhzcl # 设置最大内存限制 maxmemory 256mb # 设置内存淘汰策略 maxmemory-policy allkeys-lru # 启用 AOF 持久化 appendonly yes # AOF 文件名称 appendfilename "appendonly.aof" # 其他可选配置 # 设置日志级别 loglevel notice # 设置日志文件路径(在容器内) logfile "/data/redis-server.log" # 设置数据库数量 databases 4 -
docker run 启动Redis应用,需要注意你的数据卷位置不要出错,最后
redis-server /etc/redis/redis.conf会覆盖Redis镜像中的应用启动命令。bashdocker run -d \ --name my-redis \ -p 6379:6379 \ -v /path/on/your/host/redis.conf:/etc/redis/redis.conf \ -v /path/on/your/host/data:/data \ redis:6.2.7 \ redis-server /etc/redis/redis.conf -
通过
docker logs -f my-redis查看Redis启动日志,后续Redis的运行日志可以在配置的数据卷目录data目录中的redis-server.log文件查看 -
部署完成之后,Redis默认会安装命令行客户端工具
redis-cli,我们可以通过docker exec -it my-redis bash进入redis容器内部,然后通过redis-cli -h hostname -p port -a password指定端口、密码连接本地redis
三,Redis常见命令
Redis数据结构介绍
-
Redis是Key-Value数据库,Key通常是字符串,而Value则支持多种数据类型,这也是Redis强大功能的基石:
数据结构 形式示例 说明 String(字符串) "hello world"Redis最基本的数据类型,二进制安全,可以存储字符串、整数或浮点数,一个key对应一个value Hash(哈希) {name: "Jack", age: 21}键值对集合,适合存储对象信息。每个Hash可以存储大量的字段和值 List(列表) [A -> B -> C]有序的字符串列表,按照插入顺序排序。支持从头部或尾部添加/移除元素,底层是双向链表实现 Set(集合) {A, B, C}无序的、唯一元素的字符串集合。通过哈希表实现,支持高效的添加、删除和查找操作,以及交集、并集等集合运算 Sorted Set(有序集合) {A:1, B:2, C:3}有序的、唯一元素的集合。每个元素都关联一个分数(score),Redis根据分数为元素进行从小到大的排序 -
在Redis客户端中,可以使用help @的命令来查看不同分组下的命令,例如help @string。
通用命令
这些命令不针对特定数据类型,是所有Key都可以使用的:
| 命令 | 语法 | 描述 | 注意事项 |
|---|---|---|---|
| KEYS | KEYS pattern |
查找所有符合给定模式pattern的key | 生产环境慎用,可能阻塞服务 |
| DEL | DEL key |
删除一个指定的key | 可以同时删除多个key:DEL key1 key2 key3 |
| EXISTS | EXISTS key |
判断某个key是否存在 | 返回1表示存在,0表示不存在 |
| EXPIRE | EXPIRE key seconds |
为key设置过期时间,到期自动删除 | 时间单位为秒,设置成功返回1,失败返回0 |
| TTL | TTL key |
查看key的剩余生存时间 | 返回剩余秒数,-1表示永不过期,-2表示key不存在 |
String类型
String是最简单的类型,但也可以是整数或浮点数。
| 命令 | 语法 | 描述 | 返回值 | 示例 |
|---|---|---|---|---|
| SET | SET key value |
设置指定key的值 | OK(成功时) | SET username "john" |
| GET | GET key |
获取指定key的值 | key的值(存在时)或nil(不存在时) | GET username → "john" |
| MSET | MSET k1 v1 k2 v2 ... |
批量设置多个key-value对 | OK | MSET k1 v1 k2 v2 k3 v3 |
| MGET | MGET k1 k2 ... |
批量获取多个key的值 | 值列表 | MGET k1 k2 → "v1", "v2" |
| INCR | INCR key |
将key中储存的数字值增一 | 递增后的值 | INCR counter → 1 |
| INCRBY | INCRBY key increment |
为key的值增加指定的整数值 | 增加后的值 | INCRBY counter 5 → 6 |
| SETNX | SETNX key value |
仅当key不存在时设置值 | 1(设置成功)或0(未设置) | SETNX lock 1 → 1 |
| SETEX | SETEX key seconds value |
设置值并指定过期时间(秒) | OK | SETEX session 3600 "data" |
Hash类型
适合存储对象,可以将对象的每个字段独立存储和修改,value也是键值对的格式
| 命令 | 语法 | 描述 | 返回值 | 示例 |
|---|---|---|---|---|
| HSET | HSET key field value |
设置哈希表字段值 | 1(新字段)或0(更新字段) | HSET user:1 name "John" |
| HGET | HGET key field |
获取哈希表字段值 | 字段值或nil | HGET user:1 name → "John" |
| HMSET | HMSET key f1 v1 f2 v2 ... |
批量设置多个字段值 | OK | HMSET user:1 name "John" age 30 |
| HMGET | HMGET key f1 f2 ... |
批量获取多个字段值 | 值列表 | HMGET user:1 name age → "John", "30" |
| HGETALL | HGETALL key |
获取所有字段和值 | 字段值交替的列表 | HGETALL user:1 → "name", "John", "age", "30" |
| HKEYS | HKEYS key |
获取所有字段名 | 字段名列表 | HKEYS user:1 → "name", "age" |
| HINCRBY | HINCRBY key field increment |
为哈希表字段的整数值加上增量 | 增加后的值 | HINCRBY user:1 age 1 → 31 |
List类型
一个有序、元素可重复的双向链表。可以从队头队尾双向插入获取数据,常用来做异步队列、朋友圈点赞列表等。

| 命令 | 语法 | 描述 | 返回值 | 示例 |
|---|---|---|---|---|
| LPUSH | LPUSH key element |
从列表左侧插入一个或多个元素 | 插入后列表长度 | LPUSH queue task1 → 1 |
| LPOP | LPOP key |
从列表左侧弹出并返回一个元素 | 弹出的元素或nil | LPOP queue → "task1" |
| RPUSH | RPUSH key element |
从列表右侧插入一个或多个元素 | 插入后列表长度 | RPUSH queue task2 → 1 |
| RPOP | RPOP key |
从列表右侧弹出并返回一个元素 | 弹出的元素或nil | RPOP queue → "task2" |
| LRANGE | LRANGE key start end |
获取指定索引范围内的元素 | 元素列表 | LRANGE queue 0 -1 → "task1", "task2" |
| BLPOP | BLPOP key timeout |
阻塞式左弹出,列表为空时等待 | 弹出元素信息或nil(超时) | BLPOP queue 10 → "queue", "task1" |
- 栈:同进同出,使用LPUSH和LPOP(或RPUSH和RPOP)。
- 队列:先进先出,使用LPUSH和RPOP。
- 阻塞队列:使用LPUSH和BRPOP。
Set类型
无序、元素不可重复的集合,支持交集、并集、差集等操作,适合标签、共同好友等场景。
| 命令 | 语法 | 描述 | 返回值 | 示例 |
|---|---|---|---|---|
| SADD | SADD key member |
向集合添加一个或多个元素 | 成功添加的元素数量 | SADD tags "redis" "db" → 2 |
| SREM | SREM key member |
从集合删除一个或多个元素 | 成功删除的元素数量 | SREM tags "db" → 1 |
| SCARD | SCARD key |
获取集合的元素个数 | 集合基数(元素数量) | SCARD tags → 1 |
| SISMEMBER | SISMEMBER key member |
判断元素是否在集合中 | 1(存在)或0(不存在) | SISMEMBER tags "redis" → 1 |
| SMEMBERS | SMEMBERS key |
获取集合所有元素 | 元素列表 | SMEMBERS tags → "redis" |
| SINTER | SINTER key1 key2 |
求多个集合的交集 | 交集元素列表 | SINTER set1 set2 → "common" |
| SDIFF | SDIFF key1 key2 |
求多个集合的差集 | 差集元素列表 | SDIFF set1 set2 → "set1_only" |
| SUNION | SUNION key1 key2 |
求多个集合的并集 | 并集元素列表 | SUNION set1 set2 → "a","b","c" |
SortedSet类型(ZSet)
- 在Set的基础上,为每个元素关联一个分数(score),从而实现排序。底层由跳表实现,查询性能高。是实现排行榜功能的理想选择。
- 注意:所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可
| 命令 | 语法 | 描述 | 返回值 | 示例 |
|---|---|---|---|---|
| ZADD | ZADD key score member |
向有序集合添加元素 | 成功添加的元素数量 | ZADD ranking 95 "Alice" → 1 |
| ZREM | ZREM key member |
从有序集合删除元素 | 成功删除的元素数量 | ZREM ranking "Alice" → 1 |
| ZSCORE | ZSCORE key member |
获取元素的分数值 | 分数值或nil | ZSCORE ranking "Alice" → "95" |
| ZRANK | ZRANK key member |
获取元素升序排名(从0开始) | 排名或nil | ZRANK ranking "Alice" → 0 |
| ZREVRANK | ZREVRANK key member |
获取元素降序排名(从0开始) | 排名或nil | ZREVRANK ranking "Alice" → 2 |
| ZCARD | ZCARD key |
获取有序集合元素数量 | 元素总数 | ZCARD ranking → 3 |
| ZRANGE | ZRANGE key start end |
按分数升序获取指定排名范围的元素 | 元素列表 | ZRANGE ranking 0 -1 → "Alice", "Bob", "Charlie" |
| ZREVRANGE | ZREVRANGE key start end |
按分数降序获取指定排名范围的元素 | 元素列表 | ZREVRANGE ranking 0 -1 → "Charlie", "Bob", "Alice" |
| ZRANGEBYSCORE | ZRANGEBYSCORE key min max |
获取指定分数范围内的元素 | 元素列表 | ZRANGEBYSCORE ranking 90 100 → "Alice" |
四、Python 操作 Redis
本章基于主流 redis-py 4.x 版本,讲解Python操作Redis的核心用法,适配日常开发场景,代码简洁可直接运行。
4.1 Redis 连接方式
Redis基于TCP长连接通信,分为创建单连接、连接池两种用法,生产环境必须使用连接池复用连接,避免性能损耗。
4.1.1 单连接
适合本地调试,核心参数 decode_responses=True 自动将bytes转为字符串,规避编码问题。
python
import redis
# 初始化Redis连接
r = redis.Redis(
host="127.0.0.1",
port=6379,
db=0,
password="zcdjhzcl", # 对应自己的Redis密码
decode_responses=True, # 自动解码,解决bytes返回值问题
socket_timeout=5
)
# 连通性测试
print(r.ping()) # 返回True即连接成功
4.1.2 连接池(生产环境首选)
全局单例连接池,项目初始化创建一次,所有业务复用,大幅优化网络IO性能。
python
import redis
# 全局创建连接池(项目启动执行一次)
redis_pool = redis.ConnectionPool(
host="127.0.0.1",
port=6379,
db=0,
password="zcdjhzcl",
decode_responses=True,
max_connections=20, # 最大连接数
socket_timeout=5
)
# 全局复用连接
redis_client = redis.Redis(connection_pool=redis_pool)
4.2 数据操作
结合前文Redis原生命令,对应Python实现五大核心数据类型的增删改查,完全匹配业务常用场景。
4.2.1 String 字符串
常用于缓存、计数器、验证码、配置存储,支持批量操作与原子自增。
python
# 基础增删查
redis_client.set("username", "zhangsan")
print(redis_client.get("username"))
# 带过期时间设置(60秒过期,验证码常用)
redis_client.setex("code:1001", 60, "886688")
# 不存在则设置(分布式锁核心)
redis_client.setnx("lock:demo", "1")
# 批量操作
redis_client.mset({"k1": "v1", "k2": "v2"})
print(redis_client.mget(["k1", "k2"]))
# 计数器自增
redis_client.incr("read_count")
redis_client.incrby("read_count", 5)
4.2.2 Hash 哈希
专为结构化对象设计,适合存储用户、商品信息,无需序列化,支持单字段修改。
python
# 存储用户对象
redis_client.hset("user:1001", mapping={"name": "张三", "age": 20, "gender": "男"})
# 单字段/全量查询
print(redis_client.hget("user:1001", "name"))
print(redis_client.hgetall("user:1001"))
# 批量获取字段
print(redis_client.hmget("user:1001", ["name", "age"]))
# 字段自增
redis_client.hincrby("user:1001", "age", 1)
4.2.3 List 列表
有序可重复,基于双向链表,适合实现队列、栈、消息等待队列。
python
# 左右插入数据
redis_client.lpush("msg_queue", "msg1", "msg2")
redis_client.rpush("msg_queue", "msg3")
# 查询全部数据
print(redis_client.lrange("msg_queue", 0, -1))
# 弹出数据
redis_client.lpop("msg_queue")
redis_client.rpop("msg_queue")
# 阻塞弹出(简易消息队列,无数据等待10秒)
redis_client.blpop("msg_queue", timeout=10)
4.2.4 Set 集合
无序去重,支持集合运算,适用于点赞、好友列表、数据去重统计。
python
# 添加元素(自动去重)
redis_client.sadd("like:article:100", "user1", "user2", "user1")
# 查询所有元素
print(redis_client.smembers("like:article:100"))
# 判断元素是否存在
print(redis_client.sismember("like:article:100", "user1"))
# 集合运算
redis_client.sadd("set_a", 1, 2, 3)
redis_client.sadd("set_b", 2, 3, 4)
print(redis_client.sinter("set_a", "set_b")) # 交集
print(redis_client.sunion("set_a", "set_b")) # 并集
print(redis_client.sdiff("set_a", "set_b")) # 差集
4.2.5 ZSet 有序集合
唯一有序,通过score分值排序,是实现排行榜、权重排序的最优结构。
python
# 添加排行榜数据
redis_client.zadd("rank:score", {"小明": 95, "小红": 98, "小刚": 88})
# 升序、降序查询
print(redis_client.zrange("rank:score", 0, -1, withscores=True))
print(redis_client.zrevrange("rank:score", 0, -1, withscores=True))
# 查询排名、分值
print(redis_client.zscore("rank:score", "小红"))
print(redis_client.zrevrank("rank:score", "小红"))
# 删除元素
redis_client.zrem("rank:score", "小刚")
五、Redis 核心高级特性
仅保留开发高频必备的管道、事务两大核心特性,是批量操作、原子操作的关键能力。
5.1 管道 Pipeline(优化批量IO)
Redis每条命令都会产生网络往返,管道可将多条命令打包一次性发送,大幅提升批量操作性能。管道仅优化网络,不保证原子性。
python
# 上下文写法(自动释放资源,推荐)
with redis_client.pipeline(transaction=False) as pipe:
pipe.set("p1", "v1")
pipe.set("p2", "v2")
pipe.incr("batch_count")
pipe.execute() # 批量执行所有命令
5.2 事务 Transaction(保证原子性)
Redis事务可保证一组命令全部执行或全部不执行,满足数据原子性需求。注意:Redis事务不支持运行时回滚,仅语法错误会整体失效。
python
with redis_client.pipeline(transaction=True) as pipe:
pipe.set("tx_key1", "value1")
pipe.set("tx_key2", "value2")
pipe.execute() # 提交事务
# 取消事务示例
with redis_client.pipeline(transaction=True) as pipe:
pipe.set("temp_key", "123")
pipe.discard() # 放弃事务,命令不执行