Redis
数据类型
Redis五种数据类型分别是string(字符串),hash(哈希),list(列表),set(集合)及sort set (有序集合)
REDIS_ENCODING_INT long 类型的整数
REDIS_ENCODING_EMBSTR embstr 编码的简单动态字符串
REDIS_ENCODING_RAW 简单动态字符串
REDIS_ENCODING_HT 字典
REDIS_ENCODING_LINKEDLIST双端链表
REDIS_ENCODING_ZIPLIST 压缩列表
REDIS_ENCODING_INTSET 整数集合
REDIS_ENCODING_SKIPLIST 跳跃表和字典
1. 字符串对象的编码可以是int、raw或者embstr
2. 列表对象的编码可以是ziplist或者linkedlist
3. 哈希对象的底层实现可以是ziplist或者hashtable
4. 集合对象的编码可以是intset或者hashtable
5. 有序集合的编码可能两种,一种是ziplist,另一种是skiplist与dict的结合
缓存穿透
1. 描述:缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
2. 解决方案:
a. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截
b. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
缓存击穿
1. 描述:缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
2. 解决方案:
a. 设置热点数据永远不过期。
b. 加互斥锁,互斥锁参考代码如下
缓存雪崩
1. 描述:缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
2. 解决方案:
a. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
b. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
c. 设置热点数据永远不过期。
Redis过期策略和内存淘汰机制
1、定期删除+惰性删除
a. 定期删除:指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除
b. 惰性删除:在你获取某个key的时候,redis会检查一下 ,这个key如果设置了过期时间那么是否过期了,如果过期了此时就会删除,不会给你返回任何东西
2、如果大量过期key堆积在内存里,导致redis内存块耗尽了,怎么办?
内存淘汰机制:
redis.conf中配置:
# maxmemory-policy noeviction
a. noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错。
b. allkeys-lru:在主键空间中,优先移除最近未使用的key。
c. volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。
d. allkeys-random:在主键空间中,随机移除某个key。
e. volatile-random:在设置了过期时间的键空间中,随机移除某个key。
f. volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。
g. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键
h. allkeys-lfu:从所有键中驱逐使用频率最少的键
Redis持久化
1. 描述:Redis持久化就是把内存的数据写到磁盘,防止服务宕机挂了内存数据丢失,分为RDB和AOF两种方式
2. 方式
a. RDB持久化是把当前数据生成快照保存到硬盘中,分为手动触发和自动触发两种,手动触发命令有save和bgsave,save会阻塞当前进程,bgsave会创建子进程
b. AOF持久化以独立日志的方式记录每次写命令, 重启时再重新执行AOF文件中的命令达到恢复数据的目的
Redis架构模式
分为单机、主从、哨兵、集群
1. 单机:性能高、可靠性低
2. 主从:数据复制是单向的,只有主节点能写,从节点只能读,提高了可靠性,但是存在数据冗余,主节点写有压力
3. 哨兵:哨兵节点是特殊的Redis节点不存储数据,主从节点都是数据节点。主节点可以切换,可靠性进一步提高,但是仍然没有解决主节点写的压力
4. 集群:高可用、可拓展、分布式、容错
Redis为什么快
1. 纯内存数据库,时间主要在IO上
2. 使用多路IO复用模型,用的非阻塞IO,最快的epoll
3. 单线程轮询操作符,减少了线程切换时上下文的切换和竞争
4. Redis使用的数据结构,如Hash、跳表都很快
浙公网安备 33010602011771号