高并发系统实战课---笔记(持续更新中)

高并发常见场景:

  1. 读多写少
    eg 用户中心
    职能梳理
    缓存同步
    鉴权令牌
    机房同步
    Raft共识

  2. 强一致性
    eg 电商系统
    领域拆分
    性能与锁
    隔离与同步
    分布式事务

  3. 写多读少
    eg 链路跟踪系统
    分布式链路跟踪
    OLAP/OLTP
    ELK与链路跟踪
    ClickHouse

  4. 读多写多
    eg 游戏 直播类系统
    业务做缓存
    脚本引擎
    流量分流架构
    DNS与调度

经典架构则是:统一缓存 元数据 日志中心 WAF 压测验证


读多写少的高并发优化实践-用户中心

梳理数据表 ========================

特定场景精简字段 例如 用户账号表 只保留 账户密码和状态
数据主要分为四种:实体对象主表、辅助查询表、实体关系和历史数据

优化实体对象表

精简数据总长度;
减少表承担的业务职能;
减少统计计算查询;
实体数据更适合放在缓存当中;
尽量让实体能够通过 ID 或关系方式查找;
减少实时条件筛选方式的对外服务。

优化辅助查询表

定期核对整理数据,保证冗余数据的同步和完整

行业里也会用一些开源搜索引擎,辅助我们做类似的关系业务查询,比如用 ElasticSearch 做商品检索、用 OpenSearch 做文章检索等。这种可横向扩容的服务能大大降低数据库查询压力,但唯一缺点就是很难实现数据的强一致性,需要人工检测、核对两个系统的数据。

优化实体关系表

在关系类型数据中,建议额外用一个关系表来记录实体间 m:n 的关联关系

优化动作历史表

对于这种基于大量的数据统计后才能得到的结论数据,不建议对外提供实时统计计算服务,这种查询会严重拖慢我们的数据库,影响服务稳定。即使使用缓存临时保存统计结果,这也属于临时方案,建议用其他更具体的表去做类似的事情。

到底什么样的数据适合做缓存?

1)能够通过 ID 快速匹配的实体,以及通过关系快速查询的数据,适合放在长期缓存当中;
2)通过组合条件筛选统计的数据,也可以放到临时缓存,但是更新有延迟;
3)数据增长量大或者跟设计初衷不一样的表数据,这种不适合、也不建议去做做缓存。

缓存一致======================

做缓存是要考虑性价比(数据量、使用频率、缓存命中率三个角度去分析),一般来说,只有热点数据放到缓存才更有价值。

采用临时缓存

将数据临时放到缓存,等待 60 秒过期后数据就会被淘汰,如果有同样的数据查询需要,我们的代码会将数据重新填入缓存继续使用。这种临时缓存适合表中数据量大,但热数据少的情况,可以降低热点数据的压力。

解决缓存如果出现更新不及时的问题:
- 单条实体数据缓存刷新
- 关系型和统计型数据缓存刷新

1)首先考虑人工维护,更新较慢,存在延迟;
2)再者就是考虑通过订阅数据库来找到 ID 数据变化。如使用 Canal对 MySQL 的更新进行监控。这样变更信息会推送到 Kafka 内,我们可以根据对应的表和具体的 SQL 确认更新涉及的数据 ID,然后根据脚本内设定好的逻辑对相 关 key 进行更新。这种方式的好处是能及时更新简单的缓存,同时核心系统会给子系统广播同步数据更改,代码也不复杂;缺点是复杂的关联关系刷新,仍旧需要通过人工写逻辑来实现。

"Canal"指的是阿里巴巴开源的一个基于数据库增量日志解析,提供增量数据订阅&消费的中间件,它能够实现实时的数据同步和服务间的数据变更通知。

3)如果我们表内的数据更新很少,那么可以采用版本号缓存设计。
但一旦有任何更新,整个表内所有数据缓存一起过期。
当业务要读取某个信息的时候,业务会同时获取当前表的 version。如果发现缓存数据内的版本和当前表的版本不一致,那么就会更新这条数据。但如果 version 更新很频繁,就会严重降低缓存命中率,所以这种方案适合更新很少的表。

4)此外,关联型数据更新还可以通过识别主要实体 ID 来刷新缓存。这要保证其他缓存保存的 key 也是主要实体 ID,这样当某一条关联数据发生变化时,就可以根据主要实体 ID 对所有缓存进行刷新。这个方式的缺点是,我们的缓存要能够根据修改的数据反向找到它关联的主体 ID 才行。

5)最后,异步脚本遍历数据库刷新所有相关缓存。这个方式适用于两个系统之间同步数据,能够减少系统间的接口交互;缺点是删除数据后,还需要人工删除对应的缓存,所以更新会有延迟。但如果能配合订阅更新消息广播的话,可以做到准同步。

如果当 TTL 到期时,如果大量缓存请求没有命中,透传的流量会不会打沉我们的数据库?

这其实就是常提到的缓存穿透问题,如果缓存出现大规模并发穿透,那么很有可能导致我们服务宕机。
所以,数据库要是扛不住平时的流量,我们就不能使用临时缓存的方式去设计缓存系统,只能用长期缓存这种方式来实现热点缓存,以此避免缓存穿透打沉数据库的问题。


一般情况下,是长期缓存和临时缓存的混用。当我们要查询某个用户信息时,如果缓存中没有数据,长期缓存会直接返回没有找到,临时缓存则直接走更新流程。此外,我们的用户信息如果属于热点 key,并且在缓存中找不到的话,就直接返回数据不存在。

布隆过滤器(Bloom Filter)是一种空间效率非常高的概率型数据结构,用于判断一个元素是否在一个集合中。它能够以很低的内存消耗来快速测试一个元素是否“可能在”或“绝对不在”集合中。如果说key超过上千个,可以使用布隆过滤器判断。

在更新期间,为了防止高并发查询打沉数据库,我们将更新流程做了简单的 singleflight(请求合并)优化,只有先抢到缓存更新锁的线程,才能进入后端读取数据库并将结果填写到缓存中。而没有抢到更新锁的线程先 sleep 1 秒,然后直接读取缓存返回结果。这样可以保证后端不会有多个线程读取同一条数据,从而冲垮缓存和数据库服务(缓存的写并发没有读性能那么好)。

另外,hot_key 列表(也就是长期缓存的热点 key 列表)会在多个 Redis 中复制保存,如果要读取它,随机找一个分片就可以拿到全量配置。这些热缓存 key,来自于统计一段时间内数据访问流量,计算得出的热点数据。

那长期缓存的更新会异步脚本去定期扫描热缓存列表,通过这个方式来主动推送缓存,同时把 TTL 设置成更长的时间,来保证新的热数据缓存不会过期。当这个 key 的热度过去后,热缓存 key 就会从当前 set 中移除,腾出空间给其他地方使用。

当然,如果我们拥有一个很大的缓存集群,并且我们的数据都属于热数据,那么我们大可以脱离数据库,将数据都放到缓存当中直接对外服务,这样我们将获得更好的吞吐和并发。

最后,还有一种方式来缓解热点高并发查询,在每个业务服务器上部署一个小容量的 Redis 来保存热点缓存数据,通过脚本将热点数据同步到每个服务器的小 Redis 上,每次查询数据之前都会在本地小 Redis 查找一下,如果找不到再去大缓存内查询,通过这个方式缓解缓存的读取性能。

ps:缓存刷新方式

主键ID刷新
监控binlog刷新
条件划定刷新范围
版本号过期刷新
TTL过期刷新
异步脚本扫表刷新

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

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

相关文章

Docker+Jenkins自动化部署SpringBoot项目【详解git,jdk,maven,ssh配置等各种配置,附有示例+代码】

文章目录 DockerJenkins部署SpringBoot项目一.准备工作1.1安装jdk111.2安装Maven 二.Docker安装Jenkins2.1安装Docker2.2 安装Jenkins2.3进入jenkins 三.Jenkins设置3.1安装jenkins插件3.2全局工具配置全局配置jdk全局配置maven全局配置git 3.3 系统配置安装 Publish Over SSH …

知识图谱数据库 Neo4j in Docker笔记

下载 docker pull neo4j:community官方说明 https://neo4j.com/docs/operations-manual/2025.01/docker/introduction/ 启动 docker run \--restart always \--publish7474:7474 --publish7687:7687 \--env NEO4J_AUTHneo4j/your_password \--volumeD:\files\knowledgegrap…

前缀和算法篇:解决子数组累加和问题

1.前缀和原理 那么在介绍前缀和的原理之前,那么我们先来说下前缀和最基本的一个应用场景,那么就是如我们标题所说的子数组累加和问题,那么假设我们现在有一个区间为[L,R]的数组,那么我们要求的其中子数组比如[L,i]或者[i,m] (L&l…

Notepad++ 中删除所有以 “pdf“ 结尾的行

Notepad 中删除所有以 “pdf” 结尾的行 操作步骤 1.打开文件: 在 Notepad 中打开你需要处理的文本文件。 2.打开查找和替换对话框: 按快捷键 Ctrl F,打开“查找和替换”对话框。 3.启用正则表达式模式: 在对话框的底部&#xf…

知识管理成功:关键指标和策略,研究信息的投资回报率

信息过载会影响生产力。没有人工智能的帮助,信息过载会影响生产力。大量的可用信息,知识工作者不仅仅是超负荷工作;他们感到不知所措,他们倾向于浪费时间(和脑细胞)来应付他们被大量的数据抛向他们&#xf…

Golang 进阶训练营

一、Golang 的 slice、map、channel 1.1 slice vs array a : make([]int, 100) //切片 b : [100]int{} //数组array需指明长度,长度为常量且不可改变 array长度为其类型中的组成部分(给参数为长度100的数组的方法传长度为101的会报错) array在…

Oracle临时表空间(基础操作)

临时表空间 临时表空间:用来存放用户的临时数据,临时数据在需要时被覆盖,关闭数据库后自动删除,其中不能存放永久性数据。 用户进程和服务器进程是一对一的叫做专用连接。 任何一个用户连到oracle数据库,oracle都会…

AI时代的前端开发:对抗压力的利器

在飞速发展的AI时代,前端开发工程师们面临着前所未有的挑战。项目周期不断缩短,需求变化日新月异,交付压力更是与日俱增,这使得开发人员承受着巨大的压力。如何提升对抗压能力,成为摆在每一位前端工程师面前的重要课题…

如何使用DHTMLX Scheduler的拖放功能,在 JS 日程安排日历中创建一组相同的事件

DHTMLX Scheduler 是一个全面的调度解决方案,涵盖了与规划事件相关的广泛需求。假设您在我们的 Scheduler 文档中找不到任何功能,并且希望在我们的 Scheduler 文档中看到您的项目。在这种情况下,很可能可以使用自定义解决方案来实现此类功能。…

计算机网络-八股-学习摘要

一:HTTP的基本概念 全称: 超文本传输协议 从三个方面介绍HTTP协议 1,超文本:我们先来理解「文本」,在互联网早期的时候只是简单的字符文字,但现在「文本」的涵义已经可以扩展为图片、视频、压缩包等&am…

【pytorch】weight_norm和spectral_norm

apply_parametrization_norm 和spectral_norm是 PyTorch 中用于对模型参数进行规范化的方法,但它们在实现和使用上有显著的区别。以下是它们的主要区别和对比: 实现方式 weight_norm: weight_norm 是一种参数重参数化技术,将权…

回归预测 | Matlab实现PSO-HKELM粒子群算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现PSO-HKELM粒子群算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现PSO-HKELM粒子群算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.回归预测 | Matlab实现PSO-HKELM粒子群算法优化混合核…

多媒体软件安全与授权新范例,用 CodeMeter 实现安全、高效的软件许可管理

背景概述 Reason Studios 成立于 1994 年,总部位于瑞典斯德哥尔摩,是全球领先的音乐制作软件开发商。凭借创新的软件产品和行业标准技术,如 ReWire 和 REX 文件格式,Reason Studios 为全球专业音乐人和业余爱好者提供了一系列高质…

C++,STL容器适配器,stack:栈深入解析

文章目录 一、容器概览与核心特性核心特性速览二、底层实现原理1. 容器适配器设计2. 默认容器对比三、核心操作详解1. 容器初始化2. 元素操作接口3. 自定义栈实现四、实战应用场景1. 括号匹配校验2. 浏览器历史记录管理五、性能优化策略1. 底层容器选择基准2. 内存预分配技巧六…

互联网大厂中面试的高频计算机网络问题及详解

前言 哈喽各位小伙伴们,本期小梁给大家带来了互联网大厂中计算机网络部分的高频面试题,本文会以通俗易懂的语言以及图解形式描述,希望能给大家的面试带来一点帮助,祝大家offer拿到手软!!! 话不多说,我们立刻进入本期正题! 一、计算机网络基础部分 1 …

「软件设计模式」工厂方法模式 vs 抽象工厂模式

前言 在软件工程领域,设计模式是解决常见问题的经典方案。本文将深入探讨两种创建型模式:工厂方法模式和抽象工厂模式,通过理论解析与实战代码示例,帮助开发者掌握这两种模式的精髓。 一、工厂方法模式(Factory Metho…

Docker部署Alist网盘聚合管理工具完整教程

Docker部署Alist网盘聚合管理工具完整教程 部署alist初始化修改密码添加存储!联通网盘阿里云盘百度网盘 部署alist 本文以Linux Docker部署,假设你已经安装好Docker docker run -d --restartalways \-v /your/data:/opt/alist/data \-p 5244:5244 \-e …

Excel常用操作

Excel常用操作 学习资源 37_电子表格处理考点精讲_设置数据格式_哔哩哔哩_bilibili 快速输入数据与编辑数据 一个工作簿可以包含多个工作表 特殊数据的添加格式 输入负数, 例如-3、-5 常规输入, 直接输入-3、-5;使用(), 例如在单元格中输入(3)回车即可变为-3;上述括号不区分中…

SpringMVC环境搭建

文章目录 1.模块创建1.创建一个webapp的maven项目2.目录结构 2.代码1.HomeController.java2.home.jsp3.applicationContext.xml Spring配置文件4.spring-mvc.xml SpringMVC配置文件5.web.xml 配置中央控制器以及Spring和SpringMVC配置文件的路径6.index.jsp 3.配置Tomcat1.配置…

常见的排序算法:插入排序、选择排序、冒泡排序、快速排序

1、插入排序 步骤: 1.从第一个元素开始,该元素可以认为已经被排序 2.取下一个元素tem,从已排序的元素序列从后往前扫描 3.如果该元素大于tem,则将该元素移到下一位 4.重复步骤3,直到找到已排序元素中小于等于tem的元素…