在后端系统中,因为数据库读写性能所限,性能瓶颈每每出如今数据库上,为了下降数据库访问压力,能够采起的方式有缓存、数据库读写分离、分表等数据库
其中,对于数据库读取压力过大的状况,缓存能够说是首选解决方式后端
缓存按照数据存储位置来区分,缓存能够分为两种: 进程内缓存与进程外缓存缓存
进程内缓存: 最简单的能够直接用语言内的散列表(Java HashMap,Python字典 等),或者一些功能更完善的第三方库网络
进程外缓存: 常见的如Redis,Memcache等session
下面的表格是二者之间一些优缺点的对比, 下文将逐条分析这些优缺点负载均衡
/ | 进程内缓存 | Redis |
---|---|---|
水平扩展 | 困难 | 简单 |
可靠/易用 | 没有过时,内存淘汰等 | 可靠 |
访问速度 | 直接操做变量,延迟低 | 须要网络传输和序列化 |
可否保存引用类型 | 能够保存引用类型 | 只能存字符串 |
如今的后端程序每每是须要多个节点进行负载均衡对外提供服务的,而进程内缓存只有本节点可以访问性能
在这种场景下,若是使用了进程内缓存,那么也就意味着每一个节点有它本身的"状态",致使在A节点更改了缓存,而B节点缓存数据并不会发生变动,这时再从B节点读取就会获得没有更改过的旧数据,与A节点不一致code
这种不一致有以下解决方式:cdn
N
的增加,由于要同步到每个其余节点,发送N-1
份数据,难以接受在上面列出的几个缺点中,多节点写入致使的数据不一致问题是最严重的对象
面对这种问题,能够经过将对同一个键的写操做都发到同一个节点来避免
Redis提供了键过时,定时清理,内存淘汰等功能,支持多种淘汰策略;而且通过多年大规模的使用,可靠性很高
进程内缓存的另外一个问题就是比较简陋,每每不具有这些功能,可能须要本身处理内存溢出等状况,无疑比较困难
因为客户端和Redis之间须要等待网络通讯的延迟,而且对数据要作额外的序列化和反序列化处理,因此访问速度天然低于直接访问内存变量的进程内缓存
进程内缓存的另外一个优势就是能够保存引用类型,而Redis实际上只能存字符串,这在某些场景中是很是有用的
例如: 缓存定时任务的对象
业务中经常须要让一个任务在某个时间点执行,并可能在执行以前进行取消; 这时候使用进程内缓存保存定时任务的对象就能够很方便的执行对象上的取消定时任务方法了,而使用Redis则难以作到这一点
Redis之类的进程外缓存功能比较完善,通常状况下直接使用它便可
可是进程内缓存在某些场景中也颇有用处,例如: