当前位置: 首页 > news >正文

Redis全面详解:从配置入门到实战应用

目录

一、Redis简介与安装启动

Windows环境启动Redis

Linux环境安装与启动

二、Redis配置文件详解

常用配置项解析

配置管理命令

密码认证配置

三、Redis持久化机制

RDB持久化

AOF持久化

四、Redis数据类型及操作

键(key)操作

字符串(String)操作

列表(List)操作

哈希(Hash)操作

集合(Set)操作

有序集合(Sorted Set)操作

五、Redis主从复制

主从配置

命令行配置主从

六、Redis缓存实战:MySQL缓存方案

为什么使用Redis缓存MySQL数据?

基本缓存模式

解决缓存雪崩问题

解决缓存穿透问题

解决缓存击穿问题

七、Redis最佳实践

八、总结


一、Redis简介与安装启动

Redis(Remote Dictionary Server)是一个开源的高性能键值对存储系统,以其卓越的速度、丰富的数据结构和原子操作而闻名。它通常被用作数据库、缓存和消息中间件。

Windows环境启动Redis

  1. 启动服务器

    cmd

    redis-server.exe
  2. 连接客户端(新开命令行窗口):

    cmd

    redis-cli.exe

Linux环境安装与启动

# 安装Redis
sudo apt-get install redis-server# 启动Redis服务
sudo systemctl start redis-server# 连接Redis客户端
redis-cli

二、Redis配置文件详解

Redis的配置文件是Redis行为的核心控制中心,通常命名为redis.confredis.windows.conf

常用配置项解析

# 导入其他配置文件
include /path/to/other.conf# 服务端口号(默认6379)
port 6379# 绑定IP地址(默认为127.0.0.1,只能本地访问)
bind 127.0.0.1# 客户端空闲超时时间(0表示禁用超时功能)
timeout 0# 日志级别(debug, verbose, notice, warning)
loglevel notice# 日志文件路径
logfile ""# 数据库数量(默认16个)
databases 16# 持久化规则:在指定时间内有指定数量的更改则保存到磁盘
save 900 1      # 15分钟(900秒)内至少有1个变更
save 300 10     # 5分钟(300秒)内至少有10个变更
save 60 10000   # 1分钟(60秒)内至少有10000个变更# RDB持久化文件名
dbfilename dump.rdb# 数据存储目录
dir ./# 访问密码(默认被注释)
# requirepass foobared# 最大客户端连接数
maxclients 10000

配置管理命令

# 获取所有配置
127.0.0.1:6379> CONFIG GET *# 获取特定配置(如密码配置)
127.0.0.1:6379> CONFIG GET requirepass# 动态修改配置(临时生效,重启后失效)
127.0.0.1:6379> CONFIG SET requirepass "123456"

密码认证配置

方式一:配置文件修改(永久生效)

  1. 编辑redis.conf文件

  2. 取消requirepass注释并设置密码

  3. 重启Redis服务

方式二:命令行修改(临时生效)

127.0.0.1:6379> CONFIG SET requirepass "123456"

密码认证使用

# 连接时认证
redis-cli -a 123456# 连接后认证
127.0.0.1:6379> AUTH 123456

三、Redis持久化机制

Redis提供两种持久化方式:RDB和AOF。

RDB持久化

RDB是Redis默认的持久化方式,通过创建数据快照实现。

优势

  • 性能高,适合大规模数据恢复

  • 文件紧凑,便于备份和传输

配置示例

# 900秒内至少1个键变更则保存
save 900 1
# 300秒内至少10个键变更则保存
save 300 10
# 60秒内至少10000个键变更则保存
save 60 10000

AOF持久化

AOF(Append Only File)记录每个写操作,提供更好的持久性保证。

配置示例

# 开启AOF持久化
appendonly yes# AOF文件名
appendfilename "appendonly.aof"# 同步策略:每秒同步一次
appendfsync everysec

四、Redis数据类型及操作

键(key)操作

import redisr = redis.Redis(host='localhost', port=6379, db=0)# 删除键
r.delete('key1')# 设置键过期时间(秒)
r.expire('key1', 60)# 检查键是否存在
exists = r.exists('key1')# 获取键剩余生存时间
ttl = r.ttl('key1')# 获取键类型
key_type = r.type('key1')# 查找匹配模式的键
keys = r.keys('user:*')

字符串(String)操作

# 设置和获取值
r.set('name', 'Redis')
value = r.get('name')# 批量操作
r.mset({'key1': 'value1', 'key2': 'value2'})
values = r.mget(['key1', 'key2'])# 设置带过期时间的键值
r.setex('temp_key', 300, 'temporary_value')# 自增操作(原子性)
r.set('counter', 0)
r.incr('counter')      # 增加1 → 1
r.incrby('counter', 5) # 增加5 → 6# 自减操作
r.decr('counter')      # 减少1 → 5
r.decrby('counter', 3) # 减少3 → 2# 获取字符串长度
length = r.strlen('name')

列表(List)操作

# 左右推入元素
r.lpush('mylist', 'world')  # 左侧插入 → ['world']
r.rpush('mylist', 'hello')  # 右侧插入 → ['world', 'hello']# 左右弹出元素
left_item = r.lpop('mylist')  # 'world'
right_item = r.rpop('mylist') # 'hello'# 获取列表长度
length = r.llen('mylist')# 获取范围元素
items = r.lrange('mylist', 0, -1)  # 获取所有元素# 获取指定索引元素
item = r.lindex('mylist', 0)# 修剪列表
r.ltrim('mylist', 0, 2)  # 只保留前3个元素

哈希(Hash)操作

# 设置和获取字段值
r.hset('user:1000', 'name', 'John')
name = r.hget('user:1000', 'name')# 批量操作
r.hmset('user:1000', {'age': 30, 'city': 'New York'})
fields = r.hmget('user:1000', ['name', 'age'])# 获取所有字段和值
all_fields = r.hkeys('user:1000')
all_values = r.hvals('user:1000')# 检查字段是否存在
exists = r.hexists('user:1000', 'name')# 删除字段
r.hdel('user:1000', 'city')# 获取字段数量
field_count = r.hlen('user:1000')

集合(Set)操作

# 添加和检查元素
r.sadd('tags', 'python', 'redis', 'database')
is_member = r.sismember('tags', 'python')# 获取所有成员
members = r.smembers('tags')# 获取集合大小
size = r.scard('tags')# 移除元素
r.srem('tags', 'database')# 集合运算
r.sadd('set1', 'a', 'b', 'c')
r.sadd('set2', 'b', 'c', 'd')# 交集
intersection = r.sinter('set1', 'set2')  # {'b', 'c'}# 并集
union = r.sunion('set1', 'set2')  # {'a', 'b', 'c', 'd'}# 差集
difference = r.sdiff('set1', 'set2')  # {'a'}

有序集合(Sorted Set)操作

# 添加元素(带分数)
r.zadd('leaderboard', {'player1': 100, 'player2': 200, 'player3': 150})# 获取元素排名和分数
rank = r.zrank('leaderboard', 'player1')  # 升序排名
score = r.zscore('leaderboard', 'player1')  # 分数# 获取范围元素
top_players = r.zrange('leaderboard', 0, 2)  # 前3名# 统计分数范围内的元素
count = r.zcount('leaderboard', 100, 200)# 移除元素
r.zrem('leaderboard', 'player1')

五、Redis主从复制

Redis支持主从复制,提供数据冗余和读写分离。

主从配置

主服务器配置

# 主服务器无需特殊配置,只需设置密码(如果需要)
requirepass masterpassword

从服务器配置

# 指定主服务器
replicaof 192.168.1.100 6379# 主服务器密码
masterauth masterpassword

命令行配置主从

# 在从服务器上执行
127.0.0.1:6379> SLAVEOF masterip masterport
127.0.0.1:6379> CONFIG SET masterauth masterpassword

六、Redis缓存实战:MySQL缓存方案

为什么使用Redis缓存MySQL数据?

  1. 性能提升:内存操作速度远高于磁盘I/O

  2. 减轻数据库压力:减少直接访问MySQL的次数

  3. 高并发支持:Redis单线程模型能更好地处理并发请求

基本缓存模式

import redis
import mysql.connector
import json# 初始化连接
r = redis.Redis(host='localhost', port=6379, db=0)
db = mysql.connector.connect(host="localhost",user="root",password="password",database="mydatabase"
)def get_user(user_id):# 先尝试从Redis获取cache_key = f"user:{user_id}"cached_user = r.get(cache_key)if cached_user:return json.loads(cached_user)# Redis中没有,从MySQL获取cursor = db.cursor()cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))user = cursor.fetchone()if user:# 将结果存入Redis,设置随机过期时间避免缓存雪崩import randomexpire_time = 3600 + random.randint(0, 300)  # 1小时±5分钟r.setex(cache_key, expire_time, json.dumps(user))return userdef update_user(user_id, data):# 更新MySQLcursor = db.cursor()cursor.execute("UPDATE users SET ... WHERE id = %s", (user_id,))db.commit()# 删除Redis缓存,确保数据一致性cache_key = f"user:{user_id}"r.delete(cache_key)

解决缓存雪崩问题

缓存雪崩是指大量缓存同时过期,导致所有请求直接访问数据库。

解决方案:为缓存设置随机过期时间

def set_cache_with_random_expire(key, value, base_expire=3600):import random# 基础过期时间 ± 5分钟随机值expire = base_expire + random.randint(-300, 300)r.setex(key, expire, json.dumps(value))

解决缓存穿透问题

缓存穿透是指查询不存在的数据,绕过缓存直接访问数据库。

解决方案:缓存空对象

def get_user_safe(user_id):cache_key = f"user:{user_id}"cached_data = r.get(cache_key)if cached_data:# 如果是特殊标记的空对象,直接返回Noneif cached_data == b'NULL':return Nonereturn json.loads(cached_data)# 从数据库查询user = query_database_for_user(user_id)if user:set_cache_with_random_expire(cache_key, user)else:# 缓存空对象,设置较短过期时间r.setex(cache_key, 300, 'NULL')  # 5分钟return user

解决缓存击穿问题

缓存击穿是指热点key过期,大量并发请求直接访问数据库。

解决方案:使用互斥锁

def get_user_with_lock(user_id):cache_key = f"user:{user_id}"lock_key = f"lock:{user_id}"# 尝试获取缓存data = r.get(cache_key)if data:return json.loads(data)# 尝试获取锁lock_acquired = r.setnx(lock_key, 1)if lock_acquired:# 设置锁过期时间,防止死锁r.expire(lock_key, 10)try:# 从数据库获取数据user = query_database_for_user(user_id)if user:set_cache_with_random_expire(cache_key, user)else:r.setex(cache_key, 300, 'NULL')return userfinally:# 释放锁r.delete(lock_key)else:# 未获取到锁,等待重试import timetime.sleep(0.1)return get_user_with_lock(user_id)  # 递归重试

七、Redis最佳实践

  1. 键命名规范:使用冒号分隔的命名空间,如user:1000:profile

  2. 合理设置过期时间:避免数据永久驻留内存

  3. 监控内存使用:使用INFO memory命令定期检查

  4. 使用连接池:避免频繁创建和销毁连接

  5. 批量操作:使用pipeline减少网络往返时间

# 使用pipeline批量操作
pipe = r.pipeline()
pipe.set('key1', 'value1')
pipe.set('key2', 'value2')
pipe.incr('counter')
pipe.execute()

八、总结

Redis作为一个高性能的内存数据存储系统,在现代应用中扮演着至关重要的角色。通过合理配置、正确使用数据类型和实现有效的缓存策略,可以显著提升应用性能。同时,需要注意缓存雪崩、穿透和击穿等问题,并采取相应的解决方案。

掌握Redis的核心概念和实战技巧,对于构建高性能、可扩展的应用系统至关重要。本文涵盖了从基础配置到高级应用的全面内容,希望能为您的Redis学习之路提供有力帮助。

进一步学习建议

  1. 深入学习Redis持久化机制(RDB和AOF)

  2. 了解Redis哨兵和集群模式

  3. 探索Redis Streams实现消息队列

  4. 学习Redis Lua脚本编程

  5. 研究Redis模块系统,如RedisSearch、RedisJSON等

http://www.dtcms.com/a/347729.html

相关文章:

  • 【前端debug调试】
  • 【Java SE】抽象类、接口与Object类
  • 从“一指禅”到盲打:如何系统提升电脑输入能力?
  • 25.深入对象
  • 联邦学习之----联邦批量归一化(FedBN)
  • 线程间Bug检测工具Canary
  • Python字符串
  • SOC估算方法-蜣螂优化算法结合极限学习
  • 1200 SCL学习笔记
  • 机器人控制基础:串级PID控制算法的参数如何整定?
  • 11.Shell脚本修炼手册---IF 条件语句的知识与实践
  • 无线数传模块保障智能立体车库多设备实时通信的可靠性
  • 二、BPMNJS简介
  • share logic in core or in example
  • 【typenum】 23 倒序存储的无符号整数(private.rs片段)
  • Linux mount 命令
  • PyInstaller将.py文件转为exe,执行文件在不同的电脑出现字体大小不一致问题原因分析及解决办法
  • Spring:IOC(控制反转 )、DI(依赖注入 )、AOP(通知类型、事务、拦截器)
  • 主流.NET 平台的NuGet 生态正在积极拥抱 AOT
  • 【84页PPT】智慧方案某著名企业某集团协同OA整体解决方案(附下载方式)
  • MySQL索引原理与优化全解析
  • 【每天一个知识点】训推一体机
  • 13.Shell脚本修炼手册---玩转 CASE 语句(应用场景与实践技巧)
  • GitHub Actions workflow最佳实践
  • 提问:温度不改变 logits 与概率的排名,为何还会影响模型输出?
  • Linux 进程间通信之System V 共享内存
  • 深入探讨集成学习:Bagging与Boosting的核心原理与实践
  • RAG系统开发中的12大痛点及应对策略
  • SVG.js 一个轻量且强大的图形库
  • Sql server的行转列