redis使用

Redis 使用指南

简介

Redis 是一个开源的内存数据结构存储系统,可以用作数据库、缓存和消息中间件。它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等。Redis 提供了丰富的命令集来操作这些数据结构,并且支持数据的持久化、复制和集群等功能。

安装

说明如何安装Redis,包括下载、配置和启动步骤。

下载

  1. 访问 Redis 官方网站 下载最新版本的 Redis。
  2. 解压下载的文件:
    tar xzf redis-<version>.tar.gz
    cd redis-<version>
    

编译和安装

  1. 编译 Redis:
    make
    
  2. 安装 Redis:
    sudo make install
    

配置和启动

  1. 复制配置文件:
    cp redis.conf /etc/redis.conf
    
  2. 启动 Redis 服务器:
    redis-server /etc/redis.conf
    

基本操作

说明如何使用Redis进行基本操作,包括设置键值对、获取键值对、删除键值对等。

设置键值对

使用 SET 命令可以设置键值对:

SET key value

示例:

SET name "John Doe"

获取键值对

使用 GET 命令可以获取键对应的值:

GET key

示例:

GET name
# 返回 "John Doe"

删除键

使用 DEL 命令可以删除一个或多个键:

DEL key [key ...]

示例:

DEL name

检查键是否存在

使用 EXISTS 命令可以检查键是否存在:

EXISTS key

返回1表示存在,0表示不存在。

设置过期时间

使用 EXPIRE 命令可以为键设置过期时间(秒):

EXPIRE key seconds

示例:

EXPIRE name 60  # 60秒后过期

获取剩余生存时间

使用 TTL 命令可以获取键的剩余生存时间:

TTL key

返回-2表示键不存在,-1表示没有设置过期时间,否则返回剩余秒数。

批量操作

使用 MSETMGET 命令可以进行批量操作:

MSET key1 value1 key2 value2 ...
MGET key1 key2 ...

示例:

MSET name "John" age 30
MGET name age
# 返回 ["John", "30"]

数据类型操作

Redis支持多种数据结构,以下是每种数据类型的常用操作:

字符串(String)

key
value
  • 设置值:SET key value
  • 获取值:GET key
  • 追加值:APPEND key value
  • 获取子串:GETRANGE key start end
  • 设置新值并返回旧值:GETSET key value
  • 自增/自减:INCR key / DECR key

使用场景:

  1. 缓存:存储热点数据,如页面缓存、对象缓存
  2. 计数器:实现访问量统计、点赞数统计等功能
开始
设置值 SET
获取值 GET
追加值 APPEND
获取子串 GETRANGE
设置新值并返回旧值 GETSET
自增/自减 INCR/DECR
结束

哈希(Hash)

key
field1
field2
field3
value1
value2
value3
  • 设置字段值:HSET key field value
  • 获取字段值:HGET key field
  • 获取所有字段值:HGETALL key
  • 删除字段:HDEL key field [field ...]
  • 检查字段是否存在:HEXISTS key field
  • 获取所有字段:HKEYS key
  • 获取字段数量:HLEN key

使用场景:

  1. 对象存储:存储用户信息、商品信息等结构化数据
  2. 配置管理:存储系统配置项,支持单个字段的更新
开始
设置字段值 HSET
获取字段值 HGET
获取所有字段值 HGETALL
删除字段 HDEL
检查字段是否存在 HEXISTS
获取所有字段 HKEYS
获取字段数量 HLEN
结束

列表(List)

key
value1
value2
value3
  • 左/右插入元素:LPUSH key value / RPUSH key value
  • 左/右弹出元素:LPOP key / RPOP key
  • 获取列表长度:LLEN key
  • 获取指定范围元素:LRANGE key start stop
  • 根据索引获取元素:LINDEX key index
  • 根据值删除元素:LREM key count value

使用场景:

  1. 消息队列:实现简单的消息队列系统
  2. 最新动态:存储用户的最新动态、操作日志
开始
左/右插入 LPUSH/RPUSH
左/右弹出 LPOP/RPOP
获取列表长度 LLEN
获取指定范围 LRANGE
根据索引获取 LINDEX
根据值删除 LREM
结束

集合(Set)

key
member1
member2
member3
  • 添加元素:SADD key member [member ...]
  • 删除元素:SREM key member [member ...]
  • 获取所有元素:SMEMBERS key
  • 检查元素是否存在:SISMEMBER key member
  • 获取集合大小:SCARD key
  • 集合运算:SUNION / SINTER / SDIFF

使用场景:

  1. 标签系统:存储文章标签、商品分类
  2. 共同好友:计算两个用户的共同好友
开始
添加元素 SADD
删除元素 SREM
获取所有元素 SMEMBERS
检查元素是否存在 SISMEMBER
获取集合大小 SCARD
集合运算 SUNION/SINTER/SDIFF
结束

有序集合(Sorted Set)

key
score1:member1
score2:member2
score3:member3
  • 添加元素:ZADD key score member [score member ...]
  • 获取元素分数:ZSCORE key member
  • 获取排名:ZRANK key member
  • 获取指定范围元素:ZRANGE key start stop [WITHSCORES]
  • 删除元素:ZREM key member [member ...]
  • 获取集合大小:ZCARD key
  • 按分数范围获取元素:ZRANGEBYSCORE key min max

使用场景:

  1. 排行榜:实现游戏积分榜、热搜榜
  2. 延迟队列:通过分数存储时间戳实现延迟任务
开始
添加元素 ZADD
获取元素分数 ZSCORE
获取排名 ZRANK
获取指定范围 ZRANGE
删除元素 ZREM
获取集合大小 ZCARD
按分数范围获取 ZRANGEBYSCORE
结束

Bitmaps

key
0
1
2
...
31
  • 设置位:SETBIT key offset value
  • 获取位:GETBIT key offset
  • 统计置位数量:BITCOUNT key [start end]
  • 位运算:BITOP operation destkey key [key ...]
  • 查找第一个置位:BITPOS key bit [start] [end]

使用场景:

  1. 用户签到:记录用户每日签到情况
  2. 特征标记:标记用户特征或状态
开始
设置位 SETBIT
获取位 GETBIT
统计置位数量 BITCOUNT
位运算 BITOP
查找第一个置位 BITPOS
结束

HyperLogLog

key
registers
register1
register2
...
register16384
  • 添加元素:PFADD key element [element ...]
  • 统计基数:PFCOUNT key [key ...]
  • 合并多个HLL:PFMERGE destkey sourcekey [sourcekey ...]

使用场景:

  1. UV统计:统计网站的独立访客数
  2. 去重统计:统计大规模数据的近似去重数量
开始
添加元素 PFADD
统计基数 PFCOUNT
合并多个HLL PFMERGE
结束

Geospatial

key
member1
member2
member3
longitude1,latitude1
longitude2,latitude2
longitude3,latitude3
  • 添加地理位置:GEOADD key longitude latitude member [longitude latitude member ...]
  • 获取位置:GEOPOS key member [member ...]
  • 计算距离:GEODIST key member1 member2 [unit]
  • 查找附近位置:GEORADIUS key longitude latitude radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]

使用场景:

  1. 附近的人:查找用户附近的其他用户
  2. 位置服务:实现基于位置的搜索和推荐
开始
添加地理位置 GEOADD
获取位置 GEOPOS
计算距离 GEODIST
查找附近位置 GEORADIUS
结束

Streams

key
message1
message2
message3
field1:value1, field2:value2
field1:value1, field2:value2
field1:value1, field2:value2
  • 添加消息:XADD key ID field value [field value ...]
  • 读取消息:XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
  • 创建消费者组:XGROUP CREATE key groupname ID
  • 消费消息:XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
  • 确认消息:XACK key group ID [ID ...]
  • 查看待处理消息:XPENDING key group

使用场景:

  1. 消息队列:实现可靠的消息队列系统
  2. 日志收集:收集和存储系统日志
开始
添加消息 XADD
读取消息 XREAD
创建消费者组 XGROUP CREATE
消费消息 XREADGROUP
确认消息 XACK
查看待处理消息 XPENDING
结束

高级特性

Redis提供了多种高级功能来满足不同的使用场景:

持久化

Redis支持两种持久化方式:

  1. RDB(Redis Database):

    • 定时生成数据快照
    • 配置:save <seconds> <changes>
    • 手动保存:SAVE(阻塞)或BGSAVE(后台)
  2. AOF(Append Only File):

    • 记录每个写操作
    • 配置:appendonly yes
    • 同步策略:appendfsync always|everysec|no

事务

  • 使用MULTI开始事务
  • 使用EXEC执行事务
  • 使用DISCARD取消事务
  • 使用WATCH实现乐观锁
  • 示例:
    MULTI
    SET key1 value1
    SET key2 value2
    EXEC
    

发布/订阅

  • 发布消息:PUBLISH channel message
  • 订阅频道:SUBSCRIBE channel [channel ...]
  • 取消订阅:UNSUBSCRIBE [channel ...]
  • 模式匹配订阅:PSUBSCRIBE pattern [pattern ...]

复制

  • 主从复制配置:
    replicaof <masterip> <masterport>
    
  • 查看复制信息:INFO replication
  • 主从切换:REPLICAOF NO ONE

集群

  • 创建集群:redis-cli --cluster create ...
  • 添加节点:redis-cli --cluster add-node ...
  • 重新分片:redis-cli --cluster reshard ...
  • 查看集群信息:CLUSTER INFO
  • 查看节点信息:CLUSTER NODES

Lua脚本

  • 执行脚本:EVAL script numkeys key [key ...] arg [arg ...]
  • 缓存脚本:SCRIPT LOAD script
  • 执行缓存脚本:EVALSHA sha1 numkeys key [key ...] arg [arg ...]
  • 示例:
    EVAL "return redis.call('GET', KEYS[1])" 1 mykey
    

分布式锁

Redis实现分布式锁的最佳实践:

  1. 基本实现:

    • 获取锁:SET lock_key unique_value NX PX 30000
    • 释放锁:Lua脚本保证原子性
      if redis.call("get",KEYS[1]) == ARGV[1] then
          return redis.call("del",KEYS[1])
      else
          return 0
      end
      
  2. 关键特性:

    • 互斥性:使用SETNX保证只有一个客户端能获取锁
    • 超时机制:设置合理的过期时间防止死锁
    • 可重入性:通过ThreadLocal存储锁信息实现
    • 自动续期:使用守护线程定期延长锁的过期时间
  3. 注意事项:

    • 确保value唯一,建议使用UUID
    • 设置合理的过期时间,避免业务未完成锁已过期
    • 使用Lua脚本保证释放锁的原子性
    • 考虑集群模式下的锁可靠性
  4. 示例代码:

    // 获取锁
    String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime);
    if ("OK".equals(result)) {
        // 获取锁成功
        try {
            // 执行业务逻辑
        } finally {
            // 释放锁
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
        }
    }
    

常见问题

以下是使用Redis时可能遇到的常见问题及解决方案:

内存管理

  1. 内存不足:

    • 解决方案:使用maxmemory配置限制内存使用
    • 设置淘汰策略:maxmemory-policy(如volatile-lru)
    • 使用MEMORY USAGE命令监控内存使用
  2. 大Key问题:

    • 现象:单个Key过大导致性能下降
    • 解决方案:拆分大Key,使用多个小Key存储

性能优化

  1. 慢查询:

    • 使用SLOWLOG命令查看慢查询
    • 优化数据结构设计
    • 使用Pipeline减少网络开销
  2. 热点Key问题:

    • 现象:某些Key访问过于频繁
    • 解决方案:使用本地缓存或读写分离

数据一致性

  1. 主从延迟:

    • 使用INFO replication查看复制状态
    • 优化网络配置
    • 使用WAIT命令等待复制完成
  2. 事务原子性:

    • 确保使用MULTI/EXEC包裹事务
    • 使用WATCH实现乐观锁

故障处理

  1. 主节点故障:

    • 使用哨兵模式自动故障转移
    • 手动执行REPLICAOF NO ONE提升从节点
  2. 数据丢失:

    • 配置合理的持久化策略
    • 定期备份RDB文件
    • 使用AOF重写压缩日志

安全配置

  1. 访问控制:

    • 设置密码:requirepass
    • 使用rename-command重命名危险命令
    • 配置防火墙规则
  2. 数据加密:

    • 使用SSL/TLS加密网络传输
    • 敏感数据在客户端加密存储

分布式缓存问题

  1. 缓存穿透:

    • 现象:大量请求查询不存在的数据,导致请求直接打到数据库
    • 解决方案:
      • 使用布隆过滤器拦截非法请求
      • 缓存空值(设置较短过期时间)
      • 接口层增加参数校验
  2. 缓存击穿:

    • 现象:热点key过期瞬间,大量请求直接打到数据库
    • 解决方案:
      • 设置热点数据永不过期
      • 使用互斥锁(如Redis的SETNX)重建缓存
      • 使用本地缓存作为二级缓存
  3. 缓存雪崩:

    • 现象:大量缓存同时失效,导致数据库压力骤增
    • 解决方案:
      • 设置缓存过期时间时增加随机值
      • 使用集群模式,分散缓存失效时间
      • 实现缓存预热机制
  4. 数据一致性:

    • 现象:缓存与数据库数据不一致
    • 解决方案:
      • 使用双写策略(先写数据库,再删缓存)
      • 使用消息队列异步更新缓存
      • 设置合理的缓存过期时间
  5. 热点数据:

    • 现象:某些key访问过于频繁,导致单点压力过大
    • 解决方案:
      • 使用本地缓存
      • 对热点key进行分片
      • 使用读写分离架构

参考资料

列出参考的书籍、文档和在线资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值