Redis相关方法与使用

一、常规存取值

python 复制代码
import redis

# 方法1:直接连接
r = redis.Redis(
    host='localhost',
    port=6379,
    db=0,
    password=None,
    decode_responses=True  # 自动解码为字符串
)

# 方法2:使用连接池
pool = redis.ConnectionPool(
    host='localhost',
    port=6379,
    db=0,
    max_connections=10
)
r = redis.Redis(connection_pool=pool)

# 测试连接
print(r.ping())  # 返回 True 表示连接成功


# 设置键值
r.set('name', '张三')
r.set('age', 25)
r.set('score', 95.5)

# 设置带过期时间的键(秒)
r.setex('temp_key', 60, 'value')  # 60秒后过期

# 设置带过期时间的键(毫秒)
r.psetex('temp_key_ms', 60000, 'value')

# 如果键不存在则设置
r.setnx('unique_key', 'value')  # 只有键不存在时才会设置

# 批量设置
r.mset({'key1': 'value1', 'key2': 'value2'})

# 获取值
name = r.get('name')  # 返回 b'张三' 或 '张三'(取决于decode_responses)
age = r.get('age')
print(name, age)

# 批量获取
values = r.mget(['key1', 'key2'])
print(values)

# 获取并设置新值
old_value = r.getset('name', '李四')
print(f'旧值: {old_value}, 新值: {r.get("name")}')

二、简单分布式锁

python 复制代码
impirt redis

# 使用连接池
pool = redis.ConnectionPool(
    host='localhost',
    port=6379,
    db=0,
    max_connections=10
)
redis_client = redis.Redis(connection_pool=pool)


class RedisLock:
    """Redis 分布式锁"""

    def __init__(self, redis_client):
        self.redis = redis_client

    def acquire(self, key: str, ttl: int = 900):
        token = str(uuid.uuid4())
        ok = self.redis.set(key, token, nx=True, ex=ttl)
        return token if ok else None

    def release(self, key: str, token: str) -> None:
        lua = """
        if redis.call("get", KEYS[1]) == ARGV[1] then
            return redis.call("del", KEYS[1])
        else
            return 0
        end
        """
        self.redis.eval(lua, 1, key, token)


# 使用案例
redis_lock = RedisLock(redis_client)

# 占锁
lock_key = f'lock:xxxx'
lock = redis_lock.acquire(lock, ttl)
if not lock:
    print('占锁失败')

# 释放锁
redis_lock.release(key, lock)

三、案例

python 复制代码
import redis
import json
import time

class RedisCache:
    def __init__(self):
        self.redis_client = redis.Redis(
            host='localhost',
            port=6379,
            db=0,
            decode_responses=True
        )
    
    def set_json(self, key, data, expire=None):
        """存储JSON数据"""
        json_str = json.dumps(data, ensure_ascii=False)
        if expire:
            self.redis_client.setex(key, expire, json_str)
        else:
            self.redis_client.set(key, json_str)
    
    def get_json(self, key):
        """获取JSON数据"""
        data = self.redis_client.get(key)
        if data:
            return json.loads(data)
        return None
    
    def cache_with_ttl(self, key, func, ttl=300):
        """带过期时间的缓存装饰器"""
        cached = self.get_json(key)
        if cached is not None:
            return cached
        
        result = func()
        self.set_json(key, result, ttl)
        return result

class RateLimiter:
    """限流器"""
    def __init__(self, redis_client, max_requests, time_window):
        self.redis = redis_client
        self.max_requests = max_requests
        self.time_window = time_window
    
    def is_allowed(self, user_id):
        """检查用户是否允许访问"""
        key = f"rate_limit:{user_id}"
        current = self.redis.get(key)
        
        if current is None:
            # 第一次访问
            self.redis.setex(key, self.time_window, 1)
            return True
        
        current = int(current)
        if current < self.max_requests:
            # 增加计数
            self.redis.incr(key)
            return True
        else:
            return False
相关推荐
用户3169353811832 天前
Java连接Redis
redis
小小工匠4 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
taocarts_bidfans4 天前
反向海淘跨境缓存架构优化:taocarts Redis分层缓存实战技术
redis·缓存·架构·反向海淘·taocarts
炘爚4 天前
Linux——Redis
数据库·redis·缓存
csjane10794 天前
Redisson 限流原理
java·redis
ThanksGive4 天前
Go 服务里的 Redis 锁惊群问题:一次本地合流优化实践
redis
小挪号底迪滴4 天前
Redis 和 MySQL 数据不一致怎么办?缓存更新策略实战
redis·mysql·缓存
闪电悠米5 天前
黑马点评-Redis ZSet-实现关注 Feed 流
服务器·网络·数据库·redis·缓存·junit·lua
Devin~Y5 天前
大厂 Java 面试实录:从音视频内容社区到 AI RAG 的全链路技术设计
java·spring boot·redis·spring cloud·微服务·kafka·音视频