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系统-高并发部分
什么是高并发? 狭义来讲就是你的网站/软件同一时间能承受的用户数量有多少 相关指标有 并发数:对网站/软件同时发起的请求数,一般也可代表实际的用户 每秒响应时间:常指一次请求到系统正确响的时间(以秒为 ...
随机推荐
- $Django 在线文本编辑器skindeditor
简介 KindEditor是一套开源的在线HTML编辑器,主要用于让用户在网站上获得所见即所得编辑效果,开发人员可以用 KindEditor 把传统的多行文本输入框(textarea)替换为可视化的富 ...
- ansible笔记(2):清单配置详解
上一篇文章介绍了ansible的基本概念,以及相关的基础配置,我们已经知道,如果想要管理受管主机,则需要将受管主机添加到ansible的管理清单中,当安装ansible以后,会提供一个默认的管理清单, ...
- 添加struts2本地dtd限制
将源码保重的struts-2.1.7.dtd文件拷贝到dtds文件夹中 打开eclipse配置文件window/preferences,搜索xml找到XML Catalog
- 查看当前APP打开的是哪个Activity
按下 “window键+R键” 打开电脑的 “运行” 窗口,输入“cmd”,进入你的adb.exe所在的目录,输入 “ adb shell "dumpsys window | grep mC ...
- Spring Boot (一): Spring Boot starter自定义
前些日子在公司接触了spring boot和spring cloud,有感于其大大简化了spring的配置过程,十分方便使用者快速构建项目,而且拥有丰富的starter供开发者使用.但是由于其自动化配 ...
- sysstat-----获取服务器负载历史记录
sysstat工具与负载历史回放 很多系统负载过高的时候我们是无法立即获知或者立即解决的,当检测到或者知道历史的高负载状况时,可能需要回放历史监控数据,这时 sar 命令就派上用场了,sar命令同样来 ...
- Vue1.0到2.0变化
一.生命周期 二.代码片段 在vue1.0中可以在template编写时出现: <template> <div>第一行</div> <div>第二行&l ...
- 手把手教你React Native 实战之开山篇《一》
先说一下我为什么学习RN 18年3月29号,随着自己内心的欲望和冲动,任务交接了一下,正式离开一家医疗公司.第二天就入职了这之前已经找好的公司,由于自己对代码浓厚的热情,自己终于也不再带团队.正好有充 ...
- HTML中特殊符号的处理
一.写在前面 今天在写页面时记不清大/小于符号该怎么写,于是就想着整理一下方便后面用到! 二.HTML中常用特殊符号的处理 < < 小于号或显示标记 > ...
- vue.js----之router详解(一)
在vue1.0版本的超链接标签还是原来的a标签,链接地址由v-link属性控制 而vue2.0版本里超链接标签由a标签被替换成了router-link标签,但最终在页面还是会被渲染成a标签的 至于为什 ...