python-redis访问指南_开发语言

Redis(Remote Dictionary Server)是一种开源的内存数据结构存储,可用作数据库、缓存和消息代理。它功能强大且灵活,可根据需求调整架构和配置,以高性能、简单易用、支持多种数据结构而闻名,广泛应用于各种场景,包括实时数据处理、会话存储和分布式应用等。

一、Redis 的特点

高性能Redis 将数据存储在内存中,读写速度极快,适合实时应用场景。每秒读写操作数可以达到数十万。

丰富的数据结构支持多种数据结构,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。

持久化支持提供 RDB 快照和 AOF(Append-Only File)两种持久化方式,数据即使断电也可以恢复。

简单易用提供简单的命令集,易于学习和使用。并支持多种编程语言的客户端。

多种功能支持事务、Lua 脚本、发布/订阅、主从复制和分布式部署。

分布式特性提供 Redis Cluster 模式,可支持大规模、高可用的分布式集群。

二、Redis 的应用场景

缓存:存储热点数据以减少数据库压力,提高响应速度。

会话存储:用于存储用户会话信息,例如电商网站购物车数据。

分布式锁:使用 Redis 的原子操作实现分布式锁。

实时数据分析:高性能处理实时数据流,例如在线计数器、排行榜等。

消息队列:利用 Redis 的列表或发布/订阅功能实现生产者消费者模型。

计数器:通过自增功能实现精准计数,如视频播放量统计。

三、Redis 支持的数据结构

3.1 字符串(String)

最基本的数据类型,可存储字符串、数字等。

示例命令:

    SET key value

    GET key

    INCR key

用途:缓存对象、计数器、会话数据。 

3.2 哈希(Hash)

存储键值对的集合,类似 Python 的字典。

示例命令:

    HSET user:1 name "Alice"

    HGET user:1 name

    HGETALL user:1

用途:存储用户信息、配置数据等。

3.3 列表(List)

有序的字符串集合,可用于队列或栈。

示例命令:

    LPUSH mylist "item1"

    RPUSH mylist "item2"

    LPOP mylist

用途:消息队列、任务队列。

3.4 集合(Set)

无序的字符串集合,自动去重。

示例命令:

    SADD myset "item1"

    SADD myset "item2"

    SMEMBERS myset

用途:社交网络中的好友推荐、去重功能。

3.5 有序集合(Sorted Set)

类似集合,但每个成员有一个分数,用于排序。

示例命令:

    ZADD leaderboard 100 "Alice"

    ZADD leaderboard 200 "Bob"

    ZRANGE leaderboard 0 -1 WITHSCORES

用途:排行榜、任务调度。

3.6 位图(Bitmap)

用于高效地存储和操作二进制数据。

3.7 HyperLogLog

用于估算基数(不重复元素的数量),占用内存极小。

四、Redis 的持久化方式

4.1 RDB(Redis Database File)

  1. 定期将内存数据保存为快照。
  2. 优点:对性能影响小,适合冷备。
  3. 缺点:可能丢失最近一次快照后的数据。

4.2 AOF(Append-Only File)

  1. 将每次写操作追加到日志文件中。
  2. 优点:数据丢失量极小。
  3. 缺点:文件较大,恢复速度较慢。

4.3 混合持久化

  1. 同时使用 RDB 和 AOF,兼顾数据完整性和恢复速度。

五、Redis 的高可用架构

主从复制:主节点处理读写请求,从节点负责备份和读请求。提高读取性能,增强数据可靠性。

哨兵模式:监控主从节点状态,自动故障转移。提供高可用能力。

Redis Cluster:分布式部署,将数据分片存储到多个节点。支持大规模数据存储和高并发。

六、Redis 与其他数据库的对比

特性

Redis

MySQL

MongoDB

存储模式

内存+持久化

磁盘存储

磁盘存储

数据结构

丰富

表结构

BSON 文档

读写性能

极高

中等

事务支持

简单事务(MULTI)

完整事务

事务(4.0后支持)

应用场景

缓存、队列、计数器

OLTP、复杂查询

文档存储、分析

七、注意事项

内存限制Redis 的性能依赖内存大小,需设置合理的内存淘汰策略。

持久化选型根据数据重要性选择适当的持久化方式。

线程安全Redis 单线程处理命令,需注意避免长时间阻塞操作。

连接池对高并发场景使用连接池提升性能。

八、代码封装

最后,风云同样用python写了一个类,操作redis,大家只要在这个基础上稍作修改,便可投入项目使用,当然,redis服务器和python库的安装这里先省略了,有需要的可以去百度查阅,代码如下,自取不谢!

import redis


class RedisHelper:
    """
    RedisHelper: 封装 Redis 的常用操作,支持多种数据结构和应用场景。
    """

    def __init__(self, host='localhost', port=6379, db=0, password=None):
        """
        初始化 Redis 连接。

        :param host: Redis 主机地址
        :param port: Redis 端口
        :param db: Redis 数据库编号
        :param password: Redis 密码
        """
        self.connection = redis.StrictRedis(
            host=host, 
            port=port, 
            db=db, 
            password=password, 
            decode_responses=True  # 自动解码为字符串
        )

    # 字符串操作
    def set_string(self, key, value, ex=None):
        """
        设置字符串键值对。

        :param key: 键名
        :param value: 值
        :param ex: 过期时间(秒)
        """
        self.connection.set(key, value, ex)

    def get_string(self, key):
        """
        获取字符串键的值。

        :param key: 键名
        :return: 值
        """
        return self.connection.get(key)

    # 哈希操作
    def set_hash(self, hash_name, key, value):
        """
        设置哈希键值对。

        :param hash_name: 哈希名称
        :param key: 键名
        :param value: 值
        """
        self.connection.hset(hash_name, key, value)

    def get_hash(self, hash_name, key):
        """
        获取哈希键的值。

        :param hash_name: 哈希名称
        :param key: 键名
        :return: 值
        """
        return self.connection.hget(hash_name, key)

    def get_all_hash(self, hash_name):
        """
        获取整个哈希的键值对。

        :param hash_name: 哈希名称
        :return: 哈希键值对
        """
        return self.connection.hgetall(hash_name)

    # 列表操作
    def push_to_list(self, list_name, value, from_left=True):
        """
        向列表添加元素。

        :param list_name: 列表名称
        :param value: 值
        :param from_left: 是否从左侧插入
        """
        if from_left:
            self.connection.lpush(list_name, value)
        else:
            self.connection.rpush(list_name, value)

    def pop_from_list(self, list_name, from_left=True):
        """
        从列表弹出元素。

        :param list_name: 列表名称
        :param from_left: 是否从左侧弹出
        :return: 弹出的值
        """
        return self.connection.lpop(list_name) if from_left else self.connection.rpop(list_name)

    def get_list(self, list_name, start=0, end=-1):
        """
        获取列表的所有元素。

        :param list_name: 列表名称
        :param start: 起始索引
        :param end: 结束索引
        :return: 列表值
        """
        return self.connection.lrange(list_name, start, end)

    # 集合操作
    def add_to_set(self, set_name, value):
        """
        向集合添加元素。

        :param set_name: 集合名称
        :param value: 值
        """
        self.connection.sadd(set_name, value)

    def get_set_members(self, set_name):
        """
        获取集合中的所有成员。

        :param set_name: 集合名称
        :return: 集合成员
        """
        return self.connection.smembers(set_name)

    # 有序集合操作
    def add_to_sorted_set(self, zset_name, value, score):
        """
        向有序集合添加元素。

        :param zset_name: 有序集合名称
        :param value: 值
        :param score: 分数
        """
        self.connection.zadd(zset_name, {value: score})

    def get_sorted_set(self, zset_name, start=0, end=-1, withscores=True):
        """
        获取有序集合中的元素。

        :param zset_name: 有序集合名称
        :param start: 起始索引
        :param end: 结束索引
        :param withscores: 是否返回分数
        :return: 有序集合元素
        """
        return self.connection.zrange(zset_name, start, end, withscores=withscores)

    # 发布/订阅
    def publish_message(self, channel, message):
        """
        向频道发布消息。

        :param channel: 频道名称
        :param message: 消息内容
        """
        self.connection.publish(channel, message)

    def subscribe_to_channel(self, channel):
        """
        订阅频道。

        :param channel: 频道名称
        """
        pubsub = self.connection.pubsub()
        pubsub.subscribe(channel)
        print(f"已订阅频道: {channel}")

        for message in pubsub.listen():
            if message['type'] == 'message':
                print(f"收到消息:{message['data']}")

    # 事务操作
    def execute_transaction(self, operations):
        """
        使用事务执行多个操作。

        :param operations: 操作函数的列表,操作函数接受事务对象作为参数
        """
        with self.connection.pipeline() as pipe:
            for operation in operations:
                operation(pipe)
            pipe.execute()

# 使用示例
if __name__ == "__main__":
    redis_helper = RedisHelper()

    # 字符串操作
    redis_helper.set_string('key1', 'value1')
    print(f"获取 key1: {redis_helper.get_string('key1')}")

    # 哈希操作
    redis_helper.set_hash('user:1', 'name', 'Alice')
    print(f"获取哈希 user:1 -> name: {redis_helper.get_hash('user:1', 'name')}")

    # 列表操作
    redis_helper.push_to_list('tasks', 'task1')
    redis_helper.push_to_list('tasks', 'task2', from_left=False)
    print(f"任务列表: {redis_helper.get_list('tasks')}")

    # 集合操作
    redis_helper.add_to_set('tags', 'python')
    redis_helper.add_to_set('tags', 'redis')
    print(f"标签集合: {redis_helper.get_set_members('tags')}")

    # 有序集合操作
    redis_helper.add_to_sorted_set('leaderboard', 'Alice', 100)
    redis_helper.add_to_sorted_set('leaderboard', 'Bob', 200)
    print(f"排行榜: {redis_helper.get_sorted_set('leaderboard')}")

    # 发布/订阅
    # 请在不同终端分别运行发布和订阅代码
    # redis_helper.publish_message('news', 'Hello, Redis!')
    # redis_helper.subscribe_to_channel('news')