Nginx+Redis+Ehcache大型高并发高可用三层架构总结
在生产环境中,对于高并发架构,我们知道缓存 是最重要的环节,对于大量的高并发。可以采用三层缓存架构来实现,也就是Nginx+Redis+Ehcache
对于中间件Nginx常来做流量分发,同事nginx本身也有自己的缓存机制,但是呢,容量也是有限,我们可以用来缓存热点数据,让用户的请求直接走缓存并返回,从而减少流向服务器的流量
一:模板引擎
通常可以配合使用freemaker/velocity等模板引擎来抗住打量的请求
小型系统可能直接在服务器端 渲染出所有页面并放入缓存,之后的相同页面 请求就可以直接返回,不用去查询数据源或者做数据逻辑处理
二:双层nginx来提升缓存命中率
对于部署多个nginx而言,如果不加入 一些数据的路由策略,那么可能导致每个nginx的缓存命中率很低,因此可以部署双层Nginx
分发层nginx负责流量 分发的逻辑和策略,根据自己定义的一些规则,比如根据productld(产品表示)进行hash,然后对后端nginx数据访问 固定路由到一个nginx后端服务器上去,后端nginx用来缓存一些热点数据到自己的缓存区;
用户的请求,在nginx没有缓存相应数据,那么进入到redis缓存中,redis可做到全量数据的缓存,通过水平扩展能够提升高并发,高可用能力,
一:持久化机制
所谓持久化 机制就是讲redis内存中的数据持久化到磁盘中,然后可以定期讲磁盘文件上传到S3或 这云存储 服务上去
如果同时使用RDB和AOF两种持久化机制,那么在redis重启的时候,会使用AOF来重新构建数据,因为AOF中的数据更加完善,建议将两种持久化机制都开启,用AOF来保证数据不丢失,作为数据恢复的首选;而RDB用来做不同程度的冷备,在AOF文件都丢失或者损坏不可用的时候快速进行数据恢复
Ps:又一个坑需要踩,对于想从RDB恢复数据,同时AOF开关也是打开的,一直都无法正常恢复,因为每次会优先从AOF获取数据(如果临时关闭AOF,就正常恢复了)这个时候需要先停止redis,然后在关闭AOF,拷贝RDB到相应的目录,启动redis之后热修改配置参数redis config set appendonly yes,此时会自动生成一个当前内存数据的AOF文件,然后再次停止redis,打开AOF配置,在此启动数据及正常启动了,
RDB:对于redis中的数据执行周期性的持久化,每一刻持久化都是全量的数据一个快照,对于redis性能影响较少,基于RDB能够快速的异常恢复
AOF:以append-only的模式写入一个日志文件中,在redis重启的时候 可以通过回放AOF日志中的写入指令来重新构建整个数据集(实际上每次写的日志数据会先到linux OS cache的数据写入磁盘)对redis有一定的影响,能够尽量保证数据的完整性,redis通过rewrite机制来保障AOF文件不会太大,基于内存数据并做到适当的指令重建
二:redis集群
replication
一主多从架构,主节点负责写入,并且将数据同步到其他salve节点(异步执行)从节点负责读,主要是用来做读写分离的横向扩容架构,这种架构的master节点数据一定要做持久化,否则当master宕机重启之后内存数据清空,那么就会将空数据复制到slave,导致所有数据丢失
sentinal哨兵
哨兵是redis集群架构中很重要的一个组件,负责监控redis master和slave进程是够正常工作,当某个redis实例出现故障时,能够发送告警通知到管理员,当master node宕机能够自动转移到slave node上
前两种架构方式最大的特定是,每个节点的数据是相同的,无法存取海量的数据,因此,哨兵集群的方式使用与数据量不大的情况
redis cluster
redis cluster支撑多master node,每个master node可以挂载多个slave node,如果master挂掉,会自动将对应的某个slave切换成master,需要注意的是redis cluster下slave节点主要是用来做高可用,故障主备切换的,如果一定需要slave能够提供读的能力,修改配置也可以实现(同时也需要修改jedis源码来支持该情况下的读写分离操作),slave节点能够自动迁移(让master节点尽量平均拥有slave节点)对整个架构过载冗余的slave就可以保障系统更高的可用性
Tomcat jvm堆内存缓存,主要是抗redis出现大规模灾难,如果redis出现了大规模的宕机,导致nginx大量流量直接永祥数据生产服务器,那么最后tomcat堆内存缓存也可以处理部分请求,避免所有请求都直接流向数据库;
【缓存数据更新策略】
对时效性要求高的缓存数据,但发生变更的时候,直接采取数据库和redis缓存双写方案,提高缓存时效性
对时效性不高的数据,当发生变更之后,采用MQ异步通知的方式,通过数据生产服务来监听MQ消息,然后异步去拉去服务的数据更新tomcat jvm和redis缓存,对于nginx本地缓存过之后就可以从redis中拉去新的数据并更新到nginx本地
【数据库和redis缓存双写不一致的问题】
将数据库与缓存更新的读写操作进行异步串行化,当跟新数据的时候,根据数据的唯一标识,将更新数据操作路由到一个jvm内部队列中,一个队列对应一个工作线程,线程串行随后在队列里一条一条的执行,当执行队列中的更新数据操作,删除缓存,然后去更新数据库,此时还没有完成更新的时候过来一个读请求,读到了空缓存,那么可以先将缓存更新之后的请求发送到路由之后的队列中,此时会在队列积压,然后同步等待缓存更新完成,
【缓存雪崩解决方案】
redis集群彻底奔溃,缓存服务大量对redis的请求等待,占用资源,随后缓存服务大量的请求进入源头服务去查询DB,使得DB压力过大直至崩溃,此时对源头的请求 也大量等待占用资源,缓存服务大量的资源全部消耗在访问redis和原服务无果,最后使得自身也无法提供服务,最终整个网站崩溃;
事前解决方案:搭建一套高可用架构redis cluster集群,主从架构,一主多从,并且最好使用双机房部署集群
事中解决方案:部署一层ehcache缓存,在整个redis集群中能够扛得住部分压力,对redis cluster的访问做资源隔离,避免所有资源都请求等待,对redis cluster的访问失败这种情况应该实施熔断策略,对源服务访问进行限流以及资源隔离
事后解决方案:redis数据做了备份可以直接恢复,重启redis即可,redis数据彻底丢失或者数据过旧,可以快速缓存预热,然后让redis重新启动,最后由于资源隔离的half-open策略发现redis恢复正常,那么所有的请求将自动恢复
【Nginx缓存失效导致redis压力倍增】
这个时候我们可以在nginx本地设置缓存数据的时候设置缓存有效期,避免同一时间缓存都失效导致大量的请求直接进入redis
Nginx+Redis+Ehcache大型高并发高可用三层架构总结的更多相关文章
- Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构
Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...
- 高并发&高可用系统的常见应对策略 秒杀等-(阿里)
对于一个需要处理高并发的系统而言,可以从多个层面去解决这个问题. 1.数据库系统:数据库系统可以采取集群策略以保证某台数据库服务器的宕机不会影响整个系统,并且通过负载均衡策略来降低每一台数据库服务器的 ...
- Java生鲜电商平台-高并发的设计与架构
Java生鲜电商平台-高并发的设计与架构 说明:源码下载Java开源生鲜电商平台以及高并发的设计与架构文档 对于高并发的场景来说,比如电商类,o2o,门户,等等互联网类的项目,缓存技术是Java项目中 ...
- 高并发高可、O2O、微服务架构用学习网站
高并发高可.O2O.微服务架构用学习网站 https://www.itkc8.com 非常感谢http://www.cnblogs.com/skyblog/p/5044486.html 关于架构,笔者 ...
- java处理高并发高负载类网站的优化方法
java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据) 一:高并发高负载类网站关注点之数据库 没错,首先是数据库,这是大多数应用所面临的首个SPOF ...
- [转]java处理高并发高负载类网站的优化方法
本文转自:http://www.cnblogs.com/pengyongjun/p/3406210.html java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,ja ...
- PHP高并发高负载系统架构
PHP高并发高负载系统架构 1.为什么要进行高并发和高负载的研究 1.1.产品发展的需要 1.2.公司发展的需要 1.3.当前形式决定的 2.高并发和高负载的约束条件 2.1.硬件 2.2.部署 2. ...
- 高并发&高可用系统的常见应对策略
解耦神器:MQ MQ是分布式架构中的解耦神器,应用非常普遍.有些分布式事务也是利用MQ来做的.由于其高吞吐量,在一些业务比较复杂的情况,可以先做基本的数据验证,然后将数据放入MQ,由消费者异步去处理后 ...
- 构建高并发&高可用&安全的IT系统-高并发部分
什么是高并发? 狭义来讲就是你的网站/软件同一时间能承受的用户数量有多少 相关指标有 并发数:对网站/软件同时发起的请求数,一般也可代表实际的用户 每秒响应时间:常指一次请求到系统正确响的时间(以秒为 ...
随机推荐
- Vue 根组件,局部,全局组件 | 组件间通信,案例组件化
一 组件 <div id="app"> <h1>{{ msg }}</h1> </div> <script src=" ...
- Mysql 通过frm&ibd 恢复数据
mysql存储在磁盘中,各种天灾人祸都会导致数据丢失.大公司的时候我们常常需要做好数据冷热备,对于小公司来说要做好所有数据备份需要支出大量的成本,很多公司也是不现实的.万一还没有做好备份,数据被误删除 ...
- linux服务器上配置多个svn仓库
linux服务器上配置多个svn仓库 1.在指定目录建立仓库保存总目录,本文示例目录设定为:/usr/local/svn/svnrepos # mkdir -p /usr/local/svn/svnr ...
- 解决:Gitlab的developer角色的人没有push权限无法提交(转)
问题 几位同事合作搞一些东西,打算在Gitlab上建一个仓库,然后协同开发.建好仓库后,将其他几位同事添加进来,角色分配为Developer. 之后提交初始代码到master分支后,他们用source ...
- 【原创】Linux基础之gz文件相关操作
gz文件不需要解压即可进行相关操作 $ zcat test.log.gz $ zmore test.log.gz $ zless test.log.gz $ zgrep '1.2.3.4' test. ...
- 小白6步搞定vue脚手架创建项目
1.安装node及npm node -v (测试node是否安装成功)npm -v(测试npm是否安装成功) 2.安装cnpm npm install -g cnpm --registry=http: ...
- android端 socket长连接 架构
看过包建强的<App研发录>之后对其中的基础Activity类封装感到惊讶,一直想找一种方式去解决关于app中使用socket长连接问题,如何实现简易的封装来达到主活动中涉及socket相 ...
- 洛谷P5219 无聊的水题 I [prufer序列,生成函数,NTT]
传送门 思路 有标号无根树的计数,还和度数有关,显然可以想到prufer序列. 问题就等价于求长度为\(n-2\),值域为\([1,n]\),出现次数最多的恰好出现\(m-1\)次,这样的序列有哪些. ...
- 堆(Heap)详解——Java实现
Heap 堆定义:(这里只讲二叉堆)堆实为二叉树的一种,分为最小堆和最大堆,具有以下性质: 任意节点小于/大于它的所有后裔,最小/大元在堆的根上. 堆总是一棵完全二叉树 将根节点最大的堆叫做最大堆或大 ...
- VBS将本地的Excel数据导入到SQL Server中
VBS将本地的Excel数据导入到SQL Server中 高文龙关注0人评论1170人阅读2017-05-14 12:54:44 VBS将本地的Excel数据导入到SQL Server中 最近有个测试 ...