Java生鲜电商平台-缓存架构实战

 

Java生鲜电商平台-缓存架构实战

 

说明:在Java生鲜电商中,缓存起到了非常重要的作用,目前整个项目中才用的是redis做分布式缓存.

缓存集群

缓存集群存在的问题

1.热key
缓存集群中的某个key瞬间被数万甚至十万的并发请求打爆。


2.大value
某个key对应的value可能有GB级的大小,导致查询value的时候导致网络相关的故障问题。

缓存集群作用

在缓存里放一些平时不怎么变动的数据,然后用户在查询大量的平时不怎么变动的数据的时候,可以直接从缓存里走了。缓存集群的并发能力是很强的,而且读缓存的性能是很高的。

缓存实践案例

  • 假设系统每秒有2万请求,但是其中90%都是读请求,假如每秒1.8万请求都是在读一些不太变化的数据。那此时你把这些数据都放在数据库里,然后每秒发送2万请求到数据库上读写数据,感受一下这样合适?
  • 如果要用数据库承载每秒2万请求的话,那很可能就得搞分库分表 + 读写分离。
  • 那得分3个主库,承载每秒2000的写入请求,然后每个主库挂3个从库,一共9个从库承载每秒1.8万的读请求。
  • 这样的话,就需要一共是12台高配置的数据库服务器,这是很耗费钱的,成本非常高,很不合适。
  • 因此,可以把平时不太变化的数据放在缓存集群里,缓存集群可以采用2主2从,主节点用来写入缓存,从节点用来读缓存。
  • 以缓存集群的性能,2个从节点完全可以用来承载每秒1.8万的大量读请求,然后3个数据库主库就是承载每秒2000的写请求和少量其他读请求就OK了(数据一致性问题)。
  • 这样一来,耗费的机器瞬间变成了4台缓存机器 + 3台数据库机器 = 7台机器,是不是比之前的12台机器减少了很大的资源开销?
  • 缓存其实在系统架构里是非常重要的组成部分。很多时候,对于那些很少变化但是大量高并发读的数据,通过缓存集群来抗高并发读,是非常合适的。

热点缓存

  • 所谓热点缓存问题就是突然因为莫名的原因,出现大量的用户访问同一条缓存数据。碰巧这些key都存在于一台缓存机器上。
  • 假设每秒突然奔过来20万请求到这台机器上,那台被20万请求指向的缓存机器就会过度操劳而宕机的。
  • 读请求发现读不到数据,会从数据库里提取原始数据,然后放入剩余的其他缓存机器里去。但是接踵而来的每秒20万请求,会再次压垮其他的缓存机器。
  • 以此类推,最终导致缓存集群全盘崩溃,引发系统整体宕机。

基于流式计算技术的缓存热点自动发现

  • 其实这里关键的一点,就是对于这种热点缓存,你的系统需要能够在热点缓存突然发生的时候,直接发现他,然后瞬间立马实现毫秒级的自动负载均衡。
  • 一般出现缓存热点的时候,每秒并发肯定是很高的,可能每秒都几十万甚至上百万的请求量过来,这都是有可能的。
  • 所以,此时完全可以基于大数据领域的流式计算技术来进行实时数据访问次数的统计,比如storm、spark streaming、flink。
  • 一旦在实时数据访问次数统计的过程中,比如发现一秒之内,某条数据突然访问次数超过了1000,就直接立马把这条数据判定为是热点数据,可以将这个发现出来的热点数据写入比如zookeeper中(监听事件)。
  • 流式计算系统在进行数据访问次数统计的时候,会不会也存在说单台机器被请求每秒几十万次的问题呢?否!!!
  • 流式计算技术,尤其是storm这种系统,他可以做到同一条数据的请求过来,先分散在很多机器里进行本地计算,最后再汇总局部计算结果到一台机器进行全局汇总。
  • 所以几十万请求可以先分散在比如100台机器上,每台机器统计了这条数据的几千次请求。
  • 然后100条局部计算好的结果汇总到一台机器做全局计算即可,所以基于流式计算技术来进行统计是不会有热点问题的。

热点缓存自动加载为JVM本地缓存

  • 我们自己的系统可以对zookeeper指定的热点缓存对应的znode进行监听,如果有变化立马就可以感知到了。
  • 此时系统层就可以立马把相关的缓存数据从数据库加载出来,然后直接放在自己系统内部的本地缓存里即可。
  • 这个本地缓存,用ehcache、hashmap,其实都可以,一切看自己的业务需求。我们这里主要说的就是将缓存集群里的集中式缓存,直接变成每个系统自己本地实现缓存即可,每个系统本地是无法缓存过多数据的。
  • 因为一般这种普通系统单实例部署机器可能就一个4核8G的机器,留给本地缓存的空间是很少的,所以用来放这种热点数据的本地缓存是最合适的,刚刚好。
  • 假设系统层集群部署了100台机器,此时你100台机器瞬间在本地都会有一份热点缓存的副本。
  • 然后接下来对热点缓存的读操作,直接系统本地缓存读出来就给返回了,不用再走缓存集群了。
  • 这样的话,变成100台机器每台机器承载数千请求,那么那数千请求就直接从机器本地缓存返回数据了,这是没有问题的。

限流熔断保护

  • 在每个系统内部,还应该专门加一个对热点数据访问的限流熔断保护措施。
  • 每个系统实例内部,都可以加一个熔断保护机制,假设缓存集群最多每秒承载4万读请求,那么你一共有100个系统实例。
  • 应该提前限制好,每个系统实例每秒最多请求缓存集群读操作不超过400次,一超过就可以熔断掉,不让请求缓存集群,直接返回一个空白信息,然后用户稍后会自行再次重新刷新页面之类的。
  • 通过系统层自己直接加限流熔断保护措施,可以很好的保护后面的缓存集群、数据库集群之类的不要被打死。


转载于:https://www.cnblogs.com/jurendage/p/11269241.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247326.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java生鲜电商平台-深入理解微服务SpringCloud各个组件的关联与架构

Java生鲜电商平台-深入理解微服务SpringCloud各个组件的关联与架构 概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术。不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理&#xf…

Angular自学笔记(?)DI提供者

类提供者 类提供者的创建和使用 假设有logger类: import {Injectable } from @angular/core;@Injectable() export class LoggerService {logs: string[] = [

Angular自学笔记(?)生命周期

从实例化组件,渲染组件模板时,各声明周期就已开始 ngOnChanges 输入属性发生变化是触发,但组件内部改变输入属性是不会触发的 import {Component, Input, OnInit, OnChanges } from @angular/core;@Component({selector: app-life-cycle,templateUrl:

[转载]httpClient.execute抛Connection to refused异常问题

在4.0之后android采用了严格模式:所以在你得activity创建的时候,在super.onCreate(savedInstanceState);后面加上这个 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites(…

Angular自学笔记(?)依赖注入

什么是依赖注入 依赖注入(DI)是一种设计模式, 也有相应的框架,比如InversifyJS Angular 有自己的 DI 框架, DI 框架会在实例化该类时向其提供这个类所声明的依赖项 带修饰符的参数 在ts中,一个类的参数如果带上修饰符,那个参数就变成了类的实例属性 class Mobile {co…

MSN8.0经常出现连接错误,如何解决?

连接错误有很多种情形,请您先查看下连接错误代码 然后可以尝试以下解决办法--------- 如何解决错误 81000301 或 81000306 您登录 MSN Messenger 时,可能会收到以下错误消息: 我们无法让您登录到 MSN Messenger,可能是因为服务或 …

@ViewChild 的三种常用方法

//--1------ 在angular中进行dom操作 <div #dom>这是一个div</div> //放置一个锚点domimport { ElementRef, ViewChild } from angular/core;ViewChild(dom,{static:true}), eleRef:ElementRef; //static-True表示在运行更改检测之前解析查询结果&#xff0c;false…

SQL Server安装文件挂起错误解决办法

以前在安装sql的时候&#xff0c;如此提示&#xff0c;我只要重新启动即可&#xff0c;可是今天重新启动了N次计算机&#xff0c;问题却丝毫没有解决&#xff0c;依然提示这样的话。“以前的某个程序安装已在安装计算机上创建挂起的文件操作。运行安装程序之前必须重新启动计算…

angular 内容投影

app HTML <div class"wrapper"><h2>我是父组件</h2><div>这个div定义在父组件中</div><app-child><div class"header">这个div是父组件投影到子组件的1, {{title}}</div><div class"footer"…

移动端日历插件

//datePicker日期控件 v1.0//var calendar new datePicker();//calendar.init({// trigger: #demo1, /*选择器&#xff0c;触发弹出插件*/// type: date,/*date 调出日期选择 datetime 调出日期时间选择 time 调出时间选择 ym 调出年月选择*/// minDate:1900-1-1,/*最小日期*/…

js 操作location URL对象进行操作

把location 创建URL对象 构造器 new URL() 创建并返回一个URL对象&#xff0c;该URL对象引用使用绝对URL字符串&#xff0c;相对URL字符串和基本URL字符串指定的URL。 属性 hash 包含#的USVString&#xff0c;后跟URL的片段标识符。 host 一个USVString&#xff0c;其中…

aspx,ascx和ashx使用小结

做asp.net开发的对.aspx,.ascx和.ashx都不会陌生。关于它们&#xff0c;网上有很多文章介绍。“纸上得来终觉浅&#xff0c;绝知此事要躬行”&#xff0c;下面自己总结一下做个笔记。 1、.aspx Web窗体设计页面。Web窗体页由两部分组成&#xff1a;视觉元素&#xff08;html、服…

vue3.x通过ref属性获取元素

在vue2.x中&#xff0c;可以通过给元素添加refxxx属性&#xff0c;然后在代码中通过this.$refs.xxx获取到对应的元素 然而在vue3中时没有$refs这个东西的&#xff0c;因此vue3中通过ref属性获取元素就不能按照vue2的方式来获取vue3需要借助生命周期方法&#xff0c;原因很简单…

vue3+TypeScript封装echarts5组件

https://blog.csdn.net/qq_38330707/article/details/111497853 有用mark 等抽时间写个vueTSecharts5.0的组件文章 写个大概 带 resize的 <template><div class"echarts" :id"id"></div> </template><script lang"ts&q…

How to Register COM in VS

在 Visual Studio .Net 部署项目中注册 COM 模块的步骤 将 COM 对象添加到 Visual Studio 部署项目。在解决方案资源管理器中&#xff0c;右键单击刚添加的模块&#xff0c;然后单击属性。注意&#xff1a;“属性”窗口包含一个表&#xff0c;其中有两列和 x 行&#xff08;行数…

css3 卡片hover3D效果

鼠标hover卡片 向上翻转&#xff0c;看简易代码 <!DOCTYPE html> <html> <head><title>3D Flip Card hover effects</title><style type"text/css">* {margin: 0;padding: 0;font-family: consolas;box-sizing: border-box;}bo…

随便贴两个漏洞,如 Apache JServ协议服务

1、Apache JServ协议服务 描述&#xff1a;Apache JServ协议&#xff08;AJP&#xff09;是一种二进制协议&#xff0c;可以将来自Web服务器的入站请求代理到 位于Web服务器后面的应用程序服务器。不建议在互联网上公开使用AJP服务。 如果AJP配置错误&#xff0c;可能会允许攻击…

vue3学习笔记 Composition API setup

一、Composition API优势 相对于vue2的option API Vue3的Composition API设计更有优势 Composition(组合式)Api 功能分组 Composition(组合式)Api 功能导入复用 组合式Api 所解决的问题 (1) 更好的代码组织结构 (2) 相同的代码逻辑可以进行复用 home.vue 3种方式递进升级…

【TCP传输数据-键盘录入】

package com.yjf.esupplier.common.test;import java.io.*; import java.net.Socket;/*** author shusheng* description TCP 传输数据:键盘录入* Email shushengyiji.com* date 2019/1/15 22:57*/ public class ClientDemo1 {public static void main(String[] args) throws I…

04

1、创建/guanli 目录&#xff0c;在/guanli下创建zonghe 和 jishu 两个目录&#xff08;一条命令&#xff09; [rootlocalhost ~]# mkdir /guanli [rootlocalhost ~]# touch /guanli/zonghe [rootlocalhost ~]# touch /guanli/jishu [rootlocalhost ~]# ls /guanlix 2、添加组帐…