基本概念
非关系型数据库。可以存储键(字符串)和五种不同的数据类型的映射。
优点:
- 读写性能好(基于内存,类似于HashMap数据结构简单,单线程)
- 支持数据持久化
- 支持事务
- 数据结构丰富
- 支持主从复制,进行读写非分离
缺点:
- 容量收到物理内存的限制
- 不具备自动容错和恢复
- 主机宕机,未能及时同步数据到从机
- 难在线扩容
基本数据类型
- String: 字符串、整数、浮点数
- List:列表。
- Set:无序集合。数据结构类似hashmap
- Hash:包含键值对的无序散列表
- Zset:有序集合,数据结构类似listhashmap
持久化
将内存中的数据写入到磁盘中,防止服务器宕机导致内存数据丢失。
RDB:
默认方式,按照一定的时间将内存的数据以快照的方式保存到硬盘中产生的文件为dump.rdb。配置文件中的save参数定义快照周期。
优点:只有一个文件,方便持久化;性能最大化,fork子进程完成写操作,主进程继续处理命令。IO最大化。数据大时,比AOF的启动效率高。
缺点:数据安全性低;隔一段时间持久化,如果持久化时发生故障,数据会丢失。
AOF
将Redis执行的每次写命令记录到单独的日志文件,重启Redis会将文件中的AOF恢复。两种持久化方式同时开启,数据恢复优先选择AOF。
优点:数据安全,可以配置appendfsync属性,always,每进行一次命令操作就会记录到AOF文件中。通过append写文件,即使服务器宕机,可以通过Redis-check-aof工具解决数据一致性问题。文件没被rewrite之前,可以删除其中的某些命令
缺点:AOF文件较于Rdb文件大,回复速度慢;数据大的时候启动效率较低。
过期键的删除策略
-
定时过期:给key设置定时器,到了过期时间就会清除。会占用很多CPU资源。
-
惰性过期:只有当访问key时才会判断是否过期,过期就清除。占用很多内存。
-
定期过期:每隔一定时间,扫描一定数量的数据库的expires中的一定数量key,并且清除其中的过期的key。
线程模型
因为Redis基于内存操作,CPU不是Redis的瓶颈,所以才用单线程。
基于Reactor模式开发了网络事件处理器(文件事件处理器)。分为多用套接字、io多路复用程序、文件事件分派器、事件处理器。文件事件分派器队列的消费是单线程的,所以Redis是单线程模型。
-
文件事件处理器使用IO多路复用程序监听多个套接字,根据其执行的任务来关联事件处理器。
-
被监听的套接字准备好执行连接应答、读取、写入、关闭等操作时,与操作对应的文件事件就会产生,事件处理器就可以处理了。
即使是单线程,但是通过io多路来监听多个套接字,也可以实现高性能网络通信模型。
事务
事务是一个单独的隔离操作:事物的所有的命令都会被序列化、按顺序执行。acid性
Redis事务:本质是通过MULTI、EXEC、WATCH、Discard等一组命令的集合。不支持事务回滚和不保证事务的原子性。
MULTI:开启一个事务
WATCH:乐观锁,提供check-and-set(cas)行为。键控键,一个键被修改之后的事务都不会执行,持续到exec
EXEC:执行完事务块内的所以命令。返回所有返回值。
Discard:清空事务队列,放弃执行事务,客户端从事务状态退出。
集群方式
-
twemproxy:类似于一个代理方式,使用时将需要连接的地方改为twemproxyy,以代理的身份接收请求,使用hash算法后将请求接到具体的Redis,将结果返回twemproxyy。
-
codis:支持在节点数量改变的情况下,旧节点可以恢复到新的hash节点。
-
redis cluster3.0 :自带的集群,算法是hash槽。
分区
分区可以让Redis管理更大的内存,使用多台机器的内存。
- 客户端分区:在客户端就已经决定数据存储的位置。
- 代理分区:客户端将请求发送给道理,代理决定节点。
- 查询路由:客户端随机的请求一个Redis实例,将请求发给正确的节点。
缓存异常
缓存雪崩
同一时间缓存大面和失效,后面的请求落到数据库上,造成数据库承受大量请求崩掉
解决:
-
缓存数据的过期时间设置随机
-
加锁排队
-
给缓存数据增加缓存标记
缓存穿透
缓存和数据库中都没有数据,导致请求落到数据库上,造成数据库承受大量请求崩掉
缓存击穿
缓存中没有但数据库中有的数据(一般是缓存时间到期),由于并发多,同时没有读取到数据,同时去数据库。
缓存预热
系统上线后,将相关的数据直接加载到缓存系统。
缓存降级
访问剧增,服务器出问题,根据一些关键数据进行自动降级,或者人工降级。