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