Redis思维导图
2020-05-07 19:12:00 0 举报
AI智能生成
redis思维导图
作者其他创作
大纲/内容
redis
定义
内存结构化数据存储(数据库、缓存、消息队列)
每个操作系统中可以安装多个redis实例,每个redis实例默认有0-15 16个库
单进程、单线程(计算线程)
与memcache对比
1、memcache的value无类型、redis的value有类型
2、memcache的value中可以存储json格式内容(可以表示任意类型),但是每次都需将value完整取出来,到客户端发生计算。而redis支持value的各种操作
value类型
string
字符串
setdelmsetgetmgetappendsetrangegetrangestrlengetsetobject encoding
set k1 abc [nx|xx]nx:当k1不存在时该设置成功xx:当k1存在时该设置成功
二进制安全内容是以字节流存储,不是已字符流存储。保证原来的内容的字节完整保存
数值
incrdecrincrbyincrbyfloatdecrbydecrbyfloat
bitmap
setbit k offset v
按照二进制位设置value,1byte=8bit
bitcount k start end
按照字节的位置统计
bitop operation destkey k1 k2
场景
统计客户一年内登录app的天数,及任意时间窗口内的登录次数使用bitmap,客户id作为key,每天作为二进制位,每天登录行为记到二进制位里客户1登录:setbit user1 1 1setbit user1 2 1setbit user1 364 1统计:bitcount user1 start end
统计某一时间范围内有多少客户登录app使用bitmap,日期作为key,每一个客户做为一个二进制位,每天登录的行为记为1,存到改二进制位里客户1登录:setbit 20200101 1 1setbit 20200102 1 1客户2登录:setbit 20200102 2 1统计:bitop or destkey 20200101 20200102bitcount destkey 0 -1
布隆过滤器
判断某个元素是否存在1、通过多个不同的hash算法,将内容映射成hash值,存储到对应的bit上2、将另外一个值通过不同的hash算法,映射到bit上,有可能覆盖第一步的bit,也有可能是新的bit3、判断一个值是否存在,通过不同的hash算法算出该值的hash值,到bit上寻找,如果存在一位bit上的值为0,则表示该值不存在,如果所有的bit都是1,则表示该值有可能存在
list
栈同向命令
lpushlpop
rpushrpop
队列反向命令
lpushrpop
rpushlpop
数组索引命令
lrange k 0 -1lindexlsetlremlinsertltrim
redis中的string、list都有正负向索引
阻塞、单波队列客户端FIFO
blpopbrpop
hash
hsethgethmsethmgethkeyshvalshgetall
set
saddspopsmembers
交集
sintersinterstore
并集
sunionsunionstore
差集
sdiffsdiffstore
随机事件
srandmember k 5 -5 10 -10如果count为正数,则取出一个去重的结果集(不能超过已有集)如果count为负数,则取出一个重复的结果集(一定会满足count数量)
场景1:抽奖,奖品为5个,用户可以大于5个,可以小于5个count>0:每人只会抽取一次count<0:每人可以重复抽取
spop随机取出一个
sorted set
物理内存左大右小,不随命令发生变化
集合操作
zaddzrangezrevrangezscorezrank
并集、交集zinterstore、zunionstore,重点:权重/聚合指令
实现原理
skip list跳跃表
pipelining
echo -e 'set k1 99\incr k1\get k1' | nc localhost 6379
cat 123.txt | redis-cli --pipe
pubsub
publish channel messagesubscribe channelpsubscribe
直播1、通过线性方法+事物2、通过另外两个客户端订阅,写入sorted set 和 db
历史数据
db
最近三天数据
实时数据
pub/sub
transactions
multiexec
1、multi开启事物,然后发送指令,这些指令不会执行,而是放到队列queue中,当发送exec指令时,这些指令才会被执行2、当同时有多个客户端发送事物指令时,谁的exec指令先到达redis-server,则谁的指令会先执行
watch
watch k观察key的变化(cas),如果发现k的值变化了,则watch接下来的事物操作不会被执行
缓存回收
内存配置
配置最大内存,为0时则无内存限制:maxmemory 100mb32位机器默认内存3GB
回收策略
配置
maxmemory-policymaxmemory-samples 5
通过对配置的样本个数采样分析,基于他们的LRU访问时间淘汰最久没有访问的key。redis实现了一个LRU时钟,每个key在被访问时,会记录下服务器LRU时钟,回收时比较key的LRU时钟和服务器的LRU时钟,间隔长的会被淘汰如果maxmemory-samples配置的越大,则越接近理论的LRU算法,但是会损耗CPU指令集
算法
noeviction
当内存已满,客户端有新的命令达到,需要更多内存时,直接返回错误
allkeys-lruallkeys-lfu
所有的key参与LRU回收最远时间使用的keyLFU回收最不频繁使用的key
volatile-lruvolatile-lfu
在过期集合里的key参与LRU回收最远时间使用的keyLFU回收最不频繁使用的key
allkeys-random
所有的key参与,随机回收
volatile-random
在过期集合里的key参与,随机回收
volatile-ttl
回收在过期key的集合里,优先回收过期时间短的key
persistence
RDB
描述
持久化数据到磁盘,优点恢复快、缺点容易丢失数据。需要时点性的写入RDB, 8点-9点-10点
时点性如果8点持久化一个rdb,但是redis中的数据量很大,那么持久化的时间会很长,此时redis的数据变化了,如何保证时点性1、父子进程中的数据是隔离的,如果想子进程访问到父进程的数据,在父进程中对数据使用export,则可以在子进程中访问,如果父子进程都对该数据修改,两边不同步。2、进程中的数据其实是对内存的一个映射,不同进程中指针都是对这一块内存数据的映射3、linux中提供fork系统调用,用于创建子进程,数据只有一份,复制的是指针,由于两个进程中的数据不是同步的,所以主进程还对外提供读写,而子进程只保留了fork那个时刻点的数据,保证了RDB的时点性4、linux中fork系统调用提供了一种copy-on-write(写时复制),达到不同进程中的数据保持一致
文件默认名称:dump.rdb开启:save \"\" 不开启save 900 1save 300 10save 60 1000060秒如果有10000个key发生变化,则触发持久化如果没有10000个key变化,到了300秒,有10个key发生变化,则触发持久化如果没有10个key变化,到了900秒,有1个key发生变化,则触发持久化
命令
savebgsave
AOF
记录客户端每笔的操作到aof文件中,同时开启RDB和AOF时,只有AOF会起作用
开启:appendonly yes文件默认名称:appendonly.aof持久化aof三种方式,redis默认采用第二种appendfsync always(每有一次操作,刷新到磁盘,同步)appendfsync everysec(每秒一次,刷新到磁盘,同步)appendfsync no(不由redis触发刷新到磁盘,由内核触发写入磁盘,异步)aof 重写机制:auto-aof-rewrite-percentage 100(当已经重写后会记录下aof大小,如果再次达到100%*64mb,则再次触发重写)auto-aof-rewrite-min-size 64mb(达到64mb会触发aof自动重写)
内容写入磁盘的方式:1、内核有一个buffer(4K),当数据填满buffer时,由内核触发写到磁盘,有可能丢失一个buffer的数据2、由程序调用flush,强制内核写入磁盘,每写一次调用一次内核,成本高3、程序每秒触发一次flush,最差的情况为,内核buffer快要满4K,还没到1秒,此时掉电,则会丢失接近一个buffer的数据
文件格式
*3$3set$2k1$1a*3 表示此次操作会保存至3行记录$2 表示此行记录有2个字符长度
bgrewriteaof:重写AOF文件,会合并之前的操作日志
4.0以上版本
支持RDB和AOF混合方式aof-use-rdb-preamble yesAOF文件是以REDIS开头
4.0以下版本
AOF只记录操作日志RDB只保存历史镜像
cluster
主从复制
一主两从,主节点可读可写,从节点只能读在从节点上执行:老版本:slaveof host port新版本:replicaof host port如果主挂了,手动将从节点切换成主:replicaof no one
replica-serve-stale-data yes
在从节点同步主节点数据时,是否对外提供读服务
replica-read-only yes
是否为只对外提供读服务
repl-diskless-sync no
rdb是走磁盘还是直接走网络
repl-backlog-size 1mb
增量日志
ha(哨兵)
监控(Monitoring)提醒(Notification)自动故障迁移(Automatic failover)
port 26379sentinel monitor mymaster 127.0.0.1 6379 2
启动
redis-server /path/to/conf --sentinel或redis-sentinel
多个哨兵之间通信是通过主节点的发布/订阅实现的
shading分片
1、hash取模 modula
2、随机 random
适用于消息队列
3、一致性hash ketama
适用于缓存
1、虚拟一个很大的hash节点环 0-2^322、每个node节点根据关键词算出hash值,对应到hash环的节点中,成为物理节点3、当有数据过来时,根据hash算法得到hash值,拿到一个比该值大的最邻近的一个物理节点,将key推送到该节点上4、当有新节点加入时node03,node03有可能会落在node02之前,则有部分原本落在node02的数据,查询时会从node03去查询,则会查询不到,会造成缓存击穿,查询会落到数据库中。有两种方案: 4.1 查询时如果当前节点查询不到,则往后多查一个节点,再次没有的话,则会缓存击穿 4.2 此种模式只用于缓存,不考虑上述问题,在从之前节点无法查询时,则会从数据库中查询,同时将缓存写入node03 而之前node02节点上的数据可以通过配置LRU、LFU进行缓存淘汰
虚拟节点 如果节点个数太少,会出现数据倾斜,解决方法:将节点拼接字符串方式,再次散列成物理节点,这些节点成为虚拟的节点
代理
swemproxy
predixy
codis
redis_cluster
模型
槽位 slots(16384个)如果client连接的时redis2实例,到redis2中对key操作hash(key)%16384=12000则会到该redis实例中的映射表查找,发现应该时redis3实例,则redis2会向客户端回送消息让client重定向到redis3实例
无主模型
1、create-cluster start2、create-cluster create
1、create-cluster stop
redis-cli --clusterredis-cli --cluster inforedis-cli --cluster check
redis-cli reshard
用于解决数据倾斜,迁移某些redis实例下的某些槽位至另外redis实例下
使用细节
如果使用普通客户端连接,redis-cli -p ,get key 如果key不在当前redis实例,则会提示报错,让去对应redis实例中操作应该使用redis-cli -c -p 命令启动连接redis集群的客户端,上述问题会自动重定向到正确的redis实例中
击穿
现象
当有一个或几个key失效,此时客户端有大量并发请求这个可以,此时会造成所有的请求到db,造成缓存击穿
解决方法
步骤:1、所有的客户端往redis中执行指令setnx,如果key为空,会设置成功,否则失败2、只有setnx执行成功的才会到请求到数据库中,请求完数据库后,重新设置请求的key值,其他客户端睡眠一个随机时间,重新获取key,如果能拿到key的值返回,拿不到则重复1步骤3、有一个问题,如果setnx成功的客户端突然挂了,此时该操作中断了,没有设置key的值也没有将setnx的值销毁4、给setnx加个过期时间,但是这个过期时间不好把握,如果设置短了,客户端还没请求完db,setnx已经过期了,其他客户端会重新setnx5、加一个线程,用户检测客户端请求db的操作,来延长setnx的过期时间
穿透
大量客户端请求了redis缓存中不存在的数据,请求直达db
缺点:不能删除
布谷鸟过滤器
布隆过滤器+
雪崩
缓存中大量key设置了固定的过期时间,大量并发的请求到达,会直接到db中
与时点性无关:可以设置随机的过期时间
与时点行相关:在客户端请求时加上随机的时延,可以参考击穿方案
分布式锁
1、setnx2、设置过期时间3、创建线程延长锁过期时间
0 条评论
回复 删除
下一页