Redis
2021-10-27 16:17:21 19 举报
AI智能生成
登录查看完整内容
Redis基础知识 Redis部分进阶知识
作者其他创作
大纲/内容
cd /usr/localmkdir softwaretar -zxvf xxx.tar.gz
打开阿里云把文件copy到software里面
yum install gcc-c++
安装gcc-c++
cd usr/local/software/redis-5.0.10/depsmake hiredis lua jemalloc linenoise
编译依赖
cd /usr/local/software/redis-5.0.10make
编译Redis
mkdir -p /usr/local/redismake install PREFIX=/usr/local/redis (将redis 安装在该目录里面)
安装编译之后的文件
cd /usr/local/redis/binls
验证安装是否成功
修改daemonize为yes 后台运行
修改bind 为0.0.0.0
将解压后的redis配置文件copy到/usr/local/redis文件夹下
Redis的安装
这里的单线程只是在网络IO和键值对读写上是单线程,其他处理还是会使用多线程,例如AOF
想使用一个单线程去支持高并发,那么线程就不能阻塞
io多路复用技术
让一个线程去管理多个连接
redis里面是单线程,想支持并发连接怎么办
redis是单进程单线程模型,避免了线程的切换,可以避免锁,
redis的大量操作是在操作内存
io多路复用
1、纯内存
2、非阻塞IO
3、避免线程切换和竞态消耗
redis是单线程,为什么这么快
1、一次只运行一条命了
2、拒绝长命令或者慢命令
fysnc
close
3、redis并不是所有操作都是单线程
注意事项
Redis是非关系型数据库,数据与数据之间没有联系
可以通过多开Redis实例完善
无法发挥多核cpu的性能
缺点
比如cpu要到磁盘读取数据,cpu就需要等待磁盘将数据放入内存 ,这段时间很长,多线程的话CPU就不需要等待,直接去处理其他的请求,等到磁盘的数据到内存中,再来处理该数据
平衡计算机硬件之间的差异
为什么需要多线程
单线程
2、Redis的数据保存在内存中
3、Redis的读写操作是单线程的
1、速度快
1、Redis所有的数据保存在内存中,对数据的更新将异步地保存到磁盘中
2、Redis提供类RDB和AOF进行持久化操作
2、持久化
1、Redis是基于key-value操作的
2、Redis支持String、Hash、List、Set、sorted set等数据结构
3、还支持BitMaps(位图)、HyperLogLog(超小内存唯一值计数)、GEO(地理信息定位)等数据给是
3、支持多种数据结构
1、Java
2、Php
3、c
4、支持多种编辑语言
1、发布订阅
2、事务
3、Lua脚本
4、pipeline
5、功能丰富
1、Redis分为单机版和集群版
2、不依赖外部库
3、redis依赖于单线程模型
6、简单
7、主从复制
高可用
分布式
8、高可用、分布式
Redis特性
1、缓存系统
2、计数器
3、排行榜
4、社交网络
5、消息队列
6、实时系统
应用场景
获取当前库的所有key
keys *
删除key
del k
判断是否存在key
exists k
设置key的有效时间
expire k seconds
-1表示key存在,没有过期时间
-2表示key不存在
查看key剩余的过期时间
ttl k
去掉key的过期时间
persist k
key的类型
type key
key的相关命令
切换库
select index
查看当前库key的数量
dbsize
清空当前库
flushdb
清空所有库0-15(不安全)
flushall
db的相关命令
相关命令
可做简单的k-v缓存,实现计数器、分布式锁、session共享、分布式ID生成(自增)
C字符串并不记录自身长度,想获取长度只能遍历
sds直接获取len即可
获取长度
c字符串每次长度变化都会对数组进行内存重新分配,比较耗时
对sds内容进行修改或者需要扩展时,sds有空间预分配和惰性空间释放
内存分配
C字符串不记录自身长度,不会自动进行边界检查,所以会增加溢出的风险
sds先检查空间是否满足修改所需的要求,如果不满足就先扩容再进行修改
缓冲区安全
C字符串是以空字符串(\\0)结尾,所以字符串中不能包含空字符串,只能保存文本数据
既能保存文本数据,也能保存二进制数据(通过长度判断结束,不受影响)
二进制安全
redis底层是C,为什么不用c字符串而用sds
存放一个k-v对
set k v
获得k对应v
get k
存放多个k-v
mset k1 v1 k2 v2 ...
获得多个v
mget k1 k2 k3 ...
当库中有该K时不存。当库中没有改K时存放非常重要(做分布式锁)
setnx k v
获取值之后 修改该K的V
getset k v
该k1对应的v的值++(v必须是Integer类型)
insc k1
该k1对应的v的值--(v必须是Integer类型)
desc k1
设置每次走的步长
inscby k1 步长
descby k1 步长
将value追加到旧到value
append
返回字符串的长度
strlen
增加key对应的值3.5
incrbyfloat key 3.5
获取字符串制定下标的所有值
getrange key start end
设置执行下标所有对应的值
setrange key index value
子主题
1、缓存
3、分布式锁
场景
String
list是一个双向链表
实现高性能的分页
实现栈或队列:例如到货通知、邮件发送、秒杀、保存待抢购的商品列表
应用
列表对象保存的元素数量小于512个
列表对象保存的所有字符串元素长度都小于64个字节
当列表对象痛死满足两个条件时,列表对象使用ziplist进行存储
他将所有的元素紧挨着存储,分配的是一块连续的内存
压缩列表(ziplist)
由于普通链表指针比较浪费空间且会加重内存碎片化,所以优化为quicklist
将多个ziplist使用双向指针串起来(链表+ziplist)
既满足了快速的插入删除性能,又不会出现太大的空间冗余
特点
快速列表(quicklist)
底层实现
从左边放
lpush k v
从右边放
rpush k v
从左边取第一个
lpop k
从右边取第一个
rpop k
从左边取,没取到的话阻塞timeout时间
blpop k timeout
从右边取,没取到的话阻塞timeout时间
brpop k timeout
-1代表倒数第一个
-2 代表倒数第二个
查看队列
page size
(page-1)* size
page*size-1
实现分页
lrange k 0 -1
查看该队列的长度
llen k
lrem k count value
在list指定的值前或者后插入newValue
linsert key before|after value newValue
Lrush+Lpop=stack
Lpush+rpop=queue
Lpush+Ltrim=capped collection
Lpush + Brpop=message queue
相关tips
list
因为对象的属性和值,我们可以认为是一个map集合里面的数据!
map 适合存储对象?
相比于json串,可单独修改对象的字段
可以快速定位,存储的信息需要被频繁的修改可用hash存储,比如实现购物车
存
hset k field value
取
hget k filed
存多个
hmset k field value field value
取多个
hmget k field filed
取得所有的k-v
hgetall k
只取key
hkeys k
只取value
hvals k
删除
hdel k filed
判断hash中key是否有field
hexistsk filed
获取hash key field的数量
hlen key
hset user:1:info pageview count
记录网站每个用户个人主页的访问量
缓存视频的基本信息(数据在mysql中)仿代码
实战
hash
无序唯一
在k的set 集合里面添加一个v,该v 不能重复
sadd k v
随机弹出一个
spop k
K的set集合的所有数据
smembers k
判断key是否在集合中
sismember k
从集合中随机挑count个元素
srandmember
K的set集合的长度
scard k
减集
sdiff k1 k2 (k1-k2)
交集
sinter k1 k2
并集
sunion k1 k2
命令
集合内实战
set
写数据带分数,实现排行榜
添加 可批量添加
zadd k 分数 成员
排行 (从低到高)
zrange k start end
排行 (从高到低)
zreveage k start end
指定分数区间排行(从低到高)
zrangebyscore k 分数的最小值 分数的最大值
删除元素
zrem key leements
返回元素的总个数
zcard key
1、都必须无重复元素
2、集合是无序的,有序集合是有序的
3、集合里面只有元素,有序集合里面有元素+游标
zset和set区别
1、list可以有重复,zset无重复元素
2、list有序,zset有序
zset和list的区别
zset
Redis的数据类型
1、客户端发送命令到服务端
2、排灯等待执行
属于慢查询
客户端超时不一定是慢查询,慢查询一定是客户端超时的一个原因
3、执行命令
3、返回结果到客户端
生命周期
1、慢查询是一个先进先出队列
2、是固定长度的
3、保存在内存中的
config set slowlog-max-len 1000
动态配置
slowlog-max-len
1、慢查询阙值(微秒)
2、等于0,记录所有命令
3、<0 不记录所有命令
config set slowlog-log-slower-than 10000
slowlog-log-slower-than
两个配置
获取慢查询队列
1、slowlog get[n].
获取慢查询队列长度
2、slowlog len
清空慢查询队列
3、slowlog reset
三个命令
1、slowlog-max-len不要设置过大,默认10ms,通常设置1ms
2、slowlog-log-slower-than不要设置过小,通常设置为1000
3、理解命令的生命周期
4、定期持久化慢查询
运维经验
慢查询
发布者
订阅者
频道(channel)
角色
模型
发布订阅和消息订阅对比
发布订阅
Bitmap
geoadd:添加地理位置的坐标。
geopos:获取地理位置的坐标。
geodist:计算两个位置之间的距离。
georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
geohash:返回一个或多个位置对象的 geohash 值。
常用命令
GEO
HyperLogLog
Redis其他操作
Redis事务的本质是一组命令的集合。事务支持一次命令执行多个命令,一个事务中所有的命令都会被序列化
概念
一次性
顺序性
排他性
批量操作在事务提交前放入魂村队列,并不会被实际运行
没有隔离级别的概念
Redis中的单条命令是原子性执行的,但事务不保证原子性,且没有回滚
事务中的任意命令执行失败,其余的命令仍会被执行
不保证原子性
开始事务
命令入队
执行事务
三个阶段
监视key,如果事务在被执行前,被监视的key被改动,则事务执行失败
实现乐观锁
watch k1 k2
标记事务的开始
multi
exec
放弃事务
discard
取消watch对所有key的监控
unwatch
如果在事务队列中出现编译异常(语法错误),则执行exec命令,所有的命令都不会执行
如果在事务队列中出现运行时异常,则执行exec命令,错误命令抛出异常,其他命令正常执行
相关问题
Redis事务
从设置了过期时间的key集合中删除最近没有使用的key
volatile-lru
通过lru算法删除最近没有使用的key
allkeys-lru
从设置了过期时间的key集合中删除最近使用频率最少的key
volatile-lfu
在所有key的集合中 删除最近使用频率最少的key
allkeys-lfu
在设置了过期时间的key的集合中随机删除一个key
volatile-random
在所有key的集合中随机删除一个key
allkeys-random
在设置了过期时间的key集合中删除即将过期的key
volatile-ttl
当超过最大容量,不会删除任何key,返回一个错误
noeviction(Redis默认)
最近没有使用算法
不需要额外的存储空间,使用一个双向连表就能实现
如果一个数据在最近一段时间没有被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最久没有访问的数据最先被置换(淘汰)
LRU(least recently use)算法
最近使用频率最少的key
需要一个能记录key 使用次数的空间,使用ZSet 这样的结构就能实现
如果一个数据在最近一段时间很少被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最小频率访问的数据最先被淘汰
LFU(least recently use)算法
Redis设置maxmemory-policy的方式超过最大的容量后会怎么做
一个key 设置过期时间后(expire k seconds),能自动的删除一个操作将在未来的某个确定时间发生。
订单的过期取消 (下了一个订单,超过30min没有支付,则自动取消)
key的过期删除(给key设置了一个过期时间,到达这个过期时间后,key能自动的删除)
定时删除的原理:给每一个设置了过期时间的key分配一个线程,该线程睡眠了过期时间后,起来删除该key
缺点:当过期的key特别多时,创建的线程也会非常多,特别消耗cpu资源
定时删除
定期删除原理:专门有一个线程监视所有设置了过期时间的key的时间,如果过期,将该key删除
缺点:实时性差一点
定期删除
惰性删除原理:当用户访问该key 时,会判断该key 是否过期了如果过期了就删除该key,给用户返回null,如果没有过期就返回value
缺点:如果用户一直不访问该key,它就一直不会删除,会一直占用内存
惰性删除
可以互相解决缺点
定期删除+惰性删除结合(Redis默认)
三种策略
过期删除策略
相当于两个rendis进程,这期间主线程不参与持久化,保证redis的高性能
redis会单独创建(fork)一个与当前进程一模一样的子进程来进行持久化将数据写入到一个临时文件中,待持久化结束后替换上次持久化好的文件
原理
客户端执行shutdown命令
全量复制
debug reload
shutdown
触发机制不容忽略方法
配置文件中有快照配置,例如:save 900 1 (15分钟内有一次修改)
save命令会阻塞主线程,一般不用
bgsava会fork子进程异步持久化
1、save是同步IO,bgsave是异步IO
2、save是阻塞主线程,bgsave阻塞redis子线程
3、save和bgsave的复杂度都是O(n)
4、save不会消耗额外的内存,bgsave不会阻塞客户端命令
5、save会阻塞客户端命令,bgsave需要创建子线程,需要消耗内存
save和bgsave对比
执行save或bgsave命令
执行flushall命令
触发
底层都是调用bgsave
恢复的时候比较快,适合大规模的数据恢复
优点
如遇突然宕机,丢失的数据比较多
如果生成的快照文件比较大会影响redis的性能
dbfilename dump-${port}.rdb
dir /bigdiskpath
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
RDB的最佳配置
RDB
由主线程完成
将所有的写命令追加到AOF缓冲区中,根据对应的写入策略向硬盘进行同步操作
fork子进程来进行
随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的
线上开启 config set appendonly yes
开启后redis会保留一块内存供缓存使用,默认是1M
aof和rdb同时开启时,只保留save 900 1 减少fork子进程的次数(优化点)
需手动开启:appendonly yes
everysec:每秒同步一次,效率高,可能会丢失1秒的数据【默认也推荐使用】
追求效率
no:等到缓冲区满了才写入磁盘,次数少,效率高,不安全
追求安全
always:每次发生数据变更时立即同步到磁盘,效率低,安全
写入策略:appendsync
aof文件大于64M时重写
由于重写会fork子进程,为了减少重写次数,这里建议配置5GB以上(优化点)
auto-rewrite-min-size 64M
指超过优化后,第二次优化文件大小大于第一次优化文件后大小一倍时开始重写
auto-aof-rewirte-percentage 100
默认配置
进程内已超时的数据不再写入文件,而且多条写命令可以合并为一条
新的AOF文件只保留最终数据的写入命令(去掉了修改命令)
重写后的文件为什么会变小
1、减少磁盘占用量
2、加速恢复速度
重写作用
重写机制bgrewriteaof
相比于RDB,丢失的数据少,不过建议与RDB同时开启
恢复慢,恢复不稳定,容易bug
aof相关配置
AOF
1、RDB启动优先级比AOF低
2、DOB的体积比AOF小
3、RDB恢复数据的速度比AOF快
4、RDB数据安全行很容易丢失数据,AOF根据策略决定
RDB和AOF的区别
RDB集中管理
RDB在主机中关掉,在从机中开启
AOF开启缓存和存储
AOF重写集中管理
AOF的策略是每秒保存
RDB和AOF的最佳策略
先判断是否开启了AOF,如果存在AOF文件,则直接加载AOF文件
如果找不到AOF文件,则直接启动,不会加载RDB文件
如果没有开启AOF,则会加载RDB文件
生产环境建议AOF和RDB同时使用,RDB做灾难备份
redis启动后持久化文件的加载流程
1、同步操作
2、与内存量息息相关:内存越大,耗时越长
3、info:latest_fork_usec :监控
1、优先使用物理机或者高效支持fork操作的虚拟化技术
2、控制redis实例最大的可用内存
3、合理分配liunx内存分配策略
4、降低fork策略,比如放宽aof的触发机制,不必要的全量复制
改善fork
1、fork操作
开销,RDB和AOF文件生成
优化:不做CPU绑定,不要CPU密集型部署
1、CPU
开销:fork内存开销,copy-on-write
优化:不允许每次都写
2、内存
开销:AOF和RDB文件写入,可以结合iostat,iotop分析
1、不要和高硬盘服务器部署在一起,存储服务,消息队列
2、no-appendfsync-on-rewrite=yes
3、根据写入量决定磁盘类型,ssd
4、单机多实例持久化文件目录可以考虑分盘
优化
3、硬盘
2、进程外的开销
1、主线程开启AOF缓存并且存放到存放到AOF缓存区
2、AOF缓存区同步线程
3、AOF同时对比fsync时间
4、如果大于2秒则阻塞,如果小于则通过
流程
3、AOF追加阻塞
4、单机多实例部署
redis持久化运维常见问题
Redis的持久化
主机数据更新后根据配置和策略,自动同步到备机的master/slave机制,Master以写为主,Slave以读为从
在从机上输入命令SLAVEOF 【主机的ip】 【主机的端口号】
1、充当数据副本使用,避免数据丢失
2、扩展读的性能
一个主机(master),多个从机(salve)
一个从机只能有一个master
数据流通是单向的,只能是master到salve
主从复制的作用
配从不配主
从头复制
从机是从头开始复制还是从切入点开始复制
不能 从机只能读get
从机是否可以写 set?
原定待命,不会变成主机
主机shutdown后,从机是上位还是原地待命
可以
主机重新启动后,从机是否能够顺利复制
从机shutdown后,情况如何
查看本机的复制信息
记住命令info replication
1、将主机的读操作分摊给从节点
1、复制数据延迟(阻塞可能会造成)
2、读到过期数据
3、从节点故障
可能遇到问题
1、主从分离
1、maxmemory不一致可能会丢失数据
2、数据结构优化参数不一致可能会造成主节点和从节点内存不一致
2、主从配置不一致
通过数据分片设置不要设置过大,进行低峰复制
1、第一次全量复制不可避免
主节点重启(runId会发生变化)
故障转移
2、节点运行ID不一致
网络中断,部分复制无法满足
增加复制缓冲区的配置,进行网络增强
3、复制积压缓存区不足
3、规避全量复制
更换复制徒
主节点重启,从节点复制
1、单主节点复制风暴
主节点分布在多个机器
2、单机器复制风暴
4、规避复制风暴
运维问题
主从复制的一些问题
Master和Slave都会维护一个offset和run id ,Slave每秒都会上报自己的offset给master
Master记录在backlog(针对增量复制)中,这样才能知道双方数据是否一致
Slave发送run id 和offset到Master,Master根据情况返回信息(增量/全量)
前提
Slave从机第一次启动时
Master重启时
触发时机
1.Slave启动时回向Master发送SYNC指令(请求同步)
2.Master收到后通过bgsave保存快照,同时将后续的命令存到缓存中
3.Master将RDB发给Slave,Slave收到文件后先写入到本地磁盘,然后在从本地磁盘加载到内存中
4.最后maser会将内存中的写命令同步给Slave,Slave收到后再执行一遍
复制过程
1、bgsave时间
2、RDB的文件网络传输时间
3、从节点清空数据时间
4、从节点加载RDB时间
5、可能存在AOF重写的时间
全量复制开销过程
Master根据Slave发送的同步请求中的offset
在backlog中查询部分丢失的数据,发送给Slave
增量复制
Slave不会处理过期key,只会等待Master的过期通知
过期key的处理
主从复制数据同步的原理
salveof ip port
salveof no one 表示不是某个主机的从节点
salveof命令
1、salveof ip port
设置从节点只当作读的操作
2、salve-read-only yes
配置
1、使用命令进行主从配置,不需要重启redis服务器,但是不方便管理
2、使用配置进行主从配置,需要重启redis服务器,但是方便管理
两种配置的区别
主从复制的配置
哨兵是一个分布式系统,监控主从架构中的节点通过 span style=\
1、配置主从节点
2、配置开启sentinel监控主节点
3、配置多台机器
4、详细配置节点
安装和配置
监控主节点从节点是否正常运行
监控
当确认主节点宕机后,在从节点中选一个座位主节点,将其他从节点连接到新的主节点上通知客户端最新的地址
自动故障转移
主要功能
发现slave节点
发现主从关系
1、每10秒每个sentinel都会对master和slave执行info
通过_sentinel_hello;进行频道的交互
交互对节点的看法和自身的信息
2、每2秒每个sentinel通过master节点的channel交换信息(pub/sub)
心跳检查,失败判断依据
3、每1秒每一个sentinel会对其他sentinel和redis进行ping
三个定时任务
发现Master宕机
先过滤掉不在线和响应慢的服务器
然后过滤掉与原Master断开时间最久的
最后比较优先级priority
如果两个服务器优先级一致,那么回去查看从服务器中数据的offset,offset说明数据最新,选出offset大的服务器为Master
哨兵从服务器列表中挑选Master
哨兵向选举出的新Master发送指令,断开与旧Master的连接
把新Master的ip地址同步到其他Slave节点
新Master诞生
以前的Master如果重连了,那么以前的Master会变成新Master的Slave
工作原理
1、客户端高可用观察
2、服务端日志分析:数据节点和sentinel节点
1、从slave节点选出一个”合适的“ 节点作为新的master节点
2、对上面的slave节点执行slaveof on one命令让其成为master节点
3、向剩下的slave节点发送命令,让他们成为新master节点的slave节点,复制规则和parallel-syncs参数有关
4、更新对原来master节点配置,并保持对其关注,当宕机的机器恢复后就命令他复制新的master节点
故障转移流程
1、选择slave-priority(slave节点优先级)最高的slave节点,如果存在则返回,如果不存在则继续
2、选择复制偏移量最大的slave节点(复制的最完整),如果存在则返回,不存在则继续
3、选择runId最小的slave节点
如何选择合适的slave节点
每个sentinel对redis节点失败的偏见
主观下线
所有sentinel对redis节点失败达成共识(超过quorum的统一)
客观下线
quorum最好配置所有哨兵的一半+1
主观下线和客观下线
原因:只有一个sentinel节点完成故障转移
通过sentinel is-master-down-by-addr命令都希望成为领导者
1、每个做主观下线的sentinel节点向其他sentinel节点发送命令,要求将它设置为领导者
2、收到命令的sentinel节点如果没有同意通过其他sentinel节点发送的命令,那么将同意该申请,否则拒绝
3、如果sentinel节点发现自己的票数已经超过sentinel集合半数且超过quorum,那么自动成为领导者
4、如果此过程有多个sentinel节点成为领导者,那么等待一段时间重新选举
选举
sentinel领导选举
sentinel failover <masterName>主节点下线
sentinel failover 进行替换主节点上线
主节点
临时下线或者永久下线,需要考虑读写分离和原因
slaveof命令,sentinel节点可以感知
从节点
sentinel节点
节点的上线和下线
机器下线(机器过保)
机器性能不足(比如CPU、内存等)
节点自身故障(网络不稳定等)
问题
节点运维
1、当作副本,并且是高可用的基础
2、扩展redis 读操作的能力
从节点的作用
高可用高的读写分离
常见运维
1、故障发现
2、故障自动转移
3、配置中心
4、客户端通知
1、Redis-Sentinel是redis高可用得的实现方案
2、尽可能的在不同服务器上配置sentien节点
3、Redis-Sentinel的sentinel节点最好是大于等于3个并且数量最好是基数个
4、Redis-Sentienl数据节点和普通的数据节点没有区别
5、客户端初始化时连接的是sentinel集合,而不是具体的redis节点,但是sentienl只是配置中心而不是代理
6、Redis-Sentienl通过三个定时任务实现了Sentienl节点对主节点、从节点、其他Sentinel节点的监控
7、Redis-Sentinel在节点失败时是分为主观下线和客观下线
8、Redis-Sentienl读写分离可以依赖于Sentienl节点消息通知,获取Redis节点的数据状态变化
总结
哨兵模式
由于所有的写操作都是现在Master上操作,然后同步更新到Slave上所以从Master同步到Slave上机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重
主从复制的缺点
主从复制
通过缓存加速读写速度
CPU的L1、L2、L3CaChe
CaChe加速硬盘读写
EhCaChe缓存数据库结果
浏览器缓存
利用redis优化IO响应时间
计数器先累计,然后批量写入DB
大量写入合并为批量写
使用场景
1、加速读写
后端服务器通过前端缓存降低负载:业务端使用redis降低后端mysql负载
对高消耗的SQL:join结果集/分组统计结果
2、降低后端负载均衡
收益
缓存层和数据层有时间窗口不一致和更新策略有关
1、数据不一致
多了一层缓存逻辑
2、代码维护成本
比如集群等
3、运维成本
成本
缓存的收益和成本
maxmomory-policy
1、LRU/LFU/FIFO算法剔除
expire
2、超时提出
开发控制生命周期
3、主动更新
1、LRU/LFU/FIFO算法剔除一致性最差,同时维护成本也是最低的
2、超时剔除一致性稍微比第一种策略好一点,维护成本也低
3、主动更新一致性高,维护成本也高
三种策略的比较
最大内存和淘汰策略
1、低一致性
超时剔除和自动更新结合,最大内存和淘汰策略兜底
2、高一致性
建议
缓存的更新策略
select* from user where id=id
1、从MySQl获取用户信息
set user:{id} ‘select* from user where id=id’
2、设置用户信息缓存
缓存全部
缓存部分
3、缓存粒度
全部属性最好
1、通用性
部分属性最好
2、占用空间
3、代码维护
三个角度
缓存的粒度控制
大量请求访问缓存,缓存找不到,
缓存穿透的现象
1、代码问题
2、恶意访问或者爬虫等
原因
1、业务的响应时间
2、业务本身问题
1、总调用数
2、缓冲层命中数
3、存储层命中数
3、相关指标
如何发现
1、产生更多的键
2、缓存层和存储层数据短期不一致
可能的问题
1、缓存空对象(同时设置过期时间)
2、步隆过滤器拦截
解决方法
缓存的穿透优化
1、命令本身优化
2、减少网络通信次数
长链接
连接池
NIO(非阻塞IO技术)
3、降低接入成本
优化方法
无底洞优化
由于缓存存放者大量的请求,当缓存服务异常或者脱机,流量直接压向后端服务器,造成级连故障
什么是缓存雪崩
1、Redis集群
2、Redis-Sentinel
1、保证缓存的高可用
2、依赖隔离组件进行限流
3、提前演练(压力测试等)
缓存雪崩优化
仅仅只针对某一个key(可以是热点key重构)
缓存击穿
缓存
意思是所有的节点都要有一个主节点
中心挂了,服务就挂了
中心处理数据的能力有限,不能把节点性能发挥到最大
就是一个路由作用
中心化
让每个主机都拥有转发能力
去中心化
创建集群时,集群节点直接要相互通信,使用 redis-server的端口+10000 = 新的集群的监听端口
哈希槽 Redis集群时怎么样set一个key
执行流程
Redis集群
idea工程
redis的使用
Redis
0 条评论
回复 删除
下一页