目录
Redis 安装与数据类型
Redis(Remote Dictionary Server)是一个开源的、支持网络的Key-Value数据库,使用ANSI C语言编写,支持内存和日志型持久化。它提供多种数据类型,常用于数据库、缓存和消息中间件。
安装指南
Windows
- 安装:从 MicrosoftArchive/redis 下载安装包并安装。
- 测试:
ping
:测试服务是否启动。set name cht
:设置键值对。get name
:获取键对应的值。
Linux
前提:确保已安装Java和gcc-c++
。
- 使用源码:
- 下载源码包:
wget -http://download.redis.io/releases/redis-<version>.tar.gz
- 解压:
tar -xzf redis-<version>.tar.gz
- 进入目录:
cd redis-<version>
- 编译:make
- 安装:
sudo make install
- 验证安装:redis-server -version
- 下载源码包:
- 使用Docker:(下面的相关展示使用的是docker)
- 拉取镜像:
docker pull redis
- 运行容器:
docker run -d --name myredis redis
- 进入容器客户端:
docker exec -it myredis redis-cli
- 查看连接:
ps -ef | grep redis
- 停止服务:
shutdown
- 拉取镜像:
性能测试
使用redis-benchmark
测试性能:
- 示例命令:
docker exec -it myredis redis-benchmark -p 6379 -c 100 -n 1000000
- 参数说明:
-h
:主机名/IP。-p
:端口号,默认6379。-c
:并发连接数,默认50。-n
:请求数,默认100000。-d
:数据大小,默认3字节。-t
:指定测试类型。-P
:管道机制。-q
:安静模式。--csv
:输出CSV格式。-r
:随机键空间。
基本知识
- 数据库:默认16个数据库,切换使用
select dbindex
。 - 线程模型:单线程(Redis 6.0起支持多线程)。
- 常用命令:
DBSIZE
:查看键数。key *
:列出所有键。flushdb/FLUSHALL
:清空数据库。exists key
:检查键是否存在。expire key seconds
:设置过期时间。ttl key
:查看剩余时间。type key
:查看键类型。
数据类型
String
适用于字符串存储:
set key value
:设置值。get key
:获取值。append key value
:追加字符串。strlen key
:字符串长度。incr/decr key
:自增/自减。getrange/setrange
:截取/替换子串。setex key seconds value
:设置带过期时间的值。setnx key value
:键不存在时设置。mset/mget
:批量操作。getset key value
:先获取后设置。
List(双向列表)
lpush/rpush
:左边/右边添加元素。lrange
:获取范围内元素。lpop/rpop
:移除左/右边元素。lrem
:移除指定元素。ltrim
:截取并保留范围内元素。rpoplpush
:从源列表末尾移到目标列表开头。lset
:替换元素。linsert
:在指定元素前/后插入新元素。
Set(集合)
不允许重复元素:
sadd
:添加元素。smembers
:查看所有元素。sismember
:检查元素是否存在。scard
:元素个数。srem
:移除元素。srandmember
:随机获取元素。spop
:随机移除元素。smove
:移动元素到另一个集合。sdiff/sinter/sunion
:集合运算。
Hash(哈希)
适合对象存储:
hset
:设置键值。hget/hmget
:获取值。hmset
:批量设置。hgetall
:获取所有键值。hlen
:键的数量。hexists
:检查键是否存在。hkeys/hvals
:键列表/值列表。hincrby/hdecrby
:增量/减量。hsetex/hsetnx
:带过期时间/不存在时设置。
Zset(有序集合)
按分数排序:
zadd
:添加元素。zrange/zrevrange
:升序/降序获取元素。zrem
:移除元素。zcard
:元素个数。zcount
:统计分数区间内的元素。zrangebyscore/zrevrangebyscore
:按分数范围获取元素。
地理位置(Geospatial)
处理地理位置数据:
geoadd
:添加地理位置。geopos
:获取位置坐标。geodist
:计算两点距离。georadius/geomember
:查询区域内的位置。geohash
:生成Geohash字符串。zrange/zrem
:操作有序集合。
Hyperloglog
用于基数统计:
pfadd
:添加元素。pfcount
:统计基数。pfmerge
:合并集合。
Bitmaps
位运算支持布尔标志:
setbit/getbit
:设置/获取位值。bitcount
:统计1的位数。bitop
:进行AND、OR、XOR、NOT操作。
Redis高级功能与配置指南
1. 事务
1.1 事务简介
Redis的事务通过MULTI
命令开始,所有事务命令会缓冲到队列中,直到执行EXEC
才会运行。如果在事务执行过程中出现编译错误,所有命令都不执行;运行时错误则继续执行其他命令。
1.2 事务命令
MULTI
:开始事务。EXEC
:执行事务。DISCARD
:取消事务,放弃缓冲中的命令。
1.3 锁机制
1.3.1 悲观锁
- 总是假设最坏情况会发生,所有操作都加锁。
- 适用于并发冲突较高的场景。
1.3.2 乐观锁
- 假设冲突可能性较小,使用
WATCH
监视键。 - 事务执行前检查键是否被修改:
WATCH
命令监视键。MULTI
开始事务。- 执行事务命令,如果键未被修改,
EXEC
运行,否则事务中止。
- 优点:提高并发性能,简化逻辑。
- 缺点:可能出现数据不一致,重试逻辑复杂。
2. Redis配置文件(redis.conf)
2.1 网络配置
bind 127.0.0.1
:绑定IP地址,限制访问来源。protected-mode yes
:保护模式,防止未设置密码时外部访问。port 6379
:设置Redis服务端口。
2.2 通用配置
daemonize yes
:以守护进程运行。pidfile /var/run/redis_6379.pid
:指定PID文件。requirepass <password>
:设置客户端连接密码。loglevel notice
:设置日志级别(debug, verbose, notice, warning)。logfile ""
:指定日志文件路径。databases 16
:设置默认数据库数量。always-show-logo yes
:显示Redis启动Logo。
2.3 快照配置(RDB)
save 900 1
:在900秒内有至少1个键变化时触发持久化。stop-writes-on-bgsave-error yes
:持久化错误时停止写入。rdbcompression yes
:对RDB文件进行压缩。rdbchecksum yes
:对RDB文件进行校验。dbfilename dump.rdb
:指定RDB文件名。dir ./
:设置RDB文件存储目录。
2.4 客户端限制
maxclients 10000
:设置最大客户端连接数。
2.5 内存管理
maxmemory <bytes>
:设置最大内存限制。maxmemory-policy noeviction
:内存超出策略(默认不移除任何键)。
2.6 AOF配置
appendonly yes
:启用AOF持久化。appendfilename "appendonly.aof"
:指定AOF文件名。appendfsync everysec
:设置AOF同步策略(默认每秒一次)。
3. 持久化
3.1 RDB持久化
- 快照机制:fork子进程生成RDB文件。
- 触发机制:
- 满足
save
规则。 - 执行
flushall
。 - 退出Redis。
- 满足
- 恢复:Redis启动时自动加载
dump.rdb
文件。 - 优点:
- 高效:主进程继续处理请求。
- 恢复快:二进制文件直接加载。
- 适合备份:文件紧凑,便于存储。
- 缺点:可能丢失最近数据。
3.2 AOF持久化
- 日志机制:记录每个写操作,重启时回放。
- 优先级:高于RDB,启动时优先加载。
- 修复工具:
redis-check-aof --fix
修复损坏的AOF文件。 - 重写机制:
- 触发条件:
- 文件增长到一定比例(
auto-aof-rewrite-percentage
)。 - 达到最小大小(
auto-aof-rewrite-min-size
)。
- 文件增长到一定比例(
- 优点:减少文件碎片,优化存储。
- 触发条件:
- 优点:
- 更高可靠性:最多丢失1秒数据。
- 紧急恢复:可手动编辑AOF文件。
- 可读性:明确的操作日志,便于分析。
- 缺点:
- 文件较大:同等数据占用空间更大。
- 效率:比RDB慢,尤其在不同步时。
4. 订阅/发布
4.1 概述
Redis的发布/订阅功能用于实时消息传输,适用于实时数据更新的场景,如实时新闻、系统通知等。
4.2 命令说明
- 订阅:
SUBSCRIBE channel [channel ...]
:订阅一个或多个频道。PSUBSCRIBE pattern [pattern ...]
:订阅符合模式的频道。
- 取消订阅:
UNSUBSCRIBE [channel ...]
:取消订阅指定频道。PUNSUBSCRIBE [pattern ...]
:取消订阅符合模式的频道。
- 发布消息:
PUBLISH channel message
:向指定频道发送消息。
4.3 使用示例
# 订阅频道"cht"
127.0.0.1:6379> SUBSCRIBE cht
1) "subscribe"
2) "cht"
3) (integer) 1
# 发布消息
127.0.0.1:6379> PUBLISH cht "hello world"
(integer) 1
# 接收到的消息:
1) "message"
2) "cht"
3) "hello world"
4.4 应用场景
- 实时更新:如实时信息展示。
- 消息队列:用于分布式系统的消息传递。
- 动态通知:用户行为触发的实时通知。
Redis主从复制、哨兵模式及缓存问题解决策略
1. Redis主从复制
1.1 概述
Redis的主从复制功能用于实现数据的读写分离、数据备份和故障恢复。通过配置主从节点,可以将写操作集中在主节点,读操作分散到多个从节点,提升系统的整体性能和可用性。
1.2 主从复制的工作原理
全量复制:
- 从节点在初次连接主节点时,会触发一次全量复制。
- 主节点执行
BGSAVE
命令生成RDB文件,并将其发送给从节点。 - 从节点加载RDB文件,初始化数据。
- 主节点记录此时的复制偏移量和数据。
增量复制:
- 全量复制完成后,主节点继续处理新的写操作,并将这些操作记录在复制缓冲区中。
- 从节点定期请求主节点发送增量数据,主节点根据复制偏移量,发送从节点缺少的数据。
- 从节点接收并执行这些写操作,确保数据与主节点一致。
1.3 配置主从复制
设置从节点:
- 在从节点的配置文件
redis.conf
中,添加replicaof <master_ip> <master_port>
,指定主节点的IP和端口。 - 或者在Redis客户端中执行
SLAVEOF <master_ip> <master_port>
命令。
- 在从节点的配置文件
验证主从复制:
- 在主节点执行
INFO replication
命令,查看从节点的连接状态。 - 确认从节点已经正确连接,并且数据同步完成。
- 在主节点执行
1.4 主从复制的优缺点
- 优点:
- 数据备份与冗余,避免单点故障。
- 读写分离,提升读操作的吞吐量。
- 负载均衡,分散读操作到多个从节点。
- 缺点:
- 主节点成为性能瓶颈,所有写操作必须经过主节点。
- 数据一致性存在延迟,增量复制过程中可能出现短暂的不一致。
- 手动干预切换,主节点故障时需要人工介入,切换从节点为主节点。
2. 哨兵模式
2.1 概述
哨兵模式是在主从复制的基础上,引入了一组哨兵进程,用于监控主节点和从节点的状态。当主节点出现故障时,哨兵会自动将一个从节点提升为新的主节点,实现故障的自动转移。
2.2 哨兵的工作原理
- 监控:
- 哨兵进程通过定期向主节点和从节点发送
PING
命令,监控它们的运行状态。
- 哨兵进程通过定期向主节点和从节点发送
- 主观下线:
- 如果节点在指定时间内未回复,哨兵会将其标记为“主观下线”。
- 客观下线:
- 当一定数量的哨兵进程(由
quorum
参数配置)都标记主节点为主观下线时,主节点被判定为“客观下线”。
- 当一定数量的哨兵进程(由
- 故障转移:
- 哨兵集群选举出一个领头哨兵。
- 领头哨兵选择一个健康的从节点作为新的主节点。
- 更新所有从节点的复制目标,确保它们指向新的主节点。
- 通知客户端主节点的变更,完成故障转移。
2.3 配置哨兵
以下是一个示例的哨兵配置文件sentinel.conf
:
port 26379 # 哨兵监听的端口
daemonize yes # 以守护进程运行
pidfile "/var/run/redis-sentinel.pid" # PID文件路径
logfile "26379.log" # 日志文件路径
dir "/var/tmp/redis-sentinel/data" # 工作目录
# 监控的主节点,指定主节点名称、IP地址、端口和哨兵判定主节点下线的票数
sentinel monitor mymaster 127.0.0.1 6379 2
# 主节点的密码,如果主节点设置了密码需要配置
sentinel auth-pass mymaster 123456
# 哨兵判定主节点下线的超时时间,单位是毫秒
sentinel down-after-milliseconds mymaster 30000
# 故障转移时,允许并行同步的从节点个数,默认是1
sentinel parallel-syncs mymaster 1
# 故障转移超时时间,单位是毫秒
sentinel failover-timeout mymaster 180000
# 是否允许通过脚本配置重新配置客户端
sentinel deny-scripts-reconfig yes
2.4 简单部署
redis 使用 Docker 部署 Redis 集群(包括哨兵机制)-CSDN博客
2.5 哨兵的优缺点
- 优点:
- 自动故障转移,减少人工干预。
- 监控与通知,及时发现和处理问题。
- 提高系统的高可用性和稳定性。
- 缺点:
- 配置较为复杂,增加了维护成本。
- 增加资源开销,需要额外的服务器运行哨兵进程。
- 单点故障隐患,哨兵本身也可能成为潜在的单点故障。
3. 缓存穿透、击穿与雪崩问题及解决策略
3.1 缓存穿透
- 问题描述:
- 用户频繁查询不存在的数据,导致请求直接打到数据库,增加数据库负担,影响性能。
- 解决方法:
- 缓存空对象:
- 在数据库未找到数据时,向缓存中设置一个空对象,设置较短的过期时间,避免占用过多内存。
- 布隆过滤器:
- 使用布隆过滤器过滤不存在的数据,减少对数据库的无效查询。
- 参数校验:
- 对用户输入的参数进行严格的校验,防止恶意请求或爬虫攻击。
- 缓存空对象:
3.2 缓存击穿
- 问题描述:
- 热点数据过期后,大量并发请求直接访问数据库,导致数据库压力骤增。
- 解决方法:
- 设置热点数据永不过期:
- 对于某些热点数据,可以配置为永不过期,确保这些数据始终在缓存中。
- 互斥锁:
- 使用分布式锁(如Redis的
SETNX
命令),确保只有一个请求能访问数据库,其余请求等待,防止数据库被压垮。
- 使用分布式锁(如Redis的
- 后台刷新:
- 开启后台线程,定期更新热点数据的缓存,避免因缓存失效导致的并发请求。
- 分级缓存:
- 使用多级缓存策略,如一级缓存和二级缓存,确保数据在多级缓存中有效,减少对数据库的直接访问。
- 设置热点数据永不过期:
3.3 缓存雪崩
- 问题描述:
- 大量缓存同时过期,导致短时间内有大量请求直接打到数据库,可能引起数据库宕机。
- 解决方法:
- 随机过期时间:
- 在设置缓存过期时间时,加上一个随机的时间值,避免大量缓存集中过期。
- 互斥锁或队列:
- 使用互斥锁或队列控制对数据库的并发访问,防止大量请求同时访问数据库。
- 二级缓存:
- 建立二级缓存层,当主缓存失效时,从二级缓存中获取数据,减少对数据库的压力。
- 数据预热:
- 在缓存过期前,主动刷新和更新缓存,确保热点数据始终存在于缓存中。
- 监控与预警:
- 实时监控缓存的命中率和请求量,及时发现潜在的问题,提前采取措施。
- 随机过期时间: