一:什么是redis?
Redis是一个高速缓存数据库,也是一个Nosql数据库。Redis具有很高的存取性能,一般用作缓存数据库,减少正常存储数据库的压力。
ps: 因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小。
可在配置文件中设置内存大小
//设置Redis最大占用内存大小为100M
maxmemory 100mb
redis的配置文件不一定使用的是安装目录下面的redis.conf文件,启动redis服务的时候是可以传一个参数指定redis的配置文件的。
二:redis相比memcache的区别
memcache是一套分布式的高速缓存系统,
1.存储方式不同:memcache将所有数据存储到内存中,断电后数据库会挂掉。redis可对数据进行持久化,存在硬盘上。
2.数据支持的类型不同:memcache 支持的数据类型是简单的字符串,redis有丰富的数据类型(String、hash、list、zset、set)。
3.支持的value大小不一样,redis最大支持1GB,而memcache只有1MB。
4.redis速度比memcache快
5.Mencached不支持分布式,只能在客户端使用一致性hash来实现分布式存储,这种方式在存储和查询时都需要在客户端先计算一次数据所在的节点。redis cluster实现了分布式的支持
三:为什么redis速度那么快?
(1)完全基于内存。
(2)是使用单进程单线程模型的数据库。
(3)单线程也可处理高并发请求,还可以避免频繁上下文切换和锁竞争。
四:redis持久化机制
redis有两种持久化方式
1.RDB(基于快照)持久化
在指定的时间间隔内,生成数据集的该时间点的快照。
RDB持久化方式:
RDB 有两种持久化方式:手动触发 和 自动触发。
1)手动触发
(1)save命令:会阻塞当前 Redis 服务器响应其他命令,直到 RDB 快照生成完成为止,对于内存 比较大的实例会造成长时间阻塞,所以线上环境不建议使用
(2)bgsave命令:Redis 主进程会 fork 一个子进程,RDB 快照生成有子进程来负责,完成之后,子进程自动结束,bgsave 只会在 fork 子进程的时候短暂的阻塞,这个过程是非常短的,所以推荐使用该命令来手动触发。
2)自动触发
(1)在配置中配置了 save 相关配置信息
比如:“save m n ”m秒内数据集存在 n 次修改时,会自动触发 bgsave。
save 900 10 900秒内修改10次就会自动触发bgsave。
(2)在主从情况下,如果从节点执行全量复制操作,主节点自动执行 bgsave 生成 RDB 文件并发送给从节点。
(3)执行flushall,flushall 命令用于清空 Redis 数据库,在生产环境下一定慎用,当 Redis 执行了 flushall 命令之后,则会触发自动持久化,把 RDB 文件清空。
此处参考:https://www.zhihu.com/search?type=content&q=redis%20%20RDB
优点:
(1)RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集, 这文件非常适合用于进行备份。
(2)RDB 可以最大化 Redis 的性能(提高运行速度):父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
(3)RDB是备份了数据库的状态, 在恢复大数据集时的速度比 AOF 的恢复速度要快。
缺点:
(1)可能会造成数据的丢失,因为RDB是在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。
(2)每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。
(3) RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题(版本不兼容)
2.AOF(基于日志)持久化
记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF文件记录了除查询以外的所有变更数据库状态的指令。
AOF持久化方式:
Redis 默认并没有开启 AOF 持久化方式,需要我们自行开启,在 redis.conf 配置文件中将 appendonly no 调整为 appendonly yes,这样就开启了 AOF 持久化。
优点: 因为AOF文件记录了服务器执行的所有写操作命令,所以可读性高,数据不易丢失
缺点: 文件体积大,恢复速度慢。
3.如何选择合适的持久化方式?
五: redis的五种数据类型及使用场景
参考另一篇博文:Redis五种数据类型及应用场景
六:redis 的过期键的删除策略:
(1)定时删除:
在设置键的过期时间的同时,创建一个定时器,让定时器在键过期时间来临时,立即执行对键的删除操作。
优点:对内存是友好的,可以保证过期键会尽可能快被删除,并释放过期键所占用的内存。
缺点:对CPU不友好,在过期键较多的情况下,删除键的操作会占用相当一部分的CPU时间,在内存不紧张但CPU紧张的情况下,将cpu时间用在删除与当前任务无关的过期键上,无疑会对服务器的响应时间和吞吐量造成影响。
(2)惰性删除:
仅在程序取出键时才进行过期检查
优点: CPU友好,不会花费额外的时间。
缺点:对内存不友好,会造成内存泄漏。
(3)定期删除:
每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行的时长和频率来减少对CPU时间的影响
七:redis的6种数据淘汰策略
如果失效的key没有被访问,也未被主动删除随机选中,那这个失效的key什么时候被删除呢??
redis中有一个maxmemory配置,即redis最大能使用的内存,当redis的使用内存达到这个值,会根据配置的淘汰策略,对redis的key进行淘汰。
- noeviction:(不删除,返回错误)当内存使用超过配置的时候会返回错误,不会驱逐任何键
- allkeys-lru:(删除所有key中最久没使用的)加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键
- volatile-lru:(删除过期key中最久没使用的)加入键的时候,如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键
- allkeys-random:(所有key中,随机删除)加入键的时候,如果过限,从所有key随机删除
- volatile-random:(过期key中,随机删除)加入键的时候,如果过限,从过期键的集合中随机驱逐
- volatile-ttl:(删除马上要过期的)从配置了过期时间的键中驱逐马上就要过期的键
八:单机、集群、分布三种结构
1.单机结构
一个系统业务量很小的时候所有的代码都放在一个项目中,然后这个项目部署在一台服务器上。整个项目所有的服务都由这台服务器提供。这就是单机结构。
缺点:单机的处理能力毕竟是有限的,当你的业务增长到一定程度的时候,单机的硬件资源将无法满足你的业务需求。
2.集群结构
简单来说就是:单机处理到达瓶颈的时候,就把单机复制几份,这样就构成了一个“集群”。
集群中每台服务器就叫做这个集群的一个“节点”,所有节点构成了一个集群。每个节点都提供相同的服务,那么这样系统的处理能力就相当于提升了好几倍(有几个节点就相当于提升了这么多倍)。
用户的请求究竟由哪个节点来处理呢?在所有节点之前增加一个“调度者”的角色-----负载均衡服务器,通过一定算法将请求分到对应的服务器进行处理。尽量让负载较小的节点来处理,这样使得每个节点的压力都比较平均。
好处:就是系统扩展非常容易。但是,当业务发展到一定程度的时候,会发现一个问题——无论怎么增加节点,貌似整个集群性能的提升效果并不明显了。
3.分布式结构
分布式结构就是将一个完整的系统,按照业务功能,拆分成一个个独立的子系统,在分布式结构中,每个子系统就被称为“服务”。这些子系统能够独立运行在web容器中,它们之间通过RPC(远程过程调用)方式通信。
好处:
(1)系统之间的耦合度大大降低,可以独立开发、独立部署、独立测试,系统与系统之间的边界非常明确,排错也变得相当容易,开发效率大大提升。
(2)系统之间的耦合度降低,从而系统更易于扩展。我们可以针对性地扩展某些服务。
(3)服务的复用性更高。比如,当我们将用户系统作为单独的服务后,该公司所有的产品都可以使用该系统作为用户系统,无需重复开发。
此处参考:https://www.zhihu.com/question/20004877/answer/282033178
九: 三高:高并发、高性能、高可用
1.高并发
通过设计系统能够同时并行处理很多请求。
常见的几个指标:
响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。
吞吐量:单位时间内处理的请求数量。
QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显。
并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度上代表了系统的并发用户数
2.高性能
简单来说:高性能就是指程序处理速度快,所占内存少,cpu占用率低。
3.高可用
系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性(一直都能用)。
十:redis的三种集群方式
Redis复制(主从)
Redis哨兵(Sentinel)
Redis集群
1.主从复制(Master-Slave)
主从复制简单来说就是:主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主。
有以下特点:
1.master(主库)一般是接受写的,slave(从库)只接受读操作。
2.当master接受写操作后会将命令发送给slave执行,从而实现数据一致性
3.一个master下面可以有多个slave,但是一个slave上面只能有一个master
原理:
1 slave连接主服务器发送sync命令。
2 master持久化数据生成rdb文件并缓存这段时间的写命令
3 master向slave发送rdb文件和缓存的命令
4slave载入rdb快照后执行缓存的命令(slave初始化完成)
5 master每接收到一个写命令就发送给slave执行(从服务器初始化完成后的操作)
缺点: 延时,由于所有的写操作都是在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使得这个问题更加严重。
2 .哨兵模式
哨兵是用来监控主从数据库的,当master挂掉后选择一个salve当做master。
与master建立连接后,哨兵会执行三个操作,这三个操作的发送频率都可以在配置文件中配置:
定期向master和slave发送INFO命令
定期向master和slave的_sentinel_:hello频道发送自己的信息
定期向master、slave和其他哨兵发送PING命令
master挂掉后从slave中选取规则
1.所有在线的slave中选择优先级最高的,优先级可以通过slave-priority配置
2.如果有多个最高优先级的slave,则选取复制偏移量最大(即复制越完整)的当选
3.如果以上条件都一样,选取id最小的slave
3.集群:
redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容。
使用集群,只需要将每个数据库节点的cluster-enable配置打开即可。每个集群中至少需要三个主数据库才能正常运行。
十一:Redis 两种消息通信模式
1. 队列模式
lpush:入队命令
rpop:出队命令
Redis 队列模式其实是通过基本数据类型「列表」来实现的,即数据从列表的一端「入队」,另一端「出队」。
比如,消息入队顺序是1,2,3,4,5,6,那么出队顺序是:6,5,4,3,2,1。这是「左进右出」,也可以是「右进左出」。
与此类似,也可以使用「左进左出」的命令组合 lpush/lpop 或「右进右出」的命令组合 rpush/rpop 来实现「栈」的结构。
2. 发布订阅模式
发布者(pub)发送消息,订阅者(sub)接收消息。
发布者和订阅者之间通过频道(Channel)进行通信。
具体内容参考右侧链接:https://zhuanlan.zhihu.com/p/107109334