Redis学习指南

1. NoSQL概述

什么是 NoSQL

NoSQL(Not Only SQL)是一类非关系型数据库,设计初衷是解决传统关系型数据库在处理大规模数据、高并发和灵活性需求时的局限性。它通常不依赖固定的表结构,适合分布式系统和高性能场景。

NoSQL 与传统关系型数据库的区别

  • 数据模型:NoSQL 使用键值对、文档、列族、图等模型,而传统数据库使用二维表结构。
  • 扩展性:NoSQL 支持水平扩展,通过增加节点提升性能;传统数据库多为垂直扩展。
  • 一致性:NoSQL 通常提供最终一致性,而传统数据库强调强一致性(ACID)。

NoSQL 的分类

  • 键值存储:如 Redis、DynamoDB
  • 文档存储:如 MongoDB、CouchDB
  • 列族存储:如 Cassandra、HBase
  • 图数据库:如 Neo4j、ArangoDB

2. Redis介绍

什么是 Redis

Redis(Remote Dictionary Server)是一个开源的、高性能的键值对数据库。它将数据存储在内存中,支持多种数据结构,常用于缓存、消息队列等场景。

Redis 的特点和优势

  • 高性能:数据存储在内存,读写速度极快。
  • 丰富的数据结构:支持字符串、哈希、列表、集合、有序集合等。
  • 持久化:提供 RDB 和 AOF 两种方式将数据保存到磁盘。
  • 多功能:支持事务、发布/订阅、Lua 脚本等。

Redis 的应用场景

  • 缓存系统:加速数据访问
  • 排行榜:如游戏积分榜
  • 消息队列:实现异步任务处理
  • 会话管理:存储用户登录状态

3. Redis-CLI常用命令

3.1 基础操作

# 连接Redis
redis-cli

# 测试连接
ping

# 切换数据库(默认16个)
select 0

# 查看所有key
keys *

# 删除key
del key_name

# 设置key过期时间
expire key_name seconds

#检查键是否存在
exists key

3.2 数据类型操作

字符串操作

# 设置值
set key value

# 获取值
get key

# 批量设置
mset key1 value1 key2 value2

# 数值增减
incr key
decr key

列表操作

# 从左边插入
lpush list_name value

# 从右边插入
rpush list_name value

# 获取列表范围
lrange list_name 0 -1

哈希操作

# 设置哈希值
hset user:1 name zhangsan
hset user:1 age 20

# 获取哈希值
hget user:1 name

集合操作

# 添加集合元素
sadd myset value1 value2

# 查看集合成员
smembers myset

有序集合操作

# 添加元素和分数
zadd scoreboard 100 user1
zadd scoreboard 200 user2

4. Redis数据结构详解

4.1 String(字符串)

  • 最基本的数据类型
  • 存储单个字符串、整数、浮点数
  • 最大存储512MB

使用场景

  • 缓存用户信息
  • 计数器
  • 分布式锁

代码示例

// 设置字符串
redisTemplate.opsForValue().set("user:1:name", "张三");

// 获取字符串
String name = (String) redisTemplate.opsForValue().get("user:1:name");

4.2 List(列表)

  • 有序集合
  • 支持从两端添加和弹出元素
  • 底层是双向链表

使用场景

  • 消息队列
  • 最新消息排行
  • 异步任务处理

代码示例

// 左侧推入
redisTemplate.opsForList().leftPush("tasks", "task1");

// 右侧弹出
Object task = redisTemplate.opsForList().rightPop("tasks");

4.3 Hash(哈希)

  • 存储对象
  • 类似Map结构
  • 字段和值都是字符串

使用场景

  • 存储对象
  • 用户信息存储
  • 购物车

代码示例

// 存储用户信息
redisTemplate.opsForHash().put("user:1", "name", "张三");
redisTemplate.opsForHash().put("user:1", "age", "25");

// 获取用户信息
String name = (String) redisTemplate.opsForHash().get("user:1", "name");

4.4 Set(集合)

  • 无序集合
  • 元素唯一
  • 支持集合运算

使用场景

  • 去重
  • 标签系统
  • 社交关系

代码示例

// 添加元素
redisTemplate.opsForSet().add("tags", "Java", "Redis", "分布式");

// 查看成员
Set<String> tags = redisTemplate.opsForSet().members("tags");

4.5 Sorted Set(有序集合)

  • 每个元素关联一个分数
  • 可按分数排序
  • 元素唯一

使用场景

  • 排行榜
  • 实时数据统计

代码示例

// 添加元素和分数
redisTemplate.opsForZSet().add("leaderboard", "user1", 100);
redisTemplate.opsForZSet().add("leaderboard", "user2", 200);

Redis Java客户端

5.1 Jedis

传统的Redis Java客户端

Maven依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.1</version>
</dependency>

使用示例

import redis.clients.jedis.Jedis;

public class JedisDemo {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        jedis.set("key", "Hello Redis");
        System.out.println(jedis.get("key"));  // 输出:Hello Redis
        jedis.close();
    }
}

SpringRedisTemplate

SpringBoot推荐的Redis客户端

依赖:

        <!-- redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 连接池-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

配置

 spring:
     data:
        redis:
          client-name: springboot_mybatis  #redis客户端名称
          host: 127.0.0.1  #redis地址
          port: 6379  #redis端口
          password:  #redis密码
          lettuce:  #lettuce连接池配置
            pool:   #连接池配置
              max-active: 8  #最大连接数
              max-idle: 8  #最大空闲连接数
              min-idle: 0  #最小空闲连接数
              max-wait: 1000ms #最大等待时间

配置类

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        // 配置序列化方式
        Jackson2JsonRedisSerializer<Object> serializer = 
            new Jackson2JsonRedisSerializer<>(Object.class);
        template.setDefaultSerializer(serializer);
        
        return template;
    }
}

springCache整合Redis

@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
    return userMapper.selectById(id);
}

常见问题

  • 缓存穿透:使用布隆过滤器
  • 缓存雪崩:设置随机过期时间
  • 缓存一致性:使用Canal、消息队列同步