redis基础知识汇总
2021-10-06 17:10:54 0 举报
AI智能生成
redis基础知识汇总,目前需要扩展的点有redis的底层数据结构,io多路复用的原理,redis集群相关。分布式锁相关扩展点等等。
作者其他创作
大纲/内容
redis为啥快
基于单线程的
多路io复用
什么是io多路复用?
避免上下文切换
避免锁问题
Redis是基于内存的,操作数据比磁盘操作更加快速
面试常问缓存问题
缓存预热
缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。 避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题
解决方案:nginx +lua 将访问流量上报到 kafka 中,统计出当前最新的实时的热数据,将商品详情页访问的请求对应的流量日志实时上报到 kafka 中;
storm 从 kafka 中消费数据,实时统计访问次数;访问次数基于 LRU 内存数据结构的存储方案。
storm 从 kafka 中消费数据,实时统计访问次数;访问次数基于 LRU 内存数据结构的存储方案。
缓存雪崩
缓存雪崩是指缓存中有大批数据过期了,导致数据库压力过大甚至宕机。
解决方案:
缓存的过期时间设置随机值,避免同一时间都过期。
热点数据不设置失效时间。
缓存击穿
缓存击穿一般都是缓存中没有但是数据库有,一般都是缓存过期了,由于并发用户特别多,又没读到数据,去读数据,大量数据读取数据库导致数据库有巨大的压力。
解决方案:
设置热点数据永不过期
使用互斥锁
缓存穿透
用户不断访问并不存在的数据,数据库和缓存中都没有,这些用户可能是一些攻击者,对数据库造成巨大压力
解决方案:
布隆过滤器:
将所有可能不存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免对底层存储系统的查询压力。
布隆过滤器原理是什么?
bitmap+哈希函数
布隆过滤器的缺点是什么
缺点不能删除元素
布隆过滤器的替代品是什么?
布谷鸟过滤器
将key的vlue作为null:从缓存取不到数据,数据库也没取到,这样可以将key-value做写入,key-null,设置有效时间为30秒左右,可以防止攻击用户反复用一个id暴力攻击。
Redis的应用场景
缓存
会话缓存(Session Cache)
全页缓存(FPC)
队列
数据存储
排行榜/计数器
发布/订阅
分布式锁
分布式id
session共享
联系人自动补全
集群操作
持久化机制
rdb
优点
rdb是二进制压缩文件,占用空间小,方便传输
主进程fork子进程,最大化redis的性能
关于数据恢复,数据文件直接加载到内存即可
缺点
不能保证数据的完整性,会丢失最后保存后的数据
aof
优点
aof文件命令可读,适合灾难性恢复
三种保存模式
不开启保存
每秒保存一次默认
每个命令保存一次
缺点
存放的指令代码,数据恢复的时候,要回放和执行所有指令日志。恢复数据比rdb慢。
应用场景:
内存数据库
rdb+aof,保证数据不丢失
缓存服务器
使用rdb,性能高
不建议只用aof,性能差
分布式锁
本地锁
分布式服务在访问的时候只能获取自己的锁,分布式锁不住
分布式锁
过期策略
命令
一个key设置过期时间后(expire key seeconds),能自动删除一个操作将来的某个确定时间发生
应用场景
延时队列:订单的过期取消(下了一个订单超过30分钟没进行支付,则自动取消)
key的过期删除:key设置过期时间,达到这个过期时间后,key能自动的删除
三种策略
定时删除
定时删除的原理:给每个设置过期时间的key分配一个线程,该线程睡眠了过期时间后,起来删除该key
缺点:当过期key特别多的时候,创建的线程也会非常多,特别消耗cpu的资源。
定期删除
专门有一个线程监视所有设置过期时间的key的时间,如果过期,将该key删除。
缺点:时效性差一点
惰性删除
当用户访问该key时,会判断该key是否过期,如果过期就删除该key,给用户返回null,如果没有过期,就返回value
缺点:如果用户一直不访问该key,就一直不会删除,会一直占用系统资源
定时+定期删除结合(默认)
内存管理策略
redis中内存超过设置maxmemory-policy的限制时执行的LRU算法
从设置过期的时间key集合中删除最近没有被使用的key
通过lru算法删除最近没有在使用的key
从设置过期时间的key集合中删除最近使用频率最少的key
在所有key的集合中,删除最近使用频率最少的key
在设置过期时间的key集合中随机删除一个key
在所有key集合中随机删除一个key
在设置过期时间的key集合中删除即将过期的key
超过最大容量时不会删除任何key,返回一个错误(默认)
事务操作
概念
redis事务本质是一组命令的集合,一次执行多个命令,一个事务中所有命令中被序列化
特点
一次性
顺序性
排他性
没有隔离级别的概念
事务操作前会把命令都放入队列,并不是立即执行
不保证原子性
单条命令是保证原子操作的,但并不保证原子性,且没有回滚
任意命令失败,其余命令仍会正常执行
阶段
开始事务
执行入队
执行事务
命令
watch k1 k2
实现乐观锁
监视key 如果事务在被执行前,被监视key被改动,则事务执行失败
multi
标记事务开始
exec
执行事务
discard
放弃事务
unwatch
取消对所有key进行监控
相关异常问题
如果在事务队列中出现编译异常,则执行exec命令,所有命令都不会执行
如果在事务中出现运行时异常,则执行exec命令时,错误命令抛出异常,其他正常执行
redis的数据类型
Sorc Set类型操作
key-> score(10.1) value(string/int/float) rank:1
score(9.1) value(string/int/float) rank:0
score(11.2) value(string/int/float) rank:2
key-> score(10.1) value(string/int/float) rank:1
score(9.1) value(string/int/float) rank:0
score(11.2) value(string/int/float) rank:2
zadd
向有序集合添加一个或多个成员,或者更新已存在成员的分数
zadd key score1 member1 [score2 member2....]
zcard
获取有序集合的成员数
zcard key
zcount
计算在有序集合中指定区间分数的成员数
zcount key min max
zincrby
有序集合中对指定成员的分数加上增量 increment
zincrby key increment member
zrange
通过索引区间返回有序集合成指定区间内的成员
zrange key start stop [withscores]
zrank
返回有序集合中指定成员的索引
zrank key member
zrem
移除有序集合中的一个或多个成员
zrem key member1 [member2....]
zrevrange
返回有序集中指定区间内的成员,通过索引,分数从高到底
zrevrange key start stop [withscores]
zscore
返回有序集中,成员的分数值
zscore key member
zset写数据带分数,可实现排行榜
Hash类型操作
key-> key1 value(string/int/float)
key2 value(string/int/float)
key3 value(string/int/float)
key4 value(string/int/float)
key-> key1 value(string/int/float)
key2 value(string/int/float)
key3 value(string/int/float)
key4 value(string/int/float)
hset
将哈希表 key 中的字段 field 的值设为 value
srem key field value
hmset
同时将多个 field-value (域-值)对设置到哈希表 key 中
hmset key field1 value1 [field2 value2]
hsetnx
只有在字段 field 不存在时,设置哈希表字段的值
hsetnx key field value
hget
获取存储在哈希表中指定字段的值
hget key field
hmget
获取所有给定字段的值
hget key field1 [field2]
hgetall
获取在哈希表中指定 key 的所有字段和值
hgetall key
hvals
获取哈希表中所有值
hvals key
hlen
获取哈希表中字段的数量
hlen key
hkeys
获取所有哈希表中的字段
hkeys key
hdel
删除一个或多个哈希表字段
hdel key field1 [field2]
hexitst
查看哈希表 key 中,指定的字段是否存在
hexitst key field
map适合存储对象:因为对象的属性和值,我们可以认为是一个map集合里面的值,相对于json串,单独修改对象的字段,可以快速定位,存储的消息需要被频繁修改可用hash存储,比如实现实现购物车。
List类型操作
[key => value1 | 自
value2 | 左
value3 | 而
value4 | 右
]
[key => value1 | 自
value2 | 左
value3 | 而
value4 | 右
]
push
lpush
将一个或多个值插入到列表头部
lpush key value1 [value2....]
rpush
将一个或多个值插入到列表尾部
rpush key value1 [value2....]
pop
lpop
移出并获取列表的第一个元素
lpop key
rpop
移出并获取列表的最后一个元素
rpop key
lrange
获取列表指定范围内的元素
lrange key start stop
llen
获取列表长度
llen key
lindex
通过索引获取列表中的元素
lindex key index
lrem
移除列表元素
lrem key count value
count > 0
从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT
count < 0
从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值
count = 0
移除表中所有与 VALUE 相等的值
lset key index value
通过索引设置列表元素的值
lset key index value
list是一个双向链表,适合存储的特点:可以实现高性能的分页,实现栈或者队列,例如到货通知,邮件发送,秒杀,保存待抢购商品列表
Set类型操作
key->[ value1
value2
value3
value4
]
key->[ value1
value2
value3
value4
]
sadd
向集合添加一个或多个成员(存在则返回0)
sdd key member1 [member2]
scard
获取集合的成员数
scard key
sinter
返回给定所有集合的交集
sinter key1 [key2]
sismember
判断 member 元素是否是集合 key 的成员
sismember key member
smembers
返回集合中的所有成员
smembers key
srandmember
返回集合中一个或多个随机数
srandmember key [count]
srem
移除集合中一个或多个成员
srem key member1 [member2]
set特性:无序唯一。
String类型操作 [key|value(string/int/float)]
set
设置置顶key的值
set key value
get
获取指定key的值
get key
incr
将key中储存的数字值增一
incr key
decr key
将key中储存的数字值减一
decr key
incrby
key 所储存的值增加给定的减量值(decrement)
incrby key decrement
decrby
key 所储存的值减去给定的减量值(decrement)
decrby key decrement
append
如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
append key value
setnx
只有在 key 不存在时设置 key 的值
setnx key value
mget
获取所有(一个或多个)给定 key 的值。
mget key [key...]
mset
同时设置一个或多个 key-value 对
mget key value [key value ...]
getset
将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
getset key value
setex
将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。
setex key seconds value
strlen
返回 key 所储存的字符串值的长度
strlen key
del
删除键
del key
String适合存储的特点:可以做简单的key-value缓存,实现计数器,分布式锁,session共享,分布式id生成(自增)
redis的数据结构
SDS,双向链表、跳表,哈希表,压缩列表、整数集合
压缩列表
散列表
散列表+跳跃表
列表
双向链表
node
上一个节点
下一个节点
数据
字符串长度
字符串中剩余可用字节数
字符串本身
Lua
减少网络开销、原子性、复用
本地缓存与分布式缓存
本地缓存
本地缓存在分布式系统上会出现什么问题
线程过来后通过负载均衡发送到本地项目,发现本地缓存没有,
然后缓存一份
然后缓存一份
下次负载到别的本地项目发现还是没有,又缓存一份
同样的数据在不同的服务都缓存一份
浪费内存资源
解决方案:
使用redis分布式缓存
0 条评论
下一页