Kafka架构及基本原理简析

kafka原理及面试套路 kafka原理及面试套路一、 面试:1、列举kafka的使用场景2、Kafka消息是采用Pull模式,还是Push模式?3、 Kafka 与传统消息系统之间有三个关键区别4. Kafka中是怎么体现消息顺序性的?5、Kafka生产者客户端中使用了几个线程来处理?分别是什么?6、Kafka中的分区器、序列化器、拦截器是否了解?它们之间的处理顺序是什么?7、 “消费组中的消费者个数如果超过topic的... 阅读详情

Kafka简介
Kafka是一个由Scala和Java编写的企业级的消息发布和订阅系统,最早是由Linkedin公司开发,最终开源到Apache软件基金会的项目。Kafka是一个分布式的,支持分区的,多副本的和多订阅者的高吞吐量的消息系统,被广泛应用在应用解耦、异步处理、限流削峰和消息驱动等场景。本文将针对Kafka的架构和相关组件进行简单的介绍。在介绍Kafka的架构之前,我们先了解一下Kafk的核心概念。

Kafka核心概念
在详细介绍Kafka的架构和基本组件之前,需要先了解一下Kafka的一些核心概念。
Producer:消息的生产者,负责往Kafka集群中发送消息;
Consumer:消息的消费者,主动从Kafka集群中拉取消息。
Consumer Group:每个Consumer属于一个特定的Consumer Group,新建Consumer的时候需要指定对应的Consumer Group ID。
Broker:Kafka集群中的服务实例,也称之为节点,每个Kafka集群包含一个或者多个Broker(一个Broker就是一个服务器或节点)。
Message:通过Kafka集群进行传递的对象实体,存储需要传送的信息。
Topic:消息的类别,主要用于对消息进行逻辑上的区分,每条发送到Kafka集群的消息都需要有一个指定的Topic,消费者根据Topic对指定的消息进行消费。
Partition:消息的分区,Partition是一个物理上的概念,相当于一个文件夹,Kafka会为每个topic的每个分区创建一个文件夹,一个Topic的消息会存储在一个或者多个Partition中。
Segment:一个partition当中存在多个segment文件段(分段存储),每个Segment分为两部分,.log文件和 .index 文件,其中 .index 文件是索引文件,主要用于快速查询.log 文件当中数据的偏移量位置;
.log文件:存放Message的数据文件,在Kafka中把数据文件就叫做日志文件。一个分区下面默认有n多个.log文件(分段存储)。一个.log文件大默认1G,消息会不断追加在.log文件中,当.log文件的大小超过1G的时候,会自动新建一个新的.log文件。
.index文件:存放.log文件的索引数据,每个.index文件有一个对应同名的.log文件。

后面我们会对上面的一些核心概念进行更深入的介绍。在介绍完Kafka的核心概念之后,我们来看一下Kafka的对外提供的基本功能,组件及架构设计。

Kafka API

如上图所示,Kafka主要包含四个主要的API组件:

1. Producer API
应用程序通过Producer API向Kafka集群发送一个或多个Topic的消息。

2. Consumer API
应用程序通过Consumer API,向Kafka集群订阅一个或多个Topic的消息,并处理这些Topic下接收到的消息。

3. Streams API
应用程序通过使用Streams API充当流处理器(Stream Processor),从一个或者多个Topic获取输入流,并生产一个输出流到一个或者多个Topic,能够有效地将输入流进行转变后变成输出流输出到Kafka集群。

4. Connect API
允许应用程序通过Connect API构建和运行可重用的生产者或者消费者,能够把kafka主题连接到现有的应用程序或数据系统。Connect实际上就做了两件事情:使用Source Connector从数据源(如:DB)中读取数据写入到Topic中,然后再通过Sink Connector读取Topic中的数据输出到另一端(如:DB),以实现消息数据在外部存储和Kafka集群之间的传输。

Kafka架构

接下来我们将从Kafka的架构出发,重点介绍Kafka的主要组件及实现原理。Kafka支持消息持久化,消费端是通过主动拉取消息进行消息消费的,订阅状态和订阅关系由客户端负责维护,消息消费完后不会立刻删除,会保留历史消息,一般默认保留7天,因此可以通过在支持多订阅者时,消息无需复制多分,只需要存储一份就可以。下面将详细介绍每个组件的实现原理。

1. Producer
Producer是Kafka中的消息生产者,主要用于生产带有特定Topic的消息,生产者生产的消息通过Topic进行归类,保存在Kafka 集群的Broker上,具体的是保存在指定的partition 的目录下,以Segment的方式(.log文件和.index文件)进行存储。

2. Consumer
Consumer是Kafka中的消费者,主要用于消费指定Topic的消息,Consumer是通过主动拉取的方式从Kafka集群中消费消息,消费者一定属于某一个特定的消费组。

3. Topic
Kafka中的消息是根据Topic进行分类的,Topic是支持多订阅的,一个Topic可以有多个不同的订阅消息的消费者。Kafka集群Topic的数量没有限制,同一个Topic的数据会被划分在同一个目录下,一个Topic可以包含1至多个分区,所有分区的消息加在一起就是一个Topic的所有消息。

4. Partition
在Kafka中,为了提升消息的消费速度,可以为每个Topic分配多个Partition,这也是就之前我们说到的,Kafka是支持多分区的。默认情况下,一个Topic的消息只存放在一个分区中。Topic的所有分区的消息合并起来,就是一个Topic下的所有消息。每个分区都有一个从0开始的编号,每个分区内的数据都是有序的,但是不同分区直接的数据是不能保证有序的,因为不同的分区需要不同的Consumer去消费,每个Partition只能分配一个Consumer,但是一个Consumer可以同时一个Topic的多个Partition。

5. Consumer Group
Kafka中的每一个Consumer都归属于一个特定的Consumer Group,如果不指定,那么所有的Consumer都属于同一个默认的Consumer Group。Consumer Group由一个或多个Consumer组成,同一个Consumer Group中的Consumer对同一条消息只消费一次。每个Consumer Group都有一个唯一的ID,即Group ID,也称之为Group Name。Consumer Group内的所有Consumer协调在一起订阅一个Topic的所有Partition,且每个Partition只能由一个Consuemr Group中的一个Consumer进行消费,但是可以由不同的Consumer Group中的一个Consumer进行消费。如下图所示:

在层级关系上来说Consumer好比是跟Topic对应的,而Consumer就对应于Topic下的Partition。Consumer Group中的Consumer数量和Topic下的Partition数量共同决定了消息消费的并发量,且Partition数量决定了最终并发量,因为一个Partition只能由一个Consumer进行消费。当一个Consumer Group中Consumer数量超过订阅的Topic下的Partition数量时,Kafka会为每个Partition分配一个Consumer,多出来的Consumer会处于空闲状态。当Consumer Group中Consumer数量少于当前定于的Topic中的Partition数量是,单个Consumer将承担多个Partition的消费工作。如上图所示,Consumer Group B中的每个Consumer需要消费两个Partition中的数据,而Consumer Group C中会多出来一个空闲的Consumer4。总结下来就是:同一个Topic下的Partition数量越多,同一时间可以有越多的Consumer进行消费,消费的速度就会越快,吞吐量就越高。同时,Consumer Group中的Consumer数量需要控制为小于等于Partition数量,且最好是整数倍:如1,2,4等。

6. Segment
考虑到消息消费的性能,Kafka中的消息在每个Partition中是以分段的形式进行存储的,即每1G消息新建一个Segment,每个Segment包含两个文件:.log文件和.index文件。之前我们已经说过,.log文件就是Kafka实际存储Producer生产的消息,而.index文件采用稀疏索引的方式存储.log文件中对应消息的逻辑编号和物理偏移地址(offset),以便于加快数据的查询速度。.log文件和.index文件是一一对应,成对出现的。下图展示了.log文件和.index文件在Partition中的存在方式。

Kafka里面每一条消息都有自己的逻辑offset(相对偏移量)以及存在物理磁盘上面实际的物理地址便宜量Position,也就是说在Kafka中一条消息有两个位置:offset(相对偏移量)和position(磁盘物理偏移地址)。在kafka的设计中,将消息的offset作为了Segment文件名的一部分。Segment文件命名规则为:Partition全局的第一个Segment从0开始,后续每个segment文件名为上一个Partition的最大offset(Message的offset,非实际物理地偏移地址,实际物理地址需映射到.log中,后面会详细介绍在.log文件中查询消息的原理)。数值最大为64位long大小,由20位数字表示,前置用0填充。

上图展示了.index文件和.log文件直接的映射关系,通过上图,我们可以简单介绍一下Kafka在Segment中查找Message的过程:
1.根据需要消费的下一个消息的offset,这里假设是7,使用二分查找在Partition中查找到文件名小于(一定要小于,因为文件名编号等于当前offset的文件里存的都是大于当前offset的消息)当前offset的最大编号的.index文件,这里自然是查找到了00000000000000000000.index。
2.在.index文件中,使用二分查找,找到offset小于或者等于指定offset(这里假设是7)的最大的offset,这里查到的是6,然后获取到index文件中offset为6指向的Position(物理偏移地址)为258。
3.在.log文件中,从磁盘位置258开始顺序扫描,直到找到offset为7的Message。
至此,我们就简单介绍完了Segment的基本组件.index文件和.log文件的存储和查询原理。但是我们会发现一个问题:.index文件中的offset并不是按顺序连续存储的,为什么Kafka要将索引文件设计成这种不连续的样子?这种不连续的索引设计方式称之为稀疏索引,Kafka中采用了稀疏索引的方式读取索引,kafka每当.log中写入了4k大小的数据,就往.index里以追加的写入一条索引记录。使用稀疏索引主要有以下原因:
(1)索引稀疏存储,可以大幅降低.index文件占用存储空间大小。
(2)稀疏索引文件较小,可以全部读取到内存中,可以避免读取索引的时候进行频繁的IO磁盘操作,以便通过索引快速地定位到.log文件中的Message。

7. Message
Message是实际发送和订阅的信息是实际载体,Producer发送到Kafka集群中的每条消息,都被Kafka包装成了一个Message对象,之后再存储在磁盘中,而不是直接存储的。Message在磁盘中的物理结构如下所示。

On-disk format of a message

offset         : 8 bytes 
message length : 4 bytes (value: 4 + 1 + 1 + 8(if magic value > 0) + 4 + K + 4 + V)
crc            : 4 bytes
magic value    : 1 byte
attributes     : 1 byte
timestamp      : 8 bytes (Only exists when magic value is greater than zero)
key length     : 4 bytes
key            : K bytes
value length   : 4 bytes
value          : V bytes

其中key和value存储的是实际的Message内容,长度不固定,而其他都是对Message内容的统计和描述,长度固定。因此在查找实际Message过程中,磁盘指针会根据Message的offset和message length计算移动位数,以加速Message的查找过程。之所以可以这样加速,因为Kafka的.log文件都是顺序写的,往磁盘上写数据时,就是追加数据,没有随机写的操作。

8.Partition Replicas
最后我们简单聊一下Kafka中的Partition Replicas(分区副本)机制,0.8版本以前的Kafka是没有副本机制的。创建Topic时,可以为Topic指定分区,也可以指定副本个数。kafka 中的分区副本如下图所示:

Kafka通过副本因子(replication-factor)控制消息副本保存在几个Broker(服务器)上,一般情况下副本数等于Broker的个数,且同一个副本因子不能放在同一个Broker中。副本因子是以分区为单位且区分角色;主副本称之为Leader(任何时刻只有一个),从副本称之为 Follower(可以有多个),处于同步状态的副本叫做in-sync-replicas(ISR)。Leader负责读写数据,Follower不负责对外提供数据读写,只从Leader同步数据,消费者和生产者都是从leader读写数据,不与follower交互,因此Kafka并不是读写分离的。同时使用Leader进行读写的好处是,降低了数据同步带来的数据读取延迟,因为Follower只能从Leader同步完数据之后才能对外提供读取服务。

如果一个分区有三个副本因子,就算其中一个挂掉,那么只会剩下的两个中,选择一个leader,如下图所示。但不会在其他的broker中,另启动一个副本(因为在另一台启动的话,必然存在数据拷贝和传输,会长时间占用网络IO,Kafka是一个高吞吐量的消息系统,这个情况不允许发生)。如果指定分区的所有副本都挂了,Consumer如果发送数据到指定分区的话,将写入不成功。Consumer发送到指定Partition的消息,会首先写入到Leader Partition中,写完后还需要把消息写入到ISR列表里面的其它分区副本中,写完之后这个消息才能提交offset。

到这里,差不多把Kafka的架构和基本原理简单介绍完了。Kafka为了实现高吞吐量和容错,还引入了很多优秀的设计思路,如零拷贝,高并发网络设计,顺序存储,以后有时间再说。

Kafka 设计架构原理详细解析(超详细图解) 什么是Kafka? Apache Kafka是一个开放源代码的分布式事件流平台,成千上万的公司使用它来实现高性 能数据管道,流分析,数据集成和关键任务等相关的应用程序。 Kafka的应用场景 构造实时流数据管道,它可以在系统或应用之间可靠地获取数据 (相当于message queue),特别是在集群情况下,多个服务器需要建立交流 构建实时流式应用程序,对这些流数据进行转换或者影响。 (就是流处理,通过kafka stream topic和topic之间内部进行变化) Kafka架构设计 Produce 阅读详情

相关推荐

Kafka-Kafka基本原理与集群快速搭建

​ ChatGPT对于Apache Kafka的介绍:Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发并于2011年开源。它主要用于解决大规模数据的实时流式处理和数据管道问题。Kafka是一个分布式的发布-订阅消息系统,可以快速地处理高吞吐量的数据流,并将数据实时地分发到多个消费者中。Kafka消息系统由多个broker(服务器)组成,这些broker可以在多个数据中心之间分布式部署,以提供高可用性和容错性。Kafka的基本架构由生产者、消费者和主题(topic)组成。

weixin_43874650的博客 1314

Kafka!(多图+深入)原理详解

一、kafka概述 1.1、定义 Kakfa是一个分布式的基于发布/订阅模式的消息队列(message queue),主要应用于大数据的实时处理领域 1.2、消息队列 1.2.1、传统的消息队列&新式的消息队列的模式 上面是传统的消息队列,比如一个用户要注册信息,当用户信息写入数据库后,后面还有一些其他流程,比如发送短信,则需要等这些流程处理完成后,在返回给用户 而新式的队...

ytp552200ytp的博客 1万+

光电系统光轴校准与偏差控制实战指南

光轴作为光电系统的空间基准坐标系,直接影响多光谱传感器的协同工作精度。在包含可见光、红外与激光测距的复合系统中,光轴偏差会导致目标识别误差与打击精度下降。通过机械基准建立、光学通道粗调和多光谱协同校准等工厂级标定流程,结合千米靶标法、星点校准法等野战应急方案,可有效控制光轴偏差。典型应用场景中,温度补偿与振动抑制技术能维持光轴稳定性,如某舰载系统通过500Hz高频视觉伺服实现0.3mrad振动补偿。掌握这些光轴标定与保持策略,对提升光电系统在侦察、测距等场景的实战性能具有关键价值。

weixin_36149538的博客 273

Kafka的工作原理

pull模式的不足之处在于,如果kafka没有数据,消费者会陷入空循环中,针对这一点,Kafka的消费者会在消费时传入timeout参数,如果当前Kafka中没有数据,消费者会等待一个timeout时长再返回。,会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步,等该follower大于partition的HW时,即follower追上leader时,就可以重新加入ISR了。

wulianwang001的专栏 7385

MS1861宏晶微视频显示与控制器芯片:开发资料全解析与应用指南

本文全面解析了宏晶微MS1861视频显示与控制器芯片的核心功能与开发流程。该芯片作为高性能的“视频信号翻译官”,支持HDMI、LVDS等多种输入与MIPI、LVDS等输出,集成强大的图像处理与OSD叠加功能。文章详细介绍了从资料获取、环境搭建到以HDMI转MIPI为例的实战配置与调试技巧,为工业HMI、广告机等应用的开发者提供了完整的应用指南。

weixin_29198045的博客 337

ns3-gym入门(二):linear-mesh例子详解

学习ns3-gym中关于IEEE 802.11网状网络中控制随机接入的例子linear-mesh

zoe2222226666的博客 1842

Kafka架构及基本原理简析,linux应用开发面试题

考虑到消息消费的性能,Kafka中的消息在每个Partition中是以分段的形式进行存储的,即每1G消息新建一个Segment,每个Segment包含两个文件:.log文件和.index文件。Producer是Kafka中的消息生产者,主要用于生产带有特定Topic的消息,生产者生产的消息通过Topic进行归类,保存在Kafka 集群的Broker上,具体的是保存在指定的partition 的目录下,以Segment的方式(.log文件和.index文件)进行存储。

m0_60229361的博客 977

HMC5883L磁力计驱动开发:I²C通信、校准与FreeRTOS集成

磁力计是惯性导航与电子罗盘系统的核心传感器,其输出原始磁场数据需经精确采集、单位换算与误差补偿才能用于姿态解算。基于各向异性磁阻(AMR)原理的三轴磁力计,如HMC5883L,依赖稳定I²C通信获取12位有符号磁场采样值,并通过增益配置、硬软铁校准及温度补偿提升物理量精度。在嵌入式实时系统中,驱动层须保障数据的时间一致性与抗干扰鲁棒性,避免总线挂死、字节错位或量程误配等典型问题。本文围绕HMC5883L这一广泛使用的停产但仍在产线服役的磁传感器,详解寄存器配置、定点单位转换、八方位校准算法及FreeRTOS

weixin_42594427的博客 145

一文五分钟让你彻底理解Kafka架构原理

对于kafka的架构原理我们先提出几个问题? 1.Kafka的topic和分区内部是如何存储的,有什么特点? 2.与传统的消息系统相比,Kafka的消费模型有什么优点? 3.Kafka如何实现分布式的数据存储与数据读取? 一、Kafka架构图 1.kafka名词解释 在一套kafka架构中有多个Producer,多个Broker,多个Consumer,每个Producer可以对应多个Topic,每个Consumer只能对应一个ConsumerGroup。 整个Kafka架构对应一个ZK集群,通过ZK管理集

284

29、高速低功耗采样保持放大器设计

本文详细介绍了适用于低功耗模数转换器的高速低电压采样保持放大器(SHA)的设计技术,包括传统SHA的局限性、采样技术分类以及全NPN型和BiCMOS型SHA的具体设计实现。同时,文章深入探讨了优化输入电容、采样开关驱动及低功耗设计等具体措施,并提供了10位ADC前端和无线通信应用中的实例分析,为相关领域的工程师提供有价值的参考。

weixin_30600615的博客 424

《Autosar_MCAL高阶配置》总目录_培训教程持续更新中...

《Autosar_MCAL高阶配置》总目录_培训教程持续更新中...

「汽车电子助手」的博客 1万+

kafka基本原理

一、kafka概述 1、定义 kafka是一个分布式的基于发布订阅模式的消息队列,主要用于大数据实时处理灵越 2、消息队列 【1】应用场景 用于异步、削峰、解耦 【2】两种模式 (1)点对点模式 ​ 一对一,消费者主动拉取数据。消息生产者将消息发送到queue中,然后消费者从queue中取出并消费消息,消息被消费者消费以后,queue中不在存储消息,所以消息消费者不可能重复消费已经被消费过的消息。queue支持存在多个消费者,即一个消费者组可以有多个消费者,但是消息只能被一个消费者消费。 (2)发布订阅

专栏 1万+

【OpenCV】第二十四章: 图像特征匹配:暴力特征匹配算法、FLANN特征匹配算法

参数match就是匹配器的匹配结果;参数crossCheck表示交叉检查,意思就是用第一组中的每个描述子和第二组的所有描述子进行匹配完后,再用第二组中的每个描述子和第一组的所有描述子进行匹配,这两步做完后,两步同时找到的相同的匹配对儿就是有效的匹配。方法一:用匹配器的match方法,进行特征匹配:match = bf.match(des1, des2),就是对两幅图的描述子进行计算,返回匹配的结果。匹配的时候是计算两个描述子之间的相似度,然后返回相似度最高的一对儿匹配点,也就是最终的匹配结果。

因为热爱所以坚持 5061

【kafka】Kafka基本原理详解

Partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中没有)三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。所以在实际的应用中,。Kafka采用的是发布订阅模式,消费者主动的去kafka集群拉取消息,与producer相同的是,消费者在拉取消息的时候也是找!

翰林小院 1328

Python 爬虫实战:爬取哔哩哔哩知识区,抓取高赞课程信息

哔哩哔哩(Bilibili)是一个广受欢迎的综合性视频社区,其中的知识区汇聚了大量优质的教育、科普、技术等课程内容。本文将指导读者如何使用 Python 爬虫技术从哔哩哔哩知识区抓取高赞课程信息,并进行数据分析。本文深入探究了利用 Python 爬虫技术从哔哩哔哩知识区抓取高赞课程信息的全流程。从前期的环境搭建、模拟登录,到核心的课程数据抓取、存储,再到后续的数据分析与可视化,都详细展开讲解并提供代码支持。通过此方法所获取的数据,能够助力创作者优化内容、用户发现优质课程、平台洞察用户需求。

u014481728的博客 1134

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Kafka基本原理详解

Apache Kafka是一种开源的分布式流处理平台,专为高性能、高吞吐量的实时数据处理而设计。它最初由LinkedIn公司开发,旨在解决其网站活动中产生的大量实时数据处理和传输问题,后来于2011年开源,并捐赠给了Apache软件基金会,逐渐发展成为大数据和实时数据管道领域的核心组件之一。

嫣然细雨红尘路 5100

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Kafka基本原理和Kafka架构

Kafka基本原理和Kafka架构一、什么是Kafka:二、Kafka的架构: 一、什么是Kafka: 1、什么是Kafka? 2、扩展: 消息队列: 二、Kafka的架构: 1、Kafka的架构: 温馨提示:该文章为本人自己创作,转载请标明出处。感谢各位!!!谢谢大家!!! 本人联系方式: QQ:961094233 邮箱:961094233@qq.com ...

搁浅的博客 1498

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

图解 Kafka 架构

Kafka 是一个可横向扩展,高可靠的实时消息中间件,常用于服务解耦、流量削峰。

面向生活编程 3707

kafka和flume基本原理的比较

kafka的基本原理 Kafka的架构:分布式消息系统,默认将消息存入磁盘,存储时间是7天。 Producer:消息的生产者,自己决定消息写往哪个partition,两种:1.hash,2.轮询 Broker:组建kafka集群的节点,broker之间没有主从关系,broker由zookeeper来协调,broker负责消息的读写,存储。每个broker可以管理多个partition。 T...

wyqwilliam的博客 3861
上一篇: Redis的这些拓展方案,用过一条的就是p6级
下一篇: 10年 Java 老鸟,写给 1-3 年程序员的几点建议,满满硬货指导
Java领域指导者
博客等级 码龄7年 404粉丝 265原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值