Redis知识点总结
后续会继续更新。
Redis知识点总结
redis特点
基于内存的分布式高性能key-value数据库。
- 高性能:1.纯内存操作;2.单线程模型;
- 分布式:1.默认16个数据库,初始默认使用零号数据库;2.redis支持分布式扩展 ;
特点:
1.数据库操作读写在内存中完成,纯内存操作,磁盘用来做持久化,性能出色;
2.支持多种数据结构,单个value最大限制为1gb ;
3.可以将数据复制到任意数量的从机中 缺点:数据库操作受限于自身物理内存,不能作为海量数据的高性能读写,适合较小数据量的高性能读写;
4.单进程服务器模型与多路IO复用模型,非阻塞IO,采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
安装与配置
数据结构
内容过多,后面直接放链接。
客户端
python客户端
1.https://www.cnblogs.com/-wenli/p/10958055.html 2.https://www.cnblogs.com/-wenli/p/10992152.html
go语言客户端
1.https://www.cnblogs.com/-wenli/p/12221495.html
持久化
RDB 全量持久化(冷备)
RDB快照持久化机制,是对 Redis 中的数据执行周期性的持久化,把内存中的数据集以快照形式写入磁盘,实际操作是通过 fork 子进程执行,采用二进制压缩存储;
如何持久化:Redis会单独创建(fork)一个子进程来进行持久化,不同时刻会生成不同时刻的数据文件,每个数据文件分别都代表了某一时刻Redis里面的数据。
Fork:Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常的敏感,那RDB方式要比AOF方式更加高效。
优点:
1.RDB主进程在做快照写入磁盘过程中不进行任何IO操作,对Redis的性能影响非常小,是因为在同步数据的时候他只是fork了一个子进程去做持久化的,而且他在数据恢复的时候速度比AOF来的快。
适合冷备:恢复到某一时刻的数据。
缺点:
1.在一定间隔时间做一次备份,所以如果redis意外down掉的化,就会丢失最后一次快照后的所有修改。 2.Fork的时候,内存中的数据被克隆一份,大致2倍的膨胀性需要考虑。
AOF增量持久化(热备)
AOF 机制以日志文本的形式记录redis命令,以 append-only(追加) 的模式写入一个日志文件中。
如何持久化:RDB五分钟一次生成快照,但是AOF是一秒一次去通过一个后台的线程fsync操作,最多丢这一秒的数据。
优点:
1.数据备份更完整,支持同步与异步两种方式。
缺点:
1.相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb。
2.Aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同。
RDB与AOF如何选择
单独使用RDB会丢失很多数据,单独使用AOF,数据恢复没RDB恢复快,做数据恢复时第一时间用RDB恢复,然后AOF做数据补全,冷备热备兼备。
注意:RDB和AOF同时存在时,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
淘汰策略和主键失效机制
缓存系统都要定期清理无效数据,就需要一个主键失效和淘汰策略.在Redis当中,有生存期的key被称为volatile。在创建缓存时,要为给定的key设置生存期,当key过期的时候(生存期为0),它可能会被删除。
主键失效机制
Redis处理过期key机制
- 主动机制:当一个key被主动访问时,会对key进行超时判断,过时的key会立即删除。
- 被动机制:
- 当一个key过期了,但是没有被访问,redis会定时扫描(10s),定时扫描过程 :
- 1.从过期key中随机选出20个key,过期扫描不会遍历过期的所有的key;
- 2.删除这20个key中已经过期的key;
- 3.如果过期的key的比例超过了1/4,就重复步骤1;
- 注意:如果扫描时间达到了25ms,停止本次扫描。
处理过期keys的命令
1.expire : 设置过期时间。格式是:expire key值 秒数
2.expireat : 设置过期时间,格式是:expireat key值 到期的时间戳
3.ttl : 查看还有多少秒过期,格式是:ttl key值, -1表示永不过期,-2表示已经过期
4.persist : 设置成永不过期,格式是:persist key值 删除key的过期设置; 5.另外使用set或者getset命令为键赋值的时候,也会清除键的过期时间。
6.pttl:查看还有多少毫秒过期,格式是:pttl key值
7.pexpire : 设置过期时间,格式是:pexpire key值 毫秒数
8.pexpireat : 设置过期时间,格式是:pexpireat key值 到期的时间戳
影响生存时间的一些操作
1.PERSIST命令可以在不删除 key 的情况下,移除 key 的生存时间,让 key 重新成为一个永远不过期 key 。
2.EXPIRE命令可以重新指定key的生存时间,新的生存时间会取代旧的生存时间。
如何更新生存时间
可以对一个已经带有生存时间的 key 执行EXPIRE命令,新指定的生存时间会取代旧的生存时间。过期时间的精度已经被控制在1ms之内,主键失效的时间复杂度是O(1),EXPIRE和TTL命令搭配使用,TTL可以查看key的当前生存时间。设置成功返回 1;当 key 不存在或者不能为 key 设置生存时间时,返回 0 。
淘汰策略:内存淘汰策略:主动机制和被动机制都没有删掉过期key
redis 提供 6种数据淘汰策略:
- volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- no-enviction(驱逐):禁止驱逐数据
注意这里的6种机制,volatile和allkeys规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的lru、ttl以及random是三种不同的淘汰策略,再加上一种no-enviction永不回收的策略。
使用策略规则:
1.如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru
2.如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkeys-random
缓存问题
缓存分类
- 本地缓存:在进程的内存中进行缓存,本地缓存是内存访问,没有远程交互开销,性能最好,但是受限于单机容量,一般缓存较小且无法扩展。
- 分布式缓存:分布式缓存一般都具有良好的水平扩展能力,对较大数据量的场景也能应付自如。缺点就是需要进行远程请求,性能不如本地缓存。
- 多级缓存:为了平衡本地缓存与分布式缓存,实际业务中一般采用多级缓存,本地缓存只保存访问频率最高的部分热点数据,其他的热点数据放在分布式缓存中。
缓存问题
1.缓存更新方式与缓存不一致的解决方法:https://www.cnblogs.com/-wenli/p/11474164.html
2.缓存穿透:查询缓存不命中,然后穿透 DB 查询依然不命中。这时会有大量请求穿透缓存访问到 DB。
解决办法:
- 对请求参数进行检验,非法或者不合理的请求直接拦截。
- 网关层,如nginx配置中对一秒内访问次数超过阈值的IP拉黑
- 使用 BloomFilter 过滤器,BloomFilter 的特点是存在性检测,利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。
3.缓存击穿:某个热点数据失效时,大量针对这个数据的请求会穿透到数据源。
解决办法:
- 可以使用互斥锁更新,保证同一个进程中针对同一个数据不会并发请求到 DB,减小 DB 压力。
- 使用随机退避方式,失效时随机 sleep 一个很短的时间,再次查询,如果失败再执行更新。
- 针对多个热点 key 同时失效的问题,可以在缓存时使用固定时间加上一个小的随机数,避免大量热点 key 同一时刻失效。
3.缓存雪崩:原因是缓存在同一时间挂掉,这时所有的请求都会穿透到 DB。
解决办法:
- 设置每个Key的失效时间为随机值:setRedis(Key,value,time + Math.random() * 10000);。
- 使用快速失败的熔断策略,减少 DB 瞬间压力。
- 使用主从模式和集群模式来尽量保证缓存服务的高可用。
缓存击穿和缓存雪崩的区别:
缓存雪崩是因为大面积的缓存失效,打崩了DB,而缓存击穿不同的是缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。
Redis Sentinal(哨兵)、主从
哨兵+主从可以保证集群的高可用,但并不能保证数据不丢失。
主从
主从配置:
主从特性:
- 主从复制:从机会同步主机操作;
- 主从读写分离:只有主机可以写,从机只能读;
- 主机宕机:主机宕机后,从机原地待命,如果主机恢复,则继续工作;
- 从机宕机:从机宕机后,再次启动就会是主机角色,所以需要连接原本的主机;
- 薪火相传: 上一个Salve可以是下一个Slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为链条中下一个Maste,可以有效减轻master的写压力;
- 手动版反客为主:当主机宕机时,从机原地待命不动,在实际中当然不能这样做,我们要在从机中选择一个做主机。
主从原理和过程(同步机制):
当你启动一台从机的时候,他会发送一个psync命令给主机 ,如果是这个从机第一次连接到主机做第一次同步时,会触发一个全量复制。主机就会启动一个线程,做一次bgsave,并同时将后续的写请求记录到内存buffer,待完成后将rdb文件全量同步到从机,从机接受完成后将rdb镜像加载到内存。加载完成后,再通知主机将期间后续的写请求记录同步到从机进行重放就完成了同步过程。
主从同步的时候,新的slaver进来的时候用RDB,那之后的数据呢?有新的数据进入master怎么同步到slaver,AOF,把日志增量同步给从机。
哨兵
哨兵配置:
哨兵作用:自动版反客为主,能够后台监控主机是否故障,如果故障了根据投票数自动将从机转换为主机。
哨兵特性:
- 集群监控:负责监控 Redis master 和 slave 进程是否正常工作。
- 消息通知:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
- 故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
- 配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。
redis Cluster
Redis Cluster可以保证集群的扩展性。
Redis Cluster特点:
- 去中心化:集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态
- 互联:每个节点都和其他所有节点连接,内部使用二进制协议优化传输速度和带宽,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。
- 判断某个节点fail:通过集群中超过半数的节点检测失效时才生效。
- Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。
- redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。
redis Cluster配置
1.https://www.cnblogs.com/diegodu/p/9183356.html
2.https://www.cnblogs.com/lykxqhh/p/5690923.html
redis的应用场景及实现
热点缓存:将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。
计数器:可以对 String 进行自增(incr)自减运算(decr),从而实现计数器功能。Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。
限流器:
- 计数器
- 漏牌
- 令牌桶
分布式锁:setnx\expire\del,先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。
消息队列:
- 普通队列
- 延时队列
- 异步队列
小功能
1.Set 可以实现交集、并集等操作,从而实现共同好友等功能。
2.ZSet 可以实现有序性操作,从而实现排行榜等功能。
高级功能
- 缓存高级用法
- hyperLogLog
- geospatial
- pub/sub
- Bitmap
- Redis Module
- pipeline
- lua脚本
性能检测与监控工具
性能检测工具
redis-benchmark(redis系统自带):Redis自带的性能检测工具, 该工具可以模拟 N 个客户端同时发出 Y 个请求。可以使用 redis-benchmark -h 来查看基准参数。
监控工具
- redis-cli(redis系统自带):查看redis的连接及读写操作。
- showlog(redis系统自带):redis的slowlog是redis用于记录记录慢查询执行时间的日志系统。由于slowlog只保存在内存中,因此slowlog的效率很高,完全不用担心会影响到redis的性能。Slowlog是Redis从2.2.12版本引入的一条命令。
- RedisLive:RedisLive是由Python编写的开源的图形化监控工具。核心服务部分只包括一个web服务和基于Redis自带的Info命令以及monitor命令的监控服务。支持多实例监控,监控信息可以使用redis存储和sqlite持久化存储。