读书笔记:redis学习笔记

redis

应用场景

  • 一些限流场景
  • 数据库缓存
  • 消息队列

2. 基础知识

数据结构:5种基本数据结构:SDS、Hash、List、Set、Zset;

  • String: redis自己构建了一种sds(简单动态字符串)
    定义结构如下:
struct sdshdr {
// 记录buf数组中已使用字节的数量
// 等于sds所保存字符串的长度
int len;
// 记录buf数组中未使用字节的数量
int free;
// 字节数组,用于保存字符串
char buf[];
};
  • Hash: 可以将Redis中的Hash类型看成具有<key,<key1,value>>,其中同一个key可以有多个不同key值的<key1,value>,所以该类型非常适合于存储值对象的信息

  • List:按照插入顺序排序的字符串链表;链表节点结构如下:

typedef struct listNode {
// 前置节点
struct listNode *prev;
// 后置节点
// 节点的值
void *value;
}listNode;
  • Set:Set类型看作为没有排序的字符集合。如果多次添加相同元素,Set中将仅保留该元素的一份拷贝

  • Zset:有序集合

  • 其他数据结构:HyperLogLOG、Geo、Pub/Sub

  • 用于防止缓存击穿的数据结构:Redis Module、BloomFilter、RedisSearch、Redis-ML

设置key过期时间命令:

setRedis(Key, value, time + Mathrandom()*10000);expire;

3. 分布式锁

先拿setnx(set if not exsit)来争抢锁,抢到之后,在用expire给锁加一个过期时间防止锁忘记释放;如果在setnx之后执行expire之前,进程意外crush或者重启维护,把setnx和expire合成一条命令

4. keys命令

  • redis是单线程,keys指令会导致线程阻塞一段时间,线上服务停顿,直到指令执行完毕,服务才能恢复

  • scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但整体花费的时间会比直接用keys要长

  • smembers命令可以返回集合健当前包含的所有元素

  • scan这类增量式迭代命令来说,因为在对健进行增量迭代的过程中,健可能会被修改,所以增量迭代命令只能对被返回的元素提供有限的保证

5. 异步队列

  • list结构作为队列,rpush生产消息,lpop消费消息,当lpop没有消息的时候,要适当sleep一会,重试
  • list还有个指令blpop,在没有消息的时候,它会阻塞住直到消息过来
  • pub/sub主题订阅者模式,可以实现1N的消息队列,生产一次,消费多次
  • pub/sub主题订阅者模式,在消费者下线的情况下,生产的消息可能会丢失,得使用专业的消息队列

6. 延时队列

  • sortedset,拿时间戳作为score,消息内容作为key,调用zadd来生产消息,消费者占用zrangebyscore指令获取N秒之前的数据轮询进行处理

7. 持久化

RDB做镜像全量持久化,AOF做增量持久化,但是RDB会耗费较长时间,无法实时,在停机的时候,会导致大量丢失数据,因此需要AOF配合使用,在redis实例重启时,会使用RDB重新构建内存,仔使用AOF重放近期的操作指令来实现完整恢复重启之前的状态

Redis自身机制是AOF持久化开启,且存在AOF文件时,优先加载AOF文件,AOF关闭或者AOF文件不存在时,加载RDB文件,加载AOF/RDB后,启动成功;AOF/RDB文件存在错误时,redis启动失败,并打印错误信息

8. 机器断电对持久化的影响

AOF日志sync属性的配置,在不要求性能的情况下,可以每条写指令都sync一下磁盘,就不会丢数据,高性能的情况下,可以使用定时sync,例如1s一次,这个时候,最多会丢1s的数据

9. RDB原理

reids有2个命令可以生成RDB文件,一个是SAVE,一个是BGSAVE,其中SAVE命令会阻塞redis服务器进程,直到RDB文件创建完毕,在服务器阻塞期间,服务器不能处理任何命令请求;BGSAVE会fork出一个子进程,然后由子进程负责创建RDB文件,父进程继续处理命令请求

对应配置:save 900 1 表示900s内如果有1条是写入命令,就触发产生一次快照,可以理解为就进行一次备份;save 300 10 表示300s内有10条写入,就产生快照

10. AOF原理

通过将发送到服务器的写操作命令记录下来,形成AOF文件,文件默认名称是appendonly.aof,可以通过appendfilename来指定文件名称

对应配置:appendfsync everysec: 每秒同步一次,最多会丢1s的数据;appendfsync always:把每个写命令都立即同步到aof,很慢,但是很安全;appendfsync no:redis不处理交给OS来处理,非常快,但是也最不安全

11. 集群同步机制

redis可以使用主从同步,从从同步

第一次同步时,主节点做一次BGSAVE,同时将后续修改操作记录到内存buffer,待完成后,将RDB文件全量同步到复制节点;复制节点接受完成后将RDB镜像加载到内存,加载完成后,通知主节点后续增量数据通过AOF日志同步即可,类似于mongodb oplog

12. pipeline的好处

可以将多次IO往返时间缩减为1次,前提是pipeline执行的指令之间没有因果关系

13. 集群HA

  • 哨兵模式侧重于高可用,在master宕机时,从剩下的slave中选举出新的master,继续提供服务
  • cluster模式侧重于扩展性,单个redis内存不足时,对数据进行分片存储

14. 内存淘汰机制

  • 当redis在使用内存达到某个阀值的时候(maxmemory配置),就会触发内存淘汰机制,选取一些key来删除
  1. noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。默认策略
  2. allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key
  3. allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
  4. volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key
  5. volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
  6. volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
  • 不同策略适用场景
  1. Redis只是作为缓存,不作为DB持久化,那推荐选择allkeys-lru

  2. Redis同时用于缓存和数据持久化,那推荐选择volatile-lru

15. 缓存雪崩、击穿、穿透

  • 缓存雪崩

原因: 大面积缓存失效,新的缓存还未到期间,原本应该访问缓存的请求都去查询数据库了,造成数据库服务器压力过大,甚至宕机

解决方法:

  1. 批量往redis存数据的时候,把每个key的失效时间都加个随机值,确保数据不会在同一时间大面积失效
  2. cluster模式部署,将热点数据均匀分布在不同的redis库中,也能避免全部失效
  3. 设置热点数据永不过期,有更新操作就更新缓存
  • 缓存穿透

原因: 用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题

解决方法:

  1. 采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力
  2. 把这些key对应的值设置为null,丢到缓存里面,并设置过期时间
  3. 对于恶意攻击产生的,可以考虑限流,限制IP访问次数
  • 缓存击穿

原因: 一个热点的key,承载了大量的并发,在这个key失效的一瞬间,持续的高并发,会之间请求数据库,相当于在一个伞上凿了一个洞

解决方法:

  1. 设置热点数据永不过期

  2. 增加互斥锁

16. 哨兵

参见: redis

哨兵 + 主从实现redis的高可用

监控:Sentinel不断的检查master和slave是否正常的运行

自动故障转移:能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址

配置提供者:哨兵作为Redis客户端发现的权威来源:客户端连接到哨兵请求当前可靠的master的地址。如果发生故障,哨兵将报告新地址

17. 和memcache的区别

集群: redis和memcache都支持集群

数据类型: Redis支持的数据类型要丰富得多,Redis不仅仅支持简单的k/v类型的数据,同时还提供String,List,Set,Hash,Sorted Set,pub/sub,Transactions数据结构的存储;memcache支持简单数据类型,需要客户端自己处理复杂对象

持久化: redis支持数据落地持久化存储,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用;memcache不支持数据持久存储

分布式:redis支持主从,cluster模式;memcache可以使用一致性hash做分布式,但是要在客户端实现

value大小:memcache是一个内存缓存,key的长度小于250字符,单个item存储要小于1M

memcache支持多核多线程,redis单线程操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值