为什么使用缓存,缓存带来的问题,分布式缓存,单机架构,分布式架构

一、为什么需要缓存

提高系统访问的吞吐量和降低数据库的流量压力

没有缓存的数据库访问
假如我们的数据库使用的是非关系型数据库,比如mysql数据库,mysql数据库分为innodb和MyISAM存储引擎,innodb分为frm和ibd文件,myISAM分为frm,myi,myd文件,不论innodb还是MyISAM文件,其数据都是存储在磁盘上的。

假如mysql某张表存储大量的数据,用户在某短时间大量访问数据库,而数据必须将加载到内存才能执行。从磁盘上将大量数据,加载到内存当中,还是非常耗时的。如果是高并发的状态下,极容易是数据库宕机。

同时,Java采用jdbc的方式与与mysql服务器建立,而jdbc内部采用的socket通信【StandardSocketFactory来创建通信的socket】,而socket建立远程连接会有会有两处阻塞,连接组设和读写阻塞,如下图所示:
socket通信
基于以上通信所带来的阻塞和高并发给数据库带来的流量冲击,如果用户不直接访问数据库,而是从某个内存中读取,那么,这样可以减缓上述的两个问题,即
引入缓存

实现数据共享

此外,客户端与服务端的session会话,如果是单机的情况下,对于同一个用户来说,可以直接使用即可,因为session是tomcat是创建并保存的,如图所示
Tomcat创建session的过程.jpg在这里插入图片描述
但是,随着电商的崛起,传统的单机模式显然不适合当代的分布式架构。分布式架构简单的来理解,为了实现服务器的高可用和高性能,将服务拆分并部署到多台服务器上,用zookeeper进行服务协调,netty/Dubbo进行服务间的通信,使用docker快速搭建web访问的环境,比如Tomcat nginx mysql等。

既然session是有Tomcat生成的,那么每个jvm进程都会生成不同的session,假如有两台订单服务器,这就造成了同一个用户在订单服务器1上的session和订单服务器2上的session不一致的问题,因而,需要一个中间件来存储同一个用户的session。

因而,这里就需要对分布式的共享数据进行存储。

二、如何引入缓存

我们既然知道了缓存的重要性,那么也要区分在单机情况下的缓存和分布式情况下的缓存。

单机缓存

jvm进程中的数据如果不被Gc回收,也不被序列化出JVM,他们的生命周期就是JVM的生命周期。比如hibernate的SQLSession会话,在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。

一般情况下,单机缓存使用HaspMap来存储,hashMap维护的是Entry对象,entry对象维护忽的key和value值,这是一种强引用的关系,比如SQLSession --> cacheHasMap --> entry --> object,JVM即便报出oom也不会回收对象。

比如在我的博文 对外api的架构设计 文章中,使用concurrentHashMap作为存储IP的缓存,key值为某个公司的id,value值为该公司下的所有已配置的IP,这样如果缓存中存在这样的IP,那么就不用了访问数据库查询了,这样可以提高性能和降低数据库的读压力。

分布式缓存

为了实现同一个用户不论登录哪台服务器,其获取到的session都是相同的,最常用的还是Redis实现缓存。想要了解更多与Redis相关的知识,请点击我的博文:Redis的那些事情。

如何实现分布式缓存,可以采用Redis的hash数据类型,hash数据类型采用键值对的形式来存储的:

  1. hash值计算:通过支持MD5与MurmurHash两种计算方式,默认是采用MurmurHash,高效的hash计算。
  2. 一致性的实现:通过Java的TreeMap来模拟环状结构,实现均匀分布
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网全栈开发实战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值