redis
一、安装与配置 redis
1. 下载安装包
2. 上传到 linux 服务器并解压缩
1 | |
3. 安装依赖
1 | |
4. 编译
1 | |
编译成功:Hint: It’s a good idea to run ‘make test’ ;)
5. 安装
1 | |
6. 配置
进入 utils 目录,拷贝 redis 启动脚本
1
cp redis_init_script /etc/init.d/修改 redis 核心配置文件
redis.conf拷贝配置文件
1
2
3
4
5
6
7mkdir /usr/local/redis
cp redis.conf /usr/local/redis/
cd /usr/local/redis
vim redis.conf修改相关配置
参数 默认值 描述 推荐设置 daemonize no 是否后台启动 yes dir ./ 工作目录 /usr/local/redis/working bind 127.0.0.1 绑定的ip 0.0.0.0 requirepass foobared 访问密码 自定义即可 port 6379 端口号 6379 修改启动脚本
redis_init_script参数 默认值 描述 推荐设置 REDISPORT 6379 端口号 若要修改去 redis.conf中修改即可 CONF CONF=”/etc/redis/${REDISPORT}.conf” 启动指定的配置文件 /usr/local/redis/redis.conf 赋权限
1
chmod 777 redis_init_script启动
1
./redis_init_script start停止
1
./redis_init_script stop停止时会提示没有认证!
修改脚本文件如下:1
$CLIEXEC -a "密码" -p $REDISPORT shutdown设置 redis 开机自启动
1
2
3
4
5
6
7
8
9
10
11
12vim redis_init_script
# 新增脚本
# !/bin/bash
# chkconfig: 22345 10 90
# description: Start and Stop redis
# 注册开机自启动
chkconfig redis_init_script on
# 重启测试
reboot
二、redis 持久化机制
1. RDB
Redis DataBase
RDB 概念:每隔一段时间,把内存中的数据写入磁盘的临时文件,作为快照,恢复的时候把快照文件读进内存。如果宕机重启,那么内存里的数据肯定会没有的。
备份与恢复: 内存备份 –> 磁盘临时文件 –> 恢复到内存
RDB优劣势
- 优势
- 每隔一段时间备份,全量备份
- 灾备简单,可以远程传输
- 子进程备份的时候,主进程不会有任何 io 操作(不会有写入修改或删除),保证备份数据的的完整性
- 相对 AOF 来说,当有更大文件的时候可以快速重启恢复
- 劣势
- 发生故障时,有可能会丢失最后一次的备份数据
- 子进程所占用的内存比会和父进程一模一样,如会造成 CPU 负担
- 由于定时全量备份是重量级操作,所以对于实时备份,就无法处理了。
- 优势
RDB的配置
- 保存位置,可以在redis.conf自定义:
dbfilename dump.rdb
dir /user/local/redis/working - 保存机制:
1
2
3
4save 900 1
save 300 10
save 60 10000
save 10 31
2
3
4
5* 如果 1 个缓存更新,则 15 分钟后备份
* 如果 10 个缓存更新,则 5 分钟后备份
* 如果 10000 个缓存更新,则 1 分钟后备份
* 演示:更新 3 个缓存,10 秒后备份
* 演示:备份 dump.rdb,删除重启 - stop-writes-on-bgsave-error
yes:如果 save 过程出错,则停止写操作
no:可能造成数据不一致 - rdbcompression
yes:开启rdb压缩模式
no:关闭,会节约 cpu 损耗,但是文件会大,道理同 nginx - rdbchecksum
yes:开启校验,性能损耗 10%
no:关闭,节约性能
- 保存位置,可以在redis.conf自定义:
2.AOF
Append Only File
引子:RDB 会丢失最后一次备份的 rdb 文件,但是其实也无所谓,其实也可以忽略不计,毕竟是缓存,丢了就丢了,但是如果追求数据的完整性,那就的考虑使用 AOF 了
AOF 特点
- 以日志的形式来记录用户请求的写操作。读操作不会记录,因为写操作才会存存储。
- 文件以追加的形式而不是修改的形式。
- redis 的 aof 恢复其实就是把追加的文件从开始到结尾读取执行写操作。
优势
- AOF 更加耐用,可以以秒级别为单位备份,如果发生问题,也只会丢失最后一秒的数据,大大增加了可靠性和数据完整性。所以 AOF 可每秒同步一次,使用 fsync 操作。
- 以 log 日志形式追加,如果磁盘满了,会执行 redis-check-aof 工具
- 当数据太大的时候,redis 可以在后台自动重写 aof。当 redis 继续把日志追加到老的文件中去时,重写也是非常安全的,不会影响客户端
作。 - AOF 日志包含的所有写操作,会更加便于 redis 的解析恢复。
劣势
- 相同的数据,同一份数据,AOF 比 RDB 大
- 针对不同的同步机制,AOF 会比 RDB 慢,因为 AOF 每秒都会备份做写操作,这样相对于 RDB 来说就略低。 每秒备份 fsync 没毛病,但是如果每次写入就做一次备份 fsync 的话,那么 redis 的性能就会下降。
- AOF 发生过 bug,就是数据恢复的时候数据不完整,这样显得 AOF 会比较脆弱,容易出现 bug,因为 AOF 没有 RDB 那么简单,防止 bug 的产生,AOF 就不会根据旧的指令去重构,而是根据当时缓存中存在的数据指令去做重构,这样就更加健壮和可靠了。
AOF的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14# AOF 默认关闭,yes可以开启
appendonly no
# AOF 的文件名
appendfilename "appendonly.aof"
# no:不同步
# everysec:每秒备份,推荐使用
# always:每次操作都会备份,安全并且数据完整,但是慢性能差
appendfsync everysec
# 重写的时候是否要同步,no可以保证数据安全
no-appendfsync-on-rewrite no
# 重写机制:避免文件越来越大,自动优化压缩指令,会 fork 一个新的进程去完成重写动作,新进程里的内存数据会被重写,此时
# 当前 AOF 文件的大小是上次 AOF 大小的 100% 并且文件体积达到 64m,满足两者则触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
3.到底采用 RDB 还是 AOF 呢?
- 如果你能接受一段时间的缓存丢失,那么可以使用 RDB,可能会丢失最后一次备份数据
- 如果你对实时性的数据比较 care,那么就用 AOF,最多损失 2 秒的数据(每秒备份)
- 先加载 AOF,然后加载 RDB,如果 AOF 损坏,则删除掉后使用 RDB 恢复即可
三、redis 主从复制
1. 查看 replication 信息
1 | |
1 | |
2. 修改配置,设置为从节点
1 | |
重启 redis 使之生效!
3. 无磁盘化复制
定义:master 创建一个进程写入 rdb 文件到内存而不是磁盘
场景:网络好,硬盘读写差的情况
开启配置:
1 | |
四、哨兵机制 sentinel
作用:针对 redis 主从复制机器宕机处理
拷贝配置文件
1
2cd /home/install/redis
cp sentinel.conf /usr/local/redis/sentinel.conf进行相关配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# 关闭保护模式
protected-mode no
# 后台启动
daemonize yes
# 日志存放位置
logfile /usr/local/redis/sentinel/redis-sentinel.log
# 工作目录
dir /usr/local/redis/sentinel
# 监控的 master, 2 为 quorum:至少多少台哨兵发现 master 宕机
sentinel monitor master-135 192.168.88.135 6379 2
# master 密码
sentinel auth-pass master-132 123456
# 判断 master down 时间(毫秒), 10 秒,默认 30 秒
sentinel down-after-milliseconds master-132 10000
# 并发同步数量,默认 1,某一个 slave 被选举为 master后,其他 slave 从新的 master 同步数据
sentinel parallel-syncs master-132 1
# 故障转移超时时间(毫秒),默认 3 分钟
sentinel failover-timeout master-132 180000拷贝 sentinel.conf 到其他服务器
1
scp sentinel.conf root@192.168.88.135:/usr/local/redis/启动
1
redis-sentinel sentinel.confSpringBoot 整合哨兵
1
2
3
4
5
6
7
8
9
10
11
12
13spring:
redis:
#单机单实例
#database: 1
#host: 192.168.88.135
#password: 123456
#port: 6379
#哨兵机制
database: 1
password: 123456
sentinel:
master: master-132
nodes: 192.168.88.135:26379,192.168.88.136:26379,192.168.88.137:26379
五、redis 缓存过期机制 & 内存淘汰机制
缓存过期机制:设置过 expire 的 key 过期后
(主动)定期删除:定期定时检查
1
2# 每秒钟检查 10 次,1-500范围,过大对于 cpu 消耗大
hz 10(被动)惰性删除:访问到的 key,若过期则会被删除
内存淘汰管理
- 最大内存配置,超出则使用淘汰策略
1
maxmemory <bytes> - 策略
v 开头的都是针对设置过 expire 的 key。1
2
3
4
5
6
7
8# volatile-lru -> Evict using approximated LRU among the keys with an expire set.(最近最少使用到的 key 被淘汰)
# allkeys-lru -> Evict any key using approximated LRU.(最近最少使用到的 key 被淘汰)
# volatile-lfu -> Evict using approximated LFU among the keys with an expire set.(最少使用到的 key 被淘汰)
# allkeys-lfu -> Evict any key using approximated LFU.(最少使用到的 key 被淘汰,推荐)
# volatile-random -> Remove a random key among the ones with an expire set.(随机的 key 被淘汰)
# allkeys-random -> Remove a random key, any key.(随机的 key 被淘汰)
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)(最接近过期时间的 key 被淘汰)
# noeviction -> Don't evict anything, just return an error on write operations.(不淘汰,返回错误,不推荐)
六、redis 集群
1. 背景
- 主从复制以及哨兵,他们可以提高读的并发,但是单个 master 容量有限,数据达到一定程度会有瓶颈,这个时候可以通过水平扩展为多 master 集群。
- redis-cluster:他可以支撑多个 master-slave,支持海量数据,实现高可用与高并发。
- 哨兵模式其实也是一种集群,他能够提高读请求的并发,但是容错方面可能会有一些问题,比如 master 同步数据给 slave 的时候,这其实是异步复制吧,这个时候 master 宕机了,那么 slave上 的数据就没有 master 新,数据同步需要时间的,1-2 秒的数据会丢失。master 恢复并转换成 slave 后,新数据则丢失。
2. 特点
- 每个节点知道彼此之间的关系,也会知道自己的角色,当然他们也会知道自己存在与一个集群环境中,他们彼此之间可以交互和通信。那么这些关系都会保存到某个配置文件中,每个节点都有,这个我们在搭建的时候会做配置的。
- 客户端要和集群建立连接的话,只需要和其中一个建立关系就行。
- 某个节点挂了,也是通过超过半数的节点来进行的检测,客观下线后主从切换,和我们之前在哨兵模式中提到的是一个道理。
- Redis 中存在很多的插槽,又可以称之为槽节点,用于存储数据,这个先不管,后面再说。
3. 集群容错
- 构建 Redis 集群,需要至少 3 个节点作为 master,以此组成一个高可用的集群,此外每个 master 都需要配备一个 slave,所以整个集群需要 6 个节点,这也是最经典的 redis 集群,也可以称之为三主三从,容错性更佳。所以在搭建的时候需要有 6 台虚拟机。请各自准备 6 台虚拟机,可以通过克隆去构建,使用单实例的Redis 去克隆即可
- 集群也可以在单服务器构建,称之为伪集群,但是生产环境肯定是真的,所以建议用 6 台。
- 克隆后务必关闭Redis。
4. 构建 Redis 集群
redis.conf 配置
1
2
3
4
5
6
7
8# 开启集群模式
cluster-enabled yes
# 每一个节点需要有一个配置文件,需要 6 份。每个节点处于集群的角色都需要告知其他所有节点,彼此知道,这个文件用于存储集
cluster-config-file nodes-201.conf
# 超时时间,超时则认为 master 宕机,随后主备切换
cluster-node-timeout 5000
# 开启 AOF
appendonly yes启动 6 个 redis 实例
- 启动 6 台
- 如果启动过程出错,把 rdb、aof 等文件删除清空
创建集群
1
2
3
4
5
6#####
# 注意1:如果你使用的是 redis3.x 版本,需要使用 redis-trib.rb 来构建集群,最新版使用 C 语言来构建了,这个要注意
# 注意2:以下为新版的 redis 构建方式
#####
# 创建集群,主节点和从节点比例为1,1-3 为主,4-6 为从,1 和 4,2 和 5,3 和 6 分别对应为主从关系,这也是最经典用的最多的集群模式
redis-cli --cluster create ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6 --cluster-replicas 1slots:槽,用于装数据,主节点有,从节点没有
检查集群信息
1
redis-cli --cluster check 192.168.25.64:6380SpringBoot 集成 redis 集群
1
2
3
4
5spring:
redis:
password: 123456
cluster:
nodes: ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6
七、缓存穿透与雪崩
1. 缓存穿透
定义:查询的 key 在 redis 中不存在,在数据库中也不存在,此时被非法用户攻击,大量请求被打到数据库上,造成宕机,从而影响整个系统,这种现象称之为缓存穿透
解决方案一:将空值也放入缓存,比如空字符串、空数组、空对象或空 list
解决方案二:布隆过滤器,可以快速的判断一个元素是否在一个集合中
2. 雪崩
定义:大量的 key 同一时间过期,大量请求直接打到数据库,造成宕机
预防:
- 永不过期
- 过期时间错开
- 多缓存结合:redis + memcache …
- 采购第三方 redis:阿里云、腾讯云…
八、批量查询优化
常规做法:
1 | |
1. multiGet
1 | |
2. pipeline
1 | |
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!