一、redis概述
适用于高性能、并发处理场景下,作为缓存使用,一般不用来做永久存储
1、什么是 Redis
Redis(Remote Dictionary Server)是一个开源的、基于内存的键值对存储数据库,它可以用作数据库、缓存和消息中间件
2、Redis 的特点
基于内存运行:数据主要存储在内存中,读写性能极高
支持数据持久化:可以将内存中的数据保存到磁盘,重启后可以再次加载使用
丰富的数据类型:支持字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等
支持事务:操作都是原子性,要么全部执行,要么全部不执行
丰富的特性:支持发布/订阅、键过期等特性
3、Redis 的应用场景
缓存系统:减轻数据库压力,提升系统性能
计数器:如网站访问量、点赞数等
消息队列:利用列表类型实现简单的消息队列
排行榜:利用有序集合实现各种排行榜功能
会话存储:存储用户会话信息
二、Redis 软件安装
安装
方法一:使用小皮工具(推荐)

方法二:使用官方版本
访问 Redis 官网下载 Windows 版本
解压到指定目录,如 C:\redis
打开命令提示符,进入 Redis 目录
运行命令:redis-server.exe redis.windows.conf
验证安装
安装完成后,可以通过以下命令测试 Redis 是否正常工作:
bash
# 连接 Redis 客户端
redis-cli
# 在 Redis 客户端中测试
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set test "Hello Redis"
OK
127.0.0.1:6379> get test
"Hello Redis"
127.0.0.1:6379> exit
在pycharm创建DataSource------查看redis中数据



三、redis-py 模块使用
1、安装redis模块
使用 pip 安装
pip install redis #下载redis模块
安装windows 或 linux redis
使用 conda 安装
conda install redis-py
验证安装
import redis
print(redis.__version__)
# 查看是否有结果,有结果则正常
【重点】2、连接 Redis 数据库
python
import redis
# 创建 Redis 连接对象
r = redis.Redis(
host='localhost', # Redis 服务器地址
port=6379, # Redis 服务器端口
db=0, # 数据库编号,默认0
password=None, # 密码,如果没有设置密码则为None
decode_responses=True # 自动解码,返回字符串而不是字节
)
# 测试连接
try:
response = r.ping()
print("Redis 连接成功:", response)
except redis.ConnectionError as e:
print("Redis 连接失败:", e)
3、字符串(String)操作
【重点】a、设置和获取值
python
import redis
r = redis.Redis(
host="127.0.0.1",
port=6379,
db=0,
password="123456",
decode_responses=True
)
# 添加单个数据
r.set('username','LiMing')
# 获取单个数据
print(r.get('username'))
# 添加多个数据,set添加的数据是一个个分开的
r.mset({'age': 27, 'address': 'shunyi', 'height': 175})
# 获取多个数据
print(r.mget(['username', 'age', 'address']))
# 添加三个数据,并设置过期时间
r.setex('verification', 10, '6749') # 10s后自动删除
【重点】b、存储复杂数据,字典等
字典->json->存储redis->get_json->字典
json.dumps(数据) #将数据转换为json格式字符串
json.loads(数据) #将json格式数据转换为字典
python
import redis,json
r = redis.Redis(
host="127.0.0.1",
port=6379,
db=0,
password="123456",
decode_responses=True
)
product_info = {"pname": "basketball", "price": 89, "brand": "LiNing"}
product_json = json.dumps(product_info)
print(product_json,type(product_json))
r.set("product1",product_json)
get_product = r.get("product1")
result_product = json.loads(get_product)
print(result_product,type(result_product))
c、数值操作
python
import redis
r = redis.Redis(
host="127.0.0.1",
port=6379,
password="123456",
db=0,
decode_responses=True
)
r.set("count",0)
# 自增
r.incr('count')
print(f'The result after self augmentation is {r.get('count')}')
# 加上5
r.incrby('count',5)
print(f'The result after addition is {r.get('count')}')
# 自减
r.decr('count')
print(f'The result after self reduction is {r.get('count')}')
# 减去3
r.decrby('count',3)
print(f'The result after subtraction is {r.get('count')}')
4、哈希(Hash)------ 字典 操作
数据类型:Redis Hash = key 里面套一个小字典
对应 Python 的 dict
专门存对象 / 结构化数据
常用命令:hset / hget / hgetall
为什么要用 Redis Hash?
适合存一个对象的多个属性,例如:用户信息、商品详情、配置项、订单信息等
优点:
结构清晰,一个 key 存一整个对象
节省内存,比分开存多个 string 高效
可以单独修改某个字段,不用重写整个数据
常见用法
python
import redis
r = redis.Redis(
host='127.0.0.1',
port=6379,
password="123456",
db=0,
decode_responses=True
)
# 一次添加一个元素
r.hset('user:01', 'name', 'Jerry')
r.hset('user:01', 'age', 6 )
r.hset('user:01', 'gender', 'male')
# get一个元素
print(r.hget('user:01', 'name'))
# get多个元素
print(r.hgetall('user:01'))
# 一次添加多个元素
r.hmset('user:02', {'name': 'Tom', 'age': '5', 'gender': 'male'})
# 一次得到多个元素
print(r.hmget('user:02',['name','age']))
print(r.hgetall('user:02'))
# 获取所有字段名
print(r.hkeys('user:02'))
# 获取所有字段值
print(r.hvals('user:02'))
# 删除字段
r.hdel('user:01','gender')
# 输出删除之后的值
print(r.hgetall('user:01'))
# 输出
'''
Jerry
{'name': 'Jerry', 'age': '6', 'gender': 'male'}
['Tom', '5']
{'name': 'Tom', 'age': '5', 'gender': 'male'}
['name', 'age', 'gender']
['Tom', '5', 'male']
{'name': 'Jerry', 'age': '6'}
'''
5、列表(List)操作
常见用法
python
import redis
r = redis.Redis(
host='127.0.0.1',
port=6379,
password="123456",
db=0,
decode_responses=True
)
r.lpush('tasks', 'thread1', 'thread2', 'thread3')
r.rpush('tasks', 'thread4', 'thread5')
# 根据索引输出所有元素
print(r.lrange('tasks', 0, -1))
# 输出长度
print(r.llen('tasks'))
# 输出指定范围元素索引[1,3]
print(r.lrange('tasks', 1, 3))
# 从左侧删除元素
r.lpop('tasks')
# 输出删除后结果
print(r.lrange('tasks', 0, -1))
# 从右侧删除元素
r.rpop('tasks')
print(r.lrange('tasks', 0, -1))
6、集合(Set)操作
常见用法
python
import redis
r = redis.Redis(
host='127.0.0.1',
port=6379,
password="123456",
db=0,
decode_responses=True
)
# 添加元素
r.sadd('tags', 'python', 'java', 'html', 'php', 'c++')
# 获取所有元素
print(f'output all members:{r.smembers('tags')}')
# 元素是否存在
print(r.sismember('tags','python'))
# 获取集合元素数量
print(f'The set number is:{r.scard('tags')}')
# 随机删除元素
r.spop('tags')
print(f'The number after delete is :{r.smembers('tags')}')
# 删除指定元素
r.srem('tags','c++')
print(f'The number after delete is :{r.smembers('tags')}')
7、有序集合(Sorted Set)操作
python
import redis
r = redis.Redis(
host="127.0.0.1",
port=6379,
password="123456",
db=0,
decode_responses=True
)
r.zadd('play_score',{
"user1":1000,
"user2":500,
"user3":1500,
"user4":2000,
"user5":3100,
})
# 按分数进行升序排序
print(r.zrange('play_score', 0, -1))
# 按分数进行降序排列,默认为升序
print(r.zrange('play_score', 0, -1, desc=True))
# 获取指定元素
print(r.zscore('play_score', 'user1'))
# 增加元素分数
r.zincrby('play_score', 500, 'user4')
print(r.zscore('play_score', 'user4'))
# 获取排名
rank = r.zrevrank('play_score','user4')
print(f'user4`s ranking is {rank+1}')
# 按分数范围获取
print(r.zrangebyscore('play_score', 1000, 2000))
【重点】8、键操作和过期时间
r.expire('key',过期时间) #设置过期时间
r.ttl('key') #获取键的过期时间
r.persist('key') #设置键的过期时间为永久
r.setex('key',过期时间,'value') # 添加键并设置过期时间
r.key('字符串*') #输出like 字符串* 的所有key
r.delete('key') #删除指定key
python
import redis,json
r = redis.Redis(
host="127.0.0.1",
port=6379,
password="123456",
db=0,
decode_responses=True
)
# 增加键值对
user_data = {'name': 'Jerry', 'age': 8, 'gender': 'male'}
user_data_j = json.dumps(user_data)
r.set('user1', user_data_j)
temp_res = r.get('user1')
print(json.loads(temp_res))
# 检查件是否存在
print(r.exists('user1'))
# 设置过期时间,100s
r.expire('user1',100)
# 过期剩余时间------time to live
print(f'time to live:{r.ttl('user1')}')
# 取消过期时间、设为永久
r.persist('user1')
print(f'time to live:{r.ttl('user1')}')
# 增加键值对、并设置过期时间
r.setex('user2',30,'Tom')
print(f'time to live:{r.ttl('user2')}')
# 查找匹配模式的键
print(r.keys('*'))
print(f'The key like user*:{r.keys('user*')}')
# 删除指定键
r.delete('paly_score')
# 输出删除后的所有键
print(r.keys('*'))
总结
命令总结:
字符串:r.+set+
哈希:r.h*
列表:r.l* 从左边处理 ,r.r* 从左边处理
集合:r.s*
有序集合: r.z*
四、实战案例:简单的缓存系统
python
import redis,json,time
class RedisCache(object):
# 初始化连接池(程序启动时调用一次)
def __init__(self,host="localhost",port=6379,password=None,db=0):
self.redis_client = redis.Redis(
host = host,
port = port,
password = password,
db = db,
decode_responses=True
)
# 添加key
def add_key(self,key,value,expire_time=3600):
try:
value_json = json.dumps(value)
self.redis_client.setex(key,expire_time,value_json)
return True
except Exception as e:
print(f"Fail to add,{e}")
return False
# 获取key
def get_key(self,key):
try:
value_json = self.redis_client.get(key)
# print(value_json)
if value_json:
value_result = json.loads(value_json)
return value_result
else:
return None
except Exception as e:
print(f"Fail to get key,{e}")
return False
# 删除key
def del_key(self, key):
try:
self.redis_client.delete(key)
return True
except Exception as e:
print(f"Fail to delete,{e}")
return False
# 判断key是否存在
def isexist(self,key):
try:
self.redis_client.exists(key)
return True
except Exception as e:
print(f"Fail to check,{e}")
return False
# 清空缓存
def clear_all_cache(self):
try:
self.redis_client.flushdb()
return True
except Exception as e:
print(f"Fail to chear all,{e}")
return False
if __name__ == '__main__':
cache = RedisCache(host="127.0.0.1", password="123456")
data = {"name":"Tom", "age":6, "gender":"male"}
cache.add_key(key="user_tom",value=data,expire_time=60)
print(cache.get_key(key="user_tom"))
# 模拟耗时较长操作
def expensive_opr(x):
time.sleep(2)
return x*x
# 调用耗时较长操作
def get_square_cache(x):
cache_key = f"square:{x}"
result = cache.get_key(key=cache_key)
if result:
return result
else:
value_result = expensive_opr(x)
cache.add_key(key=cache_key,value=value_result,expire_time=600)
result = cache.get_key(key=cache_key)
return result
# 第一次运行,没有缓存
start_time = time.time()
print(get_square_cache(7))
print(f"First,spent time:{time.time() - start_time}")
# 第二次运行,有缓存
start_time = time.time()
print(get_square_cache(7))
print(f"Second,spent time:{time.time() - start_time}")
五、最佳实践建议
键名规范 :使用冒号分隔命名空间,如 user:1001:name,便于管理和查看。
设置过期时间 :作为缓存使用时,务必设置过期时间,防止内存无限增长。
避免大 Key :不要在一个 Key 中存储过大的数据(如超过 10KB 的 String 或包含百万元素的 List),这会阻塞 Redis 单线程。
连接管理 :Web 应用中应全局复用连接池,不要在每个请求中重新创建连接。
异常处理:网络波动可能导致连接中断,代码中应包含适当的重试或异常捕获机制。