resdis
2021-05-29 13:29:34 8 举报
AI智能生成
redis总结。 可参考 黑马公开课 后续补齐redis的实现原理
作者其他创作
大纲/内容
主从复制
三高架构
高并发
高性能
高可用
单位时间内能尽可能长时间的提供服务
redis单机的高可用限制
单机故障
硬盘/系统崩溃
数据丢失
容量瓶颈
内存不足
职责分类
master
写数据
写操作,自动同步到slave端
读数据(可忽略)
slaver
读数据
写(禁止)
核心问题:数据同步—master数据复制到slave中
主从复制的好处
读写分离:提高服务器的读写负载能力
负载均衡:多个从节点分担数据读取负载,大大提高Redis服务器并发量与数据吞吐量
故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复
数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式
高可用基石: 基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案
主从复制流程
建立连接
数据同步
全量复制是一个RDB过程,部分复制时一个AOF过程
runid
服务器运行ID是每一台服务器每次运行的身份识别码,由40个随机字符组成
服务器之间传递,必须每次操作携带对应的运行id,用于对方识别
复制积压缓冲区
对master来说每个slave对应一个复制缓冲区,一个FIFO的队列
保存master收到的所有指令(仅影响数据变更的指令,例如set, select)
master收到数据修改的指令,通过aof的方式刷写到slave中,复制缓冲区就作为aof的缓存
offest
用于标志slave与master之间数据的差异
命令传播
心跳机制:master与slave间需要进行信息交换,实现双方连接保持在线
master心跳
PING,周期一般10s(需要维护多个slave),由repl-ping-period决定
判断slave是否在线
可通过info replication查询slave最后一次连接时间间隔,lag为0/1正常
slave心跳
REPLCONF ACK {offset},1s,汇报自己的偏移量,以获取最新数据
判断master是否在线
基于心跳机制的命令传播
常见问题
频繁全量复制
master重启导致的全量复制
重启前,master通过RDB进行offest与runid的持久化
网络不佳导致的复制缓冲区溢出
修改复制缓冲区的大小repl-backlog-size
1. 测算从master到slave的重连平均时长second
2. 获取master平均每秒产生写命令数据总量write_size_per_second
3. 最优复制缓冲区空间 = 2 * second * write_size_per_second
2. 获取master平均每秒产生写命令数据总量write_size_per_second
3. 最优复制缓冲区空间 = 2 * second * write_size_per_second
频繁网络中断
slave频繁断开,master的cpu占用过高
slave与master断开
master的平频率过低
子主题
slave间数据不一致
监控主从节点延迟(通过offset)判断,如果slave延迟过大,暂时屏蔽程序对该slave的数据访问
slave-serve-stale-data yes|no
优化主从间的网络环境,通常放置在同一个机房部署,如使用阿里云等云服务器时要注意此现象
哨兵模式
简介
哨兵(sentinel) 是一个分布式系统,用于对主从结构中的每台服务器进行监控,当master出现故障时通过投票机制选择新的
master并将所有slave连接到新的master
master并将所有slave连接到新的master
哨兵作用—主从切换
哨兵也是一台redis服务器,只是不提供数据服务,通常哨兵配置数量为单数(便于投票)
流程
监控
监控master与slave是否正常运行
master存活检测,m,s运行状况检测
master存活检测,m,s运行状况检测
流程
sentinel首先通过info指令建立cmd连接获取master中信息(master,slave list,sentinel list)
通过sentinel list建立publish subscribe连接哨兵,对方添加sentinel list
通过 slave list建立cmd连接,获取slave的详细值(runid/offset/masterhost...)
通知
当被监控的服务器出现问题时, 向其他(哨兵间,客户端) 发送通知。
流程
任何哨兵都与主从连接。此时哨兵会定时询问查询主从的连接状态。
但任一哨兵获得连接状态,便在哨兵内传输
但任一哨兵获得连接状态,便在哨兵内传输
自动故障转移
断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服
务器地址
流程
标记下线
sentinel询问master,如无响应则反复询问,后主观标记其下线
该sentinel将故障信息传递给其余哨兵,其余哨兵对其询问
(若是哨兵故障标记主机下线,则无法在哨兵间泛洪)
(若是哨兵故障标记主机下线,则无法在哨兵间泛洪)
哨兵中超过半数认为master挂机,则标记为客观下线。标记完成
选取主sentinel用于处理master下线
所有哨兵参与竞选广播自己的信息,每轮竞选次数 + 1;
重新连接
重新选择master原则
1 在线
2 响应快
3 与原master断开时间短
4 优先原则
优先级高
offest
runid小
流程
确定为master:向新的master发送slaveof no one
连接新master:向其他slave发送slaveof 新masterIP端口
失效master重新恢复?
作为slave加入
集群
使用网络将若干台计算机联通起来,并提供统一的管理方式,使其对外呈现单机的服务效果
分散单台服务器的访问压力,实现负载均衡
分散单台服务器的存储压力,实现可扩展性
降低单台服务器宕机带来的业务灾难
原理
将所有的存储空间计划切割成16384份(非每个key),每台主机保存一部分
各个服务器将相互通信,保存各自槽的编号范围
放置时:计算出key应该保存的位置
1 CRC16循环冗余检测,获得一个类hash值
取模hash % 16384,获得槽位
获取时:一次命中返回,未命中,告知具体位置
增减节点(服务器)如何处理 — 一致性hash
一致性hash图解
服务器在一个环中,若hash命中则由其负责,若未命中则顺时针下一个负责
若某个节点失效(B),则顺延到下一个负责(C)
redis崩溃预防
缓存预热
服务器启动后迅速宕机
请求数高
主从将同步频率高,吞吐量大
解决方案
缓存预热就是系统启动前, 提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓
存的问题!用户直接查询事先被预热的缓存数据!
存的问题!用户直接查询事先被预热的缓存数据!
缓存雪崩
缓存雪崩就是瞬间 过期 数据量太大,导致对数据库服务器造成压力。如能够有效避免过期时间集中,可以有效解决雪崩现象的出现
(约40%),配合其他策略一起使用,并监控服务器的运行数据,根据运行记录做快速调整。
(约40%),配合其他策略一起使用,并监控服务器的运行数据,根据运行记录做快速调整。
方案
限制上游流量
js过滤,页面静态化处理 + 消息队列
多级缓存
nginx + redis + ehcache
性能监控机制
redis的努力
LRU与LFU切换使用
分期过期 + (固定过期 + 随机值),稀释集中过期key数量
超热数据永久化
缓存击穿
缓存击穿就是单个高热数据过期的瞬间,数据访问量较大,未命中redis后,发起了大量对同一数据的数据库访问,导致对数据库服
务器造成压力。
务器造成压力。
解决方案
提前设定,例如电商销量等
redis监控,现场调整key过期时间
添加二级缓存(防key过期后,对单key的大量访问)
缓存穿透
缓存击穿访问了不存在的数据,跳过了合法数据的redis数据缓存阶段,每次访问数据库,导致对数据库服务器造成压力。
策略
缓存key
白名单策略
布隆过滤器
布隆过滤器是一个二进制数组
首先对数组进行添加,经过不同的hash算法,分布到二进制数组中,设置为1
判断一个数是否存在,即经历所有的hash算法,若获得的所有数字都为1则认为该数字存在
bitmap
监控命中率与null占比
key加密
性能监控
什么是redis
抢购/秒杀服务崩溃
原因
海量用户
高并发
本质
关系型数据库的奔溃MySQL
性能瓶颈:磁盘IO
扩展瓶颈:数据关系复杂,可扩展性差
解决思路
NoSQL
含义
No-Only-SQL,作为关系型数据库的补充
特征
可扩容,可伸缩
大数据量下高性能
灵活的数据模型
高可用
子主题
常见NoSQL
Redis
memcache
HBase
MongoDB
memcache
HBase
MongoDB
基本操作
功能性命令
清屏
clear
帮助
help @ + tab 按群组查询
help command
退出
exit
quit
特征
数据间没有必然的关联关系
内部采用单线程机制进行工作
高性能
持久化支持。可以进行数据灾难恢复
常用数据结构
什么叫redis内数据结构
redis 自身是一个 Map,其中所有的数据都是采用 key : value 的形式存储
数据类型指的是存储的数据的类型,也就是 value 部分的类型, key 部分永远都是字符串
string
储存内容
通常使用字符串
字符串以整数的形式展示,可以作为数字操作使用,最大数值为long.MAX_VALUE
基本操作
set age 25 EX 10
带超时的设置
setex age 10 30
设置过期为10s
mset age 25 EX 20 name wangkang
带超时的多个设置
increby age 10
incre age
increbyfloat age 1.5
incre age
increbyfloat age 1.5
decrby age 10
decr age
decr age
规范性使用使用方式
表名:主键名:主键值:字段
表名:主键名:主键值:字段
set user:id:25506:fans 35533
set user:id:25506:blog 323
set user:id:25506:follow 68
set user:id:25506:blog 323
set user:id:25506:follow 68
sset user:id:25506 {fans:35533, blog:323, follow:68}
hash
储存模型
可用来对string 储存的json数据进行优化
基本操作
hset user:id:23 blogs 324
hget
hgetall
hdel
hget
hgetall
hdel
hmset user:id:23 fans 233 blogs 32
hmget
hmget
hincrby key filed value
hdecrby key filed value
hdecrby key filed value
hlen
hexists key filed
hkeys
hvals
hexists key filed
hkeys
hvals
应用场景
set
储存模型—hash的屏蔽
将hash的value屏蔽
基本操作
sadd users wangk tangx
smembers users
srem users tangx
smembers users
srem users tangx
scard users 获得总数
sismember users tangx
sismember users tangx
随机获取
srandmember users 3 users中随机获取3个值
spop users 3随机去除3个值。
交并差
注意差集
sinter users fans
sunion users fans
sdiff users fans
sunion users fans
sdiff users fans
数据储存转移
sinterstore inter users fans
sunionstore union users fans
sdiffstore diff users fans
sunionstore union users fans
sdiffstore diff users fans
可用来做简单的角色权限合并校验
做权限校验时,是使用sismember还是smermember将数据返回那?
应当将数据返回,返回后在业务层对数据校验!这样数据与业务分离,耦合度降低!
数据转移
smove union diff wangk 将wangk数据从union转移到diff
应用场景
访问统计
统计网站的PV(访问量) ,UV(独立访客) ,IP(独立IP)。
PV:网站被访问次数,可通过刷新页面提高访问量,通过string incr统计即可
UV:网站被不同用户访问的次数,可通过cookie统计访问量,相同用户切换IP地址, UV不变
IP:网站被不同IP地址访问的总次数,可通过IP地址统计访问量,相同IP不同用户访问, IP不变
PV:网站被访问次数,可通过刷新页面提高访问量,通过string incr统计即可
UV:网站被不同用户访问的次数,可通过cookie统计访问量,相同用户切换IP地址, UV不变
IP:网站被不同IP地址访问的总次数,可通过IP地址统计访问量,相同IP不同用户访问, IP不变
权限控制
校色权限认证
黑白名单
基于经营战略设定问题用户发现、鉴别规则
周期性更新满足规则的用户黑名单,加入set集合
用户行为信息达到后与黑名单进行比对,确认行为去向
黑名单过滤IP地址:应用于开放游客访问权限的信息源
黑名单过滤设备信息:应用于限定访问设备的信息源
黑名单过滤用户:应用于基于访问权限的信息源
sort_set
储存模型—set的魔改
多一列score
score并不是用于存储数据,只是用来排序使用
基本操作
zadd key score member
zrange key start end 顺序查询[start, end],0开始
zrevrange key start end withscores
zrem key member
zrange key start end 顺序查询[start, end],0开始
zrevrange key start end withscores
zrem key member
按score范围
zrangebyscore key min max [WITHSCORES] [LIMIT]
zrevrangebyscore key max min [WITHSCORES]
zremrangebyrank key start stop
zremrangebyscore key min max
zrevrangebyscore key max min [WITHSCORES]
zremrangebyrank key start stop
zremrangebyscore key min max
应用场景
榜单排名
带有权重的任务队列
对于带有权重的任务,优先处理权重高的任务,采用score记录权重即可
多条件任务权重设定如果权重条件过多时,需要对排序score值进行处理,保障score值能够兼容2条件或者多条件.
例如外贸订单优先于国内订单,总裁订单优先于员工订单,经理订单优先于员工订单
因score长度受限,需要对数据进行截断处理,尤其是时间设置为小时或分钟级即可(折算后)
先设定订单类别,后设定订单发起角色类别,整体score长度必须是统一的,不足位补0。第一排序规则首位不得是0
例如外贸订单优先于国内订单,总裁订单优先于员工订单,经理订单优先于员工订单
因score长度受限,需要对数据进行截断处理,尤其是时间设置为小时或分钟级即可(折算后)
先设定订单类别,后设定订单发起角色类别,整体score长度必须是统一的,不足位补0。第一排序规则首位不得是0
注意组合权重时,需要保证多条件的数据对其,补0操作
限时服务
对于基于时间线限定的任务处理,将处理时间记录为score值,利用排序功能区分处理的先后顺序
记录下一个要处理的时间,当到期后处理对应任务,移除redis中的记录,并记录下一个要处理的时间
当新任务加入时,判定并更新当前下一个要处理的任务时间
为提升sorted_set的性能,通常将任务根据特征存储成若干个sorted_set。例如1小时内, 1天内,周内,
月内,季内,年度等,操作时逐级提升,将即将操作的若干个任务纳入到1小时内处理的队列中
记录下一个要处理的时间,当到期后处理对应任务,移除redis中的记录,并记录下一个要处理的时间
当新任务加入时,判定并更新当前下一个要处理的任务时间
为提升sorted_set的性能,通常将任务根据特征存储成若干个sorted_set。例如1小时内, 1天内,周内,
月内,季内,年度等,操作时逐级提升,将即将操作的若干个任务纳入到1小时内处理的队列中
分段处理
list
存储模型
底层采用双向链表,维护一个头指针与尾指针
强调顺序,可左右取值与添加
哪边是头,哪边是尾巴?
一般选取左进右出
基本操作
添加
获取
删除
子主题
带时限的删除
使用场景
点赞列表维护/关注列表维护
新闻列表按时间维护
特殊数据结构
与常用数据结构的区别
bitmap
布隆过滤器
HyperLogLog
GEO
通用操作
keys
配置文件
关于服务器
daemonize yes|no 守护线程
bind 127.0.0.1 绑定主机地址
port 6379 绑定端口号
databases 16 数据库数量
关于日志配置
loglevel debug|verbose|notice|warning
日志级别开发期设置为verbose即可,生产环境中配置为notice,简化日志输出量,降低写日志IO的频度
logfile 端口号.log 日志文件名
关于客户端配置
maxclients 0 (默认无限制)同一时间客户端链接上限。超过server关闭新连接
timeout 300 客户端闲置等待最大时长,达到最大值后关闭连接。
持久化
什么是持久化
利用磁盘永久存储数据,在特定时间恢复
防止数据意外丢失。
持久化分类
快照存储RDB
逻辑存储AOF
RDB
常用指令
save
阻塞redis线程
bgsave
后台开启子线程,异步存储
配置启动
redis-server conf/reids-6973.conf
常用配置
dbfilename dump.rdb
dir location
save second changes
配置保存设置(bgsave)
rdbcompression yes
开启数据压缩(默认yes)
rdbchecksum yes
数据校验(开启损失性能)
stop-writes-on-bgsave-error yes
储存中error,停止保存
优劣
优点
快照,全量复制
恢复数据快
缺点
无法实时持久化IO性能低,数据丢失可能性大
每次bgsave启动子线程,牺牲性能
各版本不兼容现象
AOF
逻辑存储,记录数据更改的指令
写数据的策略
always
数据零误差,性能低,不建议
everysec
数据准确性较高, 性能较高,建议使用,也是默认配置
no
操作系统控制AOF周期
整体不可控
数据重写
相对于RDB有数据压缩,AOF采取数据重写的方式减少储存量
降低磁盘占用
提高持久化效率,提高IO性能
提高数据恢复的速度
重写规则
对已超时的数据不在写入文件
忽略无效指令
增改没有的数据
多次对同一数据修改,只保留最后一条指令
对同一key的多个命令,合并为一个(mult)
重写方式
手动重写bgrewriteaof
配置自动重写
对比参数可通过 info指令查询,aof_current_size为缓存中数据大小
aof_base_size为基础大小,默认系统指定
aof_base_size为基础大小,默认系统指定
重写流程
达到重写条件(配置),重写并覆盖掉原文件
常用配置
配置参数
appendonly yes
开启aof
appendfsync everysec|no|always
写数据策略
dbfilename dump-6793.aof
dir location
auto-aof-rewrite-percentage percentage 30
auto-aof-rewrite-min-size size 64mb
RDB与AOF区别
如何选择
对数据非常敏感
AOF -存储策略可设置为everysec,保证性能的同时,保证数据最多丢失1s,恢复速度慢
数据阶段有效性
保证阶段内有效/容忍数分钟的数据丢失,恢复速度快。性能可能低。
灾难恢复
RDB
双保险策略
同时开启,重启后redis优先采取aof恢复,降低丢失
事务
防止被其他指令打断/干扰
事务实现
工作流程
维护一个队列,但exec提交后同一执行
出现错误
语法错误
销毁队列
逻辑错误
正确的执行,错误的跳过,无回滚
常用解决办法(手动回滚)
记录修改之前的状态缓存下来
出现错误,单数据set回去,多数据克隆回去。
常用指令
multi
开启事务,创建队列
exec
提交事务,执行队列
discard
销毁队列
锁
监控锁
watch key
监控到key发生变化,本线程终止事务执行
但多个client操作共享变量时,都首先获得 lock,再开启事务。但事务完成,修改lock,其余client便事务失败。
分布式锁
监控锁只能用作监控,而无法控制其余线程修改共享变量(共享),分布式锁解决
setnx lock-name value
获得锁后便可以操作,其余线程无法获得lock-name。事务完成后 del lock-name即可
需要规定多个线程都申请同一把锁才可生效
删除策略
数据过期
设置数据的有效期
expire key value 倒计时秒
pexpire key value 倒计时秒
pexpire key value 倒计时秒
expireat key timestamp 倒计时时间戳
pexpireat key timestamp精确到毫秒
pexpireat key timestamp精确到毫秒
内存模型
查看有效期
ttl key
正数-剩余销毁时间
-1 永久有效
-2 已过期/删除/未定义数据
数据删除策略
目标:平衡内存占用与CPU的占用
定时
设置定时器到达过期时间则删除。
节约内存,占用cpu性能。时间换空间
适用于cpu更强的
懒惰
内部调用expireIfNeed()函数数据过期,不做处理。
访问:未过期则返回
过期删除数据
过期删除数据
适用于cpu弱,内存大
定期
特点
随机抽查,重点抽查
cpu检测频率可自行设置,内存压力也不大
流程
Redis启动,读取配置hz(10),每秒钟执行hz次serverCron库的轮询
配置文件 hz =10
info (server)查询hz值
cerverCron->databasesCron单个库轮询->activeExpireCyde()库内随机抽查
随机检测W个key,key超时则删除
W由配置文件中ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP确定
每轮删除key> W*0.25则循环本数据库
小于则跳到下一个库
逐出算法(GC)
redis执行命令前,都会调用freeMemoryIfNeeded()检测是否充足
若内存不足则执行逐出算法
否则,OOM
8种删除策略
检测易失数据(可能过期的数据集server.db[i].expires)
volatile-lru:挑选最近最少使用的数据淘汰
实现算法双向链表 + map
get获取:从map查找,有则从链表中删除,插入到头部
put放置:从map查找,有则从链表中删除,插入到头部
map中没有,则查看缓存容量。若超出,删除尾部Node。
插入到头部
map中没有,则查看缓存容量。若超出,删除尾部Node。
插入到头部
内部属性与构造器
get方法
put方法
volatile-lfu:挑选最近使用次数最少的数据淘汰
volatile-ttl:挑选将要过期的数据淘汰
volatile-random:任意选择数据淘汰
检测全库数据
allkeys-lru:挑选最近最少使用的数据淘汰
allkeys-lfu:挑选最近使用次数最少的数据淘汰
allkeys-random:任意选择数据淘汰
放弃数据驱逐
no-enviction(驱逐):禁止驱逐数据( redis4.0中默认策略),会引发错误OOM( Out Of Memory)
配置参数
maxmemory 最大可用内存
maxmemory-samples 每次选取待删除的个数
maxmemory-policy 删除策略
0 条评论
下一页