Redis--回顾提要
一、写在前
知识学了就忘!不用就忘!我太健忘!特此记录!用于复习打卡!Redis干就完事了!
二、来辣!
-
Redis做异步队列:一般list结构做队列,rpush生产消息,lpop消费消息,当lpop没有消息的时候,要适当sleep一会儿;如果不sleep,就用blpop,会阻塞;生产一次消费多次,使用pub/sub主题订阅模式,可以实现1:N的消息队列,缺点:消费者下线的时候,消息会丢。
-
做延时队列:使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒前的数据轮询处理。
-
Redis分布式锁:拿setnx来争抢锁,抢到之后再用expire给缩加一个过期时间防止锁忘记释放。如果在setnx之后,expire之前进程意外crash或者重要维护了,咋办:锁永远得不到释放,咋办:set指令有复杂的参数,可以把setnx和expire合成一条指令执行哒。
-
memched与redis区别:redis支持string,list,set,zset,hash,HyperLogLog,Geo,Pub/Sub。memcached支持简单字符串;redis更快;redis支持持久化。
-
redis没有使用一致性hash,而是引入哈希槽的概念:redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放哪个槽,集群的每一个节点负责一部分hash槽。
-
redis集群方案什么情况下会导致整个集群不可用:三个节点的集群,在没有复制模型的情况下,如果B节点挂了,整个集群会因为缺少5501-11000这个范围的槽而不可用。
-
为什么这么快:完全基于内存;数据结构简单,对数据操作简单;采用单线程,避免不必要的上下文切换和竞争条件,也不存在多进程和多线程导致的切换而消耗CPU,不存在加锁释放锁操作,也不会死锁;使用I/O复用模型,非阻塞IO;自己构建了VM机制,一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
-
场景:计数器;缓存;session缓存;全页缓存(FPC);消息队列(发布订阅);分布式锁(setnx或RedLock);set交集、并集找共同好友;zset可以实现有序,排行榜等功能。
-
RDB:默认,将内存中的数据以快照方式保存到硬盘,产生dump.rdb文件。优点:只有一个文件,方便持久化;容灾性好,一个文件可以保存到安全的磁盘。性能最大化,fork子进程完成写,主进程继续处理命令,IO最大化,主进程没有任何IO,高性能。缺点:安全性低,如果持久化之间挂了,丢一部分数据。
-
AOF:append-only file。两种方式同时开启,恢复数据会先用AOF。优点:数据安全,可以配置appendfsync属性,有always,每进行一次命令就记录一次;通过append模式写文件,即时中途宕机,可以通过redis-check-aof工具解决一致性问题;rewrite模式,(文件过大时会对命令进行合并重写),没有rewrite之前,可以删除某些命令,(比如误操作的flushall)。缺点:文件大,恢复慢;数据集大的时候,比rdb启动效率低。
-
当做缓存时如何扩容:使用一致性哈希实现动态的扩容缩容。
-
当做持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定就不能变。
-
过期键的删除策略:1)定时过期:每个设置过期时间的key都要创建一个定时器,到过期时间就会立即清除。立即清除,对内存友好。但会占用大量的cpu资源,影响响应时间和吞吐量。2)惰性过期:当访问的时候,才去判断是否已过期,过期就清除。可最大化节省cpu资源,对内存不友好;但是极端情况下,可能出现大量过期的key未被清理,占用大量内存。3)定期过期:折中方案,每隔一定时间,会扫描一定数量的expires字典中一定数量的key,并清除其中过期的。(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指redis中存储的所有键。)默认同时使用了惰性过期和定期过期。
-
expire设置过期时间,persist设置永久有效。
-
内存淘汰策略:(用于缓存的内存不足时,怎么处理新写入且需要额外申请空间的数据)。1)noevication,禁止淘汰,写入会报错。2)allkeys-lru:全键空间内,移除最近最少使用的(常用)。3)allkeys-random:随机移除。4)volatile-lru:设置了过期的键空间中,移除最近最少使用的。5)volatile-random:随机移除。6)volatile-ttl:设置了过期的键空间中,优先移除有更早过期时间的key。
-
内存优化:合理利用集合类型,小的k/v可以以更紧凑的方式存放,尽可能使用散列表(hashes),散列表使用的内存小。尽可能将数据抽象到一个散列表,比如用户,的名称,密码等所有信息存储到一个散列表。
-
事务:事务中的所有命令都会被序列化,就是一次性、顺序性、排他性的执行一个队列中的一系列命令。三个阶段:事务开始MULTI-命令入队-事务执行EXEC。执行过程中,如果服务端收到EXEC、DISCARD、WATCH、MULTI之外的请求,会把请求放入对列中排队。WATCH命令是一个乐观锁,可以为redis事务提供CAS行为。可以监控一个或多个键,一旦其中有一个键被修改、删除,之后的事务不会被执行,监控一直持续到EXEC命令。MULTI用于开启事务,总是返回OK,开启后,可以继续向服务器发送任意多行命令,不会立即执行,被放队列,当EXEC被调用时才执行。EXEC用于执行事务块内的命令,返回所有事务块中命令的返回值,按命令执行的先后顺序排序,当操作被打断,返回空值。DISCARD可以清空事务列表,并放弃执行事务,并且客户端会从事务状态中退出。UNWATCH可以取消watch对所有key的监控。
-
redis的事务总是支持ACID中的一致性和隔离性,其他不支持。当运行在_AOF_持久化模式下,且appendfsyn选项为always时,事务也具有 耐久性。
-
单条命令是原子性执行的,基于Lua脚本,可以保证脚本内命令一次性、顺序执行完成。但是事务不保证原子性,且没有回滚。事务的任意命令执行失败,其余命令也会继续执行。
三、写在后
只是简要知识点概括,看到就能回忆起相关内容为最妙~~直接评论打卡,开整!!!
作者: letscrazy
出处: https://www.cnblogs.com/letscrazy/
关于作者:letscrazy
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(licz163@163.com)咨询.