腾讯后台服务架构高性能设计之道(3)

简介: 腾讯后台服务架构高性能设计之道

9 存储

任何一个系统,从单核 CPU 到分布式,从前端到后台,要实现各式各样的功能和逻辑,只有读和写两种操作。而每个系统的业务特性可能都不一样,有的侧重读、有的侧重写,有的两者兼备,本节主要探讨在不同业务场景下存储读写的一些方法论。

9.1 读写分离

大多数业务都是读多写少,为了提高系统处理能力,可以采用读写分离的方式将主节点用于写,从节点用于读,如下图所示。

读写分离架构

读写分离架构有以下几个特点:1)数据库服务为主从架构,可以为一主一从或者一主多从;2)主节点负责写操作,从节点负责读操作;3)主节点将数据复制到从节点;基于基本架构,可以变种出多种读写分离的架构,如主-主-从、主-从-从。主从节点也可以是不同的存储,如 mysql+redis。

读写分离的主从架构一般采用异步复制,会存在数据复制延迟的问题,适用于对数据一致性要求不高的业务。可采用以下几个方式尽量避免复制滞后带来的问题。

1)写后读一致性:即读自己的写,适用于用户写操作后要求实时看到更新。典型的场景是,用户注册账号或者修改账户密码后,紧接着登录,此时如果读请求发送到从节点,由于数据可能还没同步完成,用户登录失败,这是不可接受的。针对这种情况,可以将自己的读请求发送到主节点上,查看其他用户信息的请求依然发送到从节点。

2)二次读取:优先读取从节点,如果读取失败或者跟踪的更新时间小于某个阀值,则再从主节点读取。

3)关键业务读写主节点,非关键业务读写分离。

4)单调读:保证用户的读请求都发到同一个从节点,避免出现回滚的现象。如用户在 M 主节点更新信息后,数据很快同步到了从节点 S1,用户查询时请求发往 S1,看到了更新的信息。接着用户再一次查询,此时请求发到数据同步没有完成的从节点 S2,用户看到的现象是刚才的更新的信息又消失了,即以为数据回滚了。

9.2 动静分离

动静分离将经常更新的数据和更新频率低的数据进行分离。最常见于 CDN,一个网页通常分为静态资源(图片/js/css 等)和动态资源(JSP、PHP 等),采取动静分离的方式将静态资源缓存在 CDN 边缘节点上,只需请求动态资源即可,减少网络传输和服务负载。

在数据库和 KV 存储上也可以采取动态分离的方式,如 7.6 提到的点播视频缓存的动静分离。在数据库中,动静分离更像是一种垂直切分,将动态和静态的字段分别存储在不同的库表中,减小数据库锁的粒度,同时可以分配不同的数据库资源来合理提升利用率。

9.3 冷热分离

冷热分离可以说是每个存储产品和海量业务的必备功能,Mysql、ElasticSearch、CMEM、Grocery 等都直接或间接支持冷热分离。将热数据放到性能更好的存储设备上,冷数据下沉到廉价的磁盘,从而节约成本。企鹅电竞为了节省在腾讯云成本,直播回放按照主播粉丝数和时间等条件也采用了冷热分离,下图是 ES 冷热分离的一个实现架构图。

ES冷热分离架构图

9.4 重写轻读

重写轻度个人理解可能有两个含义:1)关键写,降低读的关键性,如异步复制,保证主节点写成功即可,从节点的读可容忍同步延迟。2)写重逻辑,读轻逻辑,将计算的逻辑从读转移到写。适用于读请求的时候还要进行计算的场景,常见的如排行榜是在写的时候构建而不是在读请求的时候再构建。

在微博、朋友圈等社交产品场景中都有类似关注或朋友的功能。以朋友圈模拟为例(具体我也不知道朋友圈是怎么做的),如果用户进入朋友圈时看到的朋友消息列表是在请求的时候遍历其朋友的新消息再按时间排序组装出来的,这显然很难满足朋友圈这么大的海量请求。可以采取重写轻读的方式,在发朋友圈的时候就把列表构造好,然后直接读就可以了。

仿照 Actor 模型,为用户建立一个信箱,用户发朋友圈后写完自己的信箱就返回,然后异步的将消息推送到其朋友的信箱,这样朋友读取他的信箱时就是其朋友圈的消息列表,如下图所示:

重写轻读流程

上图仅仅是为了展示重写轻度的思路,在实际应用中还有些其他问题。如:1)写扩散:这是个写扩散的行为,如果一个大户的朋友很多,这写扩散的代价也是很大的,而且可能有些人万年不看朋友圈甚至屏蔽了朋友。需要采取一些其他的策略,如朋友数在某个范围内是才采取这种方式,数量太多采取推拉结合和分析一些活跃指标等。2)信箱容量:一般来说查看朋友圈不会不断的往下翻页查看,这时候应该限制信箱存储条目数,超出的条目从其他存储查询。

9.5 数据异构

数据异构主要是按照不同的维度建立索引关系以加速查询。如京东、天猫等网上商城,一般按照订单号进行了分库分表。由于订单号不在同一个表中,要查询一个买家或者商家的订单列表,就需要查询所有分库然后进行数据聚合。可以采取构建异构索引,在生成订单的时同时创建买家和商家到订单的索引表,这个表可以按照用户 id 进行分库分表。



10 队列

在系统应用中,不是所有的任务和请求必须实时处理,很多时候数据也不需要强一致性而只需保持最终一致性,有时候我们也不需要知道系统模块间的依赖,在这些场景下队列技术大有可为。

10.1 应用场景

队列的应用场景很广泛,总结起来主要有以下几个方面:

  • 异步处理:业务请求的处理流程通常很多,有些流程并不需要在本次请求中立即处理,这时就可以采用异步处理。如直播平台中,主播开播后需要给粉丝发送开播通知,可以将开播事件写入到消息队列中,然后由专门的 daemon 来处理发送开播通知,从而提高开播的响应速度。
  • 流量削峰:高并发系统的性能瓶颈一般在 I/O 操作上,如读写数据库。面对突发的流量,可以使用消息队列进行排队缓冲。以企鹅电竞为例,每隔一段时间就会有大主播入驻,如梦泪等。这个时候会有大量用户的订阅主播,订阅的流程需要进行多个写操作,这时先只写用户关注了哪个主播存储。然后在进入消息队列暂存,后续再写主播被谁关注和其他存储。
  • 系统解耦:有些基础服务被很多其他服务依赖,如企鹅电竞的搜索、推荐等系统需要开播事件。而开播服务本身并不关心谁需要这些数据,只需处理开播的事情就行了,依赖服务(包括第一点说的发送开播通知的 daemon)可以订阅开播事件的消息队列进行解耦。
  • 数据同步:消息队列可以起到数据总线的作用,特别是在跨系统进行数据同步时。拿我以前参与过开发的一个分布式缓存系统为例,通过 RabbitMQ 在写 Mysql 时将数据同步到 Redis,从而实现一个最终一致性的分布式缓存。
  • 柔性事务:传统的分布式事务采用两阶段协议或者其优化变种实现,当事务执行时都需要争抢锁资源和等待,在高并发场景下会严重降低系统的性能和吞吐量,甚至出现死锁。互联网的核心是高并发和高可用,一般将传统的事务问题转换为柔性事务。下图是阿里基于消息队列的一种分布式事务实现(详情查看:企业 IT 架构转型之道 阿里巴巴中台战略思想与架构实战,微信读书有电子版):
    基于MQ的分布式柔性事务

其核心原理和流程是:

1)分布式事务发起方在执行第一个本地事务前,向 MQ 发送一条事务消息并保存到服务端,MQ 消费者无法感知和消费该消息 ①②。

2)事务消息发送成功后开始进行单机事务操作 ③:

a)如果本地事务执行成功,则将 MQ 服务端的事务消息更新为正常状态 ④;

b)如果本地事务执行时因为宕机或者网络问题没有及时向 MQ 服务端反馈,则之前的事务消息会一直保存在 MQ。MQ 服务端会对事务消息进行定期扫描,如果发现有消息保存时间超过了一定的时间阀值,则向 MQ 生产端发送检查事务执行状态的请求 ⑤;

c)检查本地事务结果后 ⑥,如果事务执行成功,则将之前保存的事务消息更新为正常状态,否则告知 MQ 服务端进行丢弃;

3)消费者获取到事务消息设置为正常状态后,则执行第二个本地事务 ⑧。如果执行失败则通知 MQ 发送方对第一个本地事务进行回滚或正向补偿。

10.2 应用分类

  • 缓冲队列:队列的基本功能就是缓冲排队,如 TCP 的发送缓冲区,网络框架通常还会再加上应用层的缓冲区。使用缓冲队列应对突发流量时,使处理更加平滑,从而保护系统,上过 12306 买票的都懂。
    缓冲队列

在大数据日志系统中,通常需要在日志采集系统和日志解析系统之间增加日志缓冲队列,以防止解析系统高负载时阻塞采集系统甚至造成日志丢弃,同时便于各自升级维护。下图天机阁数据采集系统中,就采用 Kafka 作为日志缓冲队列。

天机阁数据采集系统

  • 请求队列:对用户的请求进行排队,网络框架一般都有请求队列,如 spp 在 proxy 进程和 work 进程之间有共享内存队列,taf 在网络线程和 Servant 线程之间也有队列,主要用于流量控制、过载保护和超时丢弃等。
    TAF请求接收队列
  • 任务队列:将任务提交到队列中异步执行,最常见的就是线程池的任务队列。
  • 消息队列
    用于消息投递,主要有点对点和发布订阅两种模式,常见的有 RabbitMQ、RocketMQ、Kafka 等,下图是常用消息队列的对比:

常用消息队列

总结

本文探讨和总结了后台开发设计高性能服务的常用方法和技术,并通过思维导图总结了成一套方法论。当然这不是高性能的全部,甚至只是凤毛菱角。每个具体的领域都有自己的高性能之道,如网络编程的 I/O 模型和 C10K 问题,业务逻辑的数据结构和算法设计,各种中间件的参数调优等。文中也描述了一些项目的实践,如有不合理的地方或者有更好的解决方案,请各位同仁赐教。

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
4月前
|
存储 缓存 安全
某鱼电商接口架构深度剖析:从稳定性到高性能的技术密码
某鱼电商接口架构揭秘:分层解耦、安全加固、性能优化三维设计,实现200ms内响应、故障率低于0.1%。详解三层架构、多引擎存储、异步发布、WebSocket通信与全链路防护,助力开发者突破电商接口“三难”困境。
|
7月前
|
消息中间件 负载均衡 中间件
⚡ 构建真正的高性能即时通讯服务:基于 Netty 集群的架构设计与实现
本文介绍了如何基于 Netty 构建分布式即时通讯集群。随着用户量增长,单体架构面临性能瓶颈,文章对比了三种集群方案:Nginx 负载均衡、注册中心服务发现与基于 ZooKeeper 的消息路由架构。最终选择第三种方案,通过 ZooKeeper 实现服务注册发现与消息路由,并结合 RabbitMQ 支持跨服务器消息广播。文中还详细讲解了 ZooKeeper 搭建、Netty 集群改造、动态端口分配、服务注册、负载均衡及消息广播的实现,构建了一个高可用、可水平扩展的即时通讯系统。
857 0
|
4月前
|
Go API 数据库
腾讯WeKnora 架构学习指南
《WeKnora架构学习指南》系统解析了这一腾讯开源的智能知识库项目,涵盖核心架构、技术栈、代码结构与学习路径。通过生活化类比和深度流程图解,帮助开发者从零掌握Go后端、Vue前端、RAG原理及微服务协同,提供四阶段进阶路线与实战建议,助力快速上手并参与贡献。
958 3
|
4月前
|
缓存 运维 监控
Redis 7.0 高性能缓存架构设计与优化
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Redis 7.0高性能缓存架构,探索函数化编程、多层缓存、集群优化与分片消息系统,用代码在二进制星河中谱写极客诗篇。
|
5月前
|
消息中间件 缓存 监控
中间件架构设计与实践:构建高性能分布式系统的核心基石
摘要 本文系统探讨了中间件技术及其在分布式系统中的核心价值。作者首先定义了中间件作为连接系统组件的"神经网络",强调其在数据传输、系统稳定性和扩展性中的关键作用。随后详细分类了中间件体系,包括通信中间件(如RabbitMQ/Kafka)、数据中间件(如Redis/MyCAT)等类型。文章重点剖析了消息中间件的实现机制,通过Spring Boot代码示例展示了消息生产者的完整实现,涵盖消息ID生成、持久化、批量发送及重试机制等关键技术点。最后,作者指出中间件架构设计对系统性能的决定性影响,
|
7月前
|
文字识别 运维 监控
架构解密|一步步打造高可用的 JOCR OCR 识别服务
本文深入解析了JOCR OCR识别服务的高可用架构设计,涵盖从用户上传、智能调度、核心识别到容错监控的完整链路,助力打造高性能、低成本的工业级OCR服务。
336 0
架构解密|一步步打造高可用的 JOCR OCR 识别服务
|
7月前
|
缓存 监控 数据安全/隐私保护
京东平台商品详情接口技术解密:高性能架构与实战经验
本文深入解析京东商品详情接口技术架构,涵盖微服务设计、多级缓存、异步加载及数据一致性保障等关键策略,分享高并发场景下的性能优化实践,助力电商系统稳定高效运行。
|
8月前
|
存储 关系型数据库 数据库
高性能云盘:一文解析RDS数据库存储架构升级
性能、成本、弹性,是客户实际使用数据库过程中关注的三个重要方面。RDS业界率先推出的高性能云盘(原通用云盘),是PaaS层和IaaS层的深度融合的技术最佳实践,通过使用不同的存储介质,为客户提供同时满足低成本、低延迟、高持久性的体验。
|
8月前
|
存储 缓存 运维
微信读书十周年,后台架构的技术演进和实践总结
微信读书经过了多年的发展,赢得了良好的用户口碑,后台系统的服务质量直接影响着用户的体验。团队多年来始终保持着“小而美”的基因,快速试错与迭代成为常态。后台团队在日常业务开发的同时,需要主动寻求更多架构上的突破,提升后台服务的可用性、扩展性,以不断适应业务与团队的变化。
336 0
|
9月前
|
消息中间件 缓存 算法
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
703 0
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡