前言
计算和数据交互在高并发系统中,往往存在很大的访问压力和通信代价。
数据和计算离得越近,这个代价就越小,所以引入单机进程内缓存可以大大提高访问效率。
进程内缓存可以采用带锁的Map或者第三方库,或者自己实现进程内缓存管理,如ConcurrentHashMap,ThreadLocal,guava cache等。
进程内缓存,相比较分布式缓存,可以减轻分布式缓存服务器的访问压力,同时进程内访问,提高数据访问速度,降低系统时延。
但是进程内缓存的缺点是受限于单机内存,同时单机缓存的数据一致性维护也是一道难题,在分布式系统中很难维护缓存命中率,会造成一定的资源浪费。
分布式系统架构中的设计原则之一是:应用层,服务层需要做到无状态。 进程内缓存设计则和这一原则相背。 如果是非高并发系统不建议采用此方案。
方案
RPC通信
进程内缓存的维护,可以基于RPC服务进行数据通知,多个单机服务接收到RPC请求后维护自身进程内缓存,方案的缺点显而易见,一旦通知失败,将会造成局部机器缓存数据不一致问题。
MQ通信
类似于第一个方案,引入MQ方式后,可以基于MQ的持久化及可靠性机制进行进程内缓存更新,但是并没有从根本上解决单机缓存一致性问题,同时引入MQ造成系统复杂度提升。
进程主动拉取
单机节点定时主动拉取数据,定期更新进程内数据,此方案可以解决上述的局部单机数据不一致问题,同时降低了数据更新复杂度,但是在定时更新时间窗口内,应用可能使用到脏数据问题,无法保证数据更新的实时性。
具体采用哪种方式需要结合系统对于一致性,实时性,时间窗口等特点进行针对性设计。
场景
缓存数据本身有期使用特点,如数据只读,数据更新频繁,数据一致性要求高等特点。
只读数据
只读数据我们只需要将其加载到进程内即可,不用担心脏数据问题,无需维护其数据一致性。 我们可以在系统启动时进行数据拉取放入进程内。
高并发要求
进程内缓存可以作为高并发场景下对于集群压力保护的第一道闸门,抵挡一部分流量,但是在数据一致性,集群稳定性,业务压力预估,运营策略等多角度评估系统负载能力。
允许一定数据不一致
上面几种进程内缓存方案都会面对不同数据不一致问题,理论上业务系统一般不会有极强一致的数据一致性要求,所以进程内缓存数据通过定时更新拉取进行数据同步,可以满足大部分业务系统的需求。