news 2026/6/21 3:19:17

【Clickhouse从入门到精通】第44篇:ClickHouse副本与分片概述——分布式架构总览

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Clickhouse从入门到精通】第44篇:ClickHouse副本与分片概述——分布式架构总览

上一篇【第43篇】ClickHouse时间日期函数与JSON解析
下一篇【第45篇】ClickHouse数据副本_ZooKeeper配置与副本定义


摘要

本文是《Clickhouse从入门到精通》系列博客的第44篇文章,深入介绍ClickHouse分布式架构的两大核心概念:副本(Replica)与分片(Shard)。文章从单机部署的局限性出发,详细阐述副本与分片的设计理念、核心作用、实现机制,以及两者在不同场景下的组合方式。通过对比表格和实战案例,帮助读者理解如何根据具体业务需求规划合理的分布式集群架构,为后续深入副本配置与ReplicatedMergeTree原理打下坚实基础。

关键词:副本、分片、分布式架构、高可用、水平扩展


1. 引言

在前面43篇文章中,我们系统地学习了ClickHouse的方方面面:从基础架构、数据类型、表引擎、查询语法,到 MergeTree 系列引擎的底层原理、数据分区与索引机制、主索引与跳数索引、SET和JOIN引擎、时间日期函数与JSON解析等。所有这些内容,都是建立在单机ClickHouse实例的基础之上的。

然而,在生产环境中,单机部署往往无法满足企业级应用的需求。当数据量突破单机存储上限、当查询并发超过单机处理能力、当硬件故障可能导致服务不可用——这些场景都逼迫我们走向分布式架构。

ClickHouse的分布式架构设计,围绕两个核心概念展开:副本(Replica)分片(Shard)。理解这两个概念,是掌握ClickHouse分布式部署的前提。

本文作为分布式系列的开篇,将从宏观视角带领读者一览ClickHouse分布式架构的全貌,理解副本与分片各自解决什么问题、如何协同工作,以及如何根据实际业务场景选择合适的架构组合。

2. 单机局限与分布式需求

2.1 单机部署的典型瓶颈

在开发测试环境或数据量较小的场景下,单机ClickHouse实例完全可以胜任。但随着业务增长,单机部署会逐渐暴露出以下瓶颈:

存储容量瓶颈

ClickHouse虽然以高效压缩著称,但单机磁盘容量终究有限。当数据量达到TB甚至PB级别时,单块磁盘或RAID阵列都无法容纳。即便使用大容量磁盘,备份和恢复的时间成本也会急剧上升。

-- 单机场景下,查看当前数据量SELECTdatabase,table,formatReadableSize(sum(bytes_on_disk))ASsize_on_disk,sum(rows)AStotal_rowsFROMsystem.partsWHEREactive=1GROUPBYdatabase,tableORDERBYsum(bytes_on_disk)DESCLIMIT10;

计算能力瓶颈

ClickHouse的并行计算能力在单机范围内已经非常出色(利用多个CPU核心和多块磁盘),但当查询并发量大幅上升,或者需要执行极其复杂的聚合查询时,单机CPU和内存资源终究会达到上限。

高可用缺失

单机部署意味着单点故障(Single Point of Failure, SPOF)。一旦服务器宕机、磁盘损坏,或者操作系统出现问题,整个ClickHouse服务将完全不可用,直到故障恢复。对于需要7×24小时可用的生产系统而言,这是不可接受的。

备份与恢复风险

即使有定期备份策略,从备份中恢复TB级数据也需要相当长的时间。在恢复期间,服务处于不可用状态,这对业务造成的影响可能非常严重。

2.2 分布式架构解决的核心问题

ClickHouse的分布式架构设计,旨在通过以下方式解决上述瓶颈:

核心需求解决方案ClickHouse实现机制
数据量超出单机存储上限数据分片(Sharding)将数据水平拆分到多个节点
高可用与故障切换数据副本(Replication)多节点存储相同数据副本
读查询负载均衡副本读取分摊分布式查询自动路由
写吞吐扩展分片写入并行化数据按分片键分发
在线横向扩展增加分片节点弹性扩缩容

3. 副本(Replica)核心概念

3.1 副本的作用

副本(Replica),指的是在多台物理服务器上存储相同数据的拷贝。在ClickHouse中,副本机制主要由ReplicatedMergeTree系列表引擎来实现。

副本机制解决的核心问题包括:

高可用性(High Availability)

当某个副本节点发生硬件故障、操作系统崩溃或网络分区时,集群中的其他副本节点可以立即接管服务,保证数据的可读性和可写性。这是生产环境部署的最低要求。

故障切换(Failover)

ClickHouse的副本机制支持自动故障检测和切换。当leader副本不可用时,其他副本会自动选举新的leader,无需人工干预。

读负载均衡(Read Load Balancing)

多个副本都可以对外提供读服务。当查询并发量较高时,可以将读请求分摊到不同的副本节点上,从而提升整体的查询吞吐能力。写请求通常由leader副本协调,但也可以通过配置实现更复杂的写入策略。

-- 查看各副本的数据同步状态SELECTdatabase,table,replica_name,is_leader,is_readonly,total_replicas,active_replicasFROMsystem.replicasORDERBYdatabase,table;

3.2 副本实现机制:基于ZooKeeper协调的ReplicatedMergeTree

ClickHouse的副本机制并非通过传统的主从复制(Master-Slave Replication)实现,而是基于ZooKeeper(或使用ClickHouse Keeper作为替代)进行协调的ReplicatedMergeTree引擎。

其核心工作流程如下:

  1. 写入操作:客户端向任意副本节点发起INSERT请求,该节点作为本次写入的协调者,将操作日志写入ZooKeeper的/log路径
  2. 日志分发:其他副本节点监听ZooKeeper中的/log路径,发现新日志后拉取并执行
  3. 数据传输:实际的数据文件并不经过ZooKeeper传输,而是通过ClickHouse节点之间的HTTP通信直接传输,保证了数据传输的高效性
  4. 最终一致性:由于写入是异步同步的,不同副本之间可能存在短暂的数据不一致,但最终会达到一致状态

这种设计的核心优势在于:ZooKeeper只存储元数据和小量的协调信息,不存储实际数据,从而避免了ZooKeeper成为性能瓶颈。

3.3 副本与备份的区别

很多初学者容易混淆"副本"与"备份"的概念,二者有本质区别:

对比维度副本(Replica)备份(Backup)
用途实时高可用、故障切换灾难恢复、数据归档
数据时效性近实时(秒级延迟)取决于备份频率(小时/天级)
自动化程度全自动同步通常需手动或定时任务
恢复速度秒级(自动切换)分钟到小时级
存储位置通常同机房或近机房可跨地域、跨云存储
是否参与查询是(读负载均衡)否(仅供恢复)
ClickHouse机制ReplicatedMergeTree + ZKBACKUP/RESTORE 或文件系统快照

重要结论:副本不能替代备份。即便有了多副本,仍然需要定期备份策略来应对误删除、数据损坏、以及机房级别灾难等极端场景。

4. 分片(Shard)核心概念

4.1 分片的作用

分片(Shard),指的是将不同的数据分布到多个物理节点上,每个节点只存储整体数据的一个子集。分片机制解决的核心问题是水平扩展(Horizontal Scaling)

与副本"复制相同数据"的理念完全不同,分片的核心是"切分不同数据":

突破单机存储上限

通过将数据分散到多个节点,整个集群的总存储容量等于各分片存储容量之和。理论上,分片数量可以无限扩展(实际受协调开销限制),从而实现PB级甚至EB级的数据存储。

突破单机计算上限

查询可以在多个分片上并行执行,每个分片只处理自己持有的数据子集,从而将查询性能与分片数量近似呈线性关系提升。

-- 查看各分片的数据分布情况SELECTshard_num,count()ASparts_count,formatReadableSize(sum(bytes_on_disk))ASsize_on_disk,sum(rows)AStotal_rowsFROMclusterAllReplicas('cluster_name',system,parts)WHEREactive=1GROUPBYshard_numORDERBYshard_num;

4.2 分片与分区(PARTITION BY)的区别

这是ClickHouse学习中最容易混淆的概念之一。许多用户误以为"分区"就是"分片",实际上二者完全不同:

对比维度分片(Shard)分区(Partition)
作用范围跨物理节点单节点内部
目的水平扩展、突破单机上限数据管理、分区裁剪
数据存储不同节点存不同数据同一节点存不同目录
查询并行跨节点并行节点内多线程并行
配置方式集群配置 + 分布式表CREATE TABLE时PARTITION BY
失败影响分片故障影响部分数据分区故障仅影响该分区
典型数量级2-几十个几十-几百个

简单记忆:分区是"竖着切"(按时间或其他维度将表内数据分组管理),分片是"横着切"(将数据分布到不同机器上)。

4.3 分片键的设计原则

分片键(Sharding Key)决定了数据行会被分配到哪个分片。合理的分片键设计对集群性能有决定性影响。

分片键的选择原则

  1. 均匀分布:分片键的哈希值应尽可能均匀地分布到各个分片,避免出现"数据倾斜"(某些分片数据量远大于其他分片)
  2. 查询友好:常见的查询条件如果包含分片键,可以实现"分区裁剪"效果,只查询相关分片
  3. 避免频繁变更:分片键一旦确定,修改成本很高(需要重新分布数据)
  4. 离散度高:选择基数高的列作为分片键,如用户ID、订单ID等
-- 使用分布式表引擎时指定分片键CREATETABLEdistributed_table(user_id UInt64,event_timeDateTime,event_type String,amount Float64)ENGINE=Distributed('cluster_name','default','local_table',sipHash64(user_id));-- ^^^^^^^^^^^^^^^^-- 分片键:对user_id做哈希

常见分片策略对比

分片策略适用场景优点缺点
哈希分片(sipHash64)通用场景数据分布均匀范围查询需跨所有分片
取模分片(% shard_count)分片数固定简单直观扩缩容需重新分布
范围分片时间序数据时间范围查询高效易产生数据倾斜
一致性哈希动态扩缩容扩缩容影响小实现复杂

5. 副本与分片的组合方式

5.1 四种基本组合模式

副本和分片是两个正交的概念,可以独立使用,也可以组合使用。根据业务需求的不同,可以采用以下四种基本组合模式:

模式一:单副本单分片(Standalone)

┌─────────────┐ │ 节点 A │ ← 唯一节点,无副本,无分片 │ (所有数据) │ └─────────────┘
  • 描述:即标准的单机部署,不使用副本也不使用分片
  • 优点:部署简单,运维成本低,无额外开销
  • 缺点:无高可用,无扩展能力
  • 适用场景:开发测试环境、数据量小的非关键业务

模式二:多副本单分片(Replication Only)

┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 节点 A │ │ 节点 B │ │ 节点 C │ │ (副本1) │←─副本同步──→│ (副本2) │←─副本同步──→│ (副本3) │ │ (所有数据) │ │ (所有数据) │ │ (所有数据) │ └─────────────┘ └─────────────┘ └─────────────┘
  • 描述:数据在多个节点上各有完整副本,但数据不分片
  • 优点:高可用(任意节点故障不影响服务),读负载可分摊
  • 缺点:存储容量不扩展(每个节点存全量数据),写性能无提升
  • 适用场景:数据量在单机可承受范围内,但对高可用有强需求的场景

模式三:单副本多分片(Sharding Only)

┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 节点 A │ │ 节点 B │ │ 节点 C │ │ (分片1) │ │ (分片2) │ │ (分片3) │ │ (1/3数据) │ │ (1/3数据) │ │ (1/3数据) │ └─────────────┘ └─────────────┘ └─────────────┘
  • 描述:数据按分片键分布到多个节点,但每个分片只有一份拷贝
  • 优点:存储和计算能力可水平扩展,适合大规模数据存储
  • 缺点:无高可用(任何节点故障都会导致部分数据不可用)
  • 适用场景:数据可重新生成或从其他源重新导入的场景(如日志分析),对可用性要求不高

模式四:多副本多分片(Production Recommended)

┌──────────────────────────────────────────────────┐ │ 分片1 │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 节点 A │←─副本同步──→│ 节点 B │ │ │ │ (副本1) │ │ (副本2) │ │ │ └─────────────┘ └─────────────┘ │ └──────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────┐ │ 分片2 │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 节点 C │←─副本同步──→│ 节点 D │ │ │ │ (副本1) │ │ (副本2) │ │ │ └─────────────┘ └─────────────┘ │ └──────────────────────────────────────────────────┘
  • 描述:每个分片配置多个副本,兼顾水平扩展和高可用
  • 优点:既能水平扩展存储和计算,又具备高可用能力
  • 缺点:硬件成本较高(数据冗余存储),运维复杂度增加
  • 适用场景:生产环境的标准配置,尤其是对可用性和扩展性都有要求的场景

5.2 架构组合对比表

架构模式高可用水平扩展读负载均衡硬件成本运维复杂度生产推荐
单副本单分片
多副本单分片部分场景
单副本多分片⚠️(仅分片内)
多副本多分片

6. ClickHouse集群架构中的关键组件

6.1 ZooKeeper / ClickHouse Keeper的角色

在ClickHouse分布式架构中,ZooKeeper(或使用ClickHouse内置的ClickHouse Keeper)承担着集群协调的核心职责。它是副本机制正常工作的基础,但本身不存储任何实际数据。

ZooKeeper在ClickHouse集群中的具体职责包括:

  1. 副本元数据管理:存储每个副本的元数据信息,包括副本名称、所在节点、同步状态等
  2. 操作日志协调:管理副本间的数据同步日志(/log路径),确保各副本按相同顺序执行操作
  3. Leader选举:当当前leader副本不可用时,协调选举新的leader副本
  4. DDL查询协调:在执行分布式DDL(如CREATE TABLE ... ON CLUSTER)时,协调各节点执行
  5. INSERT去重:通过记录数据块哈希,防止重复写入
ClickHouse节点与ZooKeeper的关系: ┌─────────────────────────────────────┐ │ ZooKeeper集群 │ │ (存储元数据、协调信息、日志) │ └──────────┬──────────────────────────┘ │ 监听/写入元数据 ┌───────┴───────┐ ▼ ▼ ┌─────────┐ ┌─────────┐ │ ClickHouse│ │ ClickHouse│ │ 节点 A │ │ 节点 B │ │ (副本1) │ │ (副本2) │ └─────────┘ └─────────┘ │ │ └───────数据同步───────┘ (实际数据通过HTTP传输,不经过ZK)

重要提示:随着集群规模增大,ZooKeeper可能成为性能瓶颈。ClickHouse Keeper是ClickHouse官方提供的ZooKeeper替代方案,使用Raft共识算法,性能更好,运维更简单,是新建集群的推荐选择。

6.2 Distributed表引擎

Distributed表引擎是ClickHouse实现分布式查询的核心组件。它本身不存储任何数据,而是作为一个"路由层",将查询转发到对应的本地表,然后汇总结果返回给客户端。

-- Distributed表引擎的建表语法CREATETABLEdistributed_tableENGINE=Distributed('cluster_name',-- 集群名称(在config.xml中定义)'database',-- 本地表所在的数据库'local_table',-- 本地表名称sipHash64(id)-- 分片键(用于写入时数据分发))

Distributed表的核心功能

  • 查询路由:接收客户端查询,将查询发送到相关分片,合并结果返回
  • 写入分发:接收客户端写入,根据分片键将数据和distribution到对应的分片
  • 跨分片聚合:在协调节点上对各个分片返回的部分结果进行二次聚合

重要注意事项

  1. Distributed表不存储数据,必须配合本地表(通常是ReplicatedMergeTree表)使用
  2. 查询通过Distributed表时,会在协调节点上产生额外的计算开销(二次聚合)
  3. 写入通过Distributed表时,如果目标分片不可达,数据可能丢失(需配置合适的写入策略)

6.3 ReplicatedMergeTree系列引擎

ReplicatedMergeTree是支持副本机制的MergeTree家族表引擎。它在普通MergeTree的基础上,增加了基于ZooKeeper的副本协调功能。

ReplicatedMergeTree系列包括:

引擎名称对应基础引擎额外功能
ReplicatedMergeTreeMergeTree基础副本引擎
ReplicatedReplacingMergeTreeReplacingMergeTree副本 + 去重替换
ReplicatedSummingMergeTreeSummingMergeTree副本 + 自动汇总
ReplicatedAggregatingMergeTreeAggregatingMergeTree副本 + 聚合状态
ReplicatedCollapsingMergeTreeCollapsingMergeTree副本 + 行折叠
ReplicatedVersionedCollapsingMergeTreeVersionedCollapsingMergeTree副本 + 版本折叠

在后续文章中,我们将深入解析ReplicatedMergeTree的工作原理。

7. 生产级集群规划建议

7.1 分片数选择原则

选择分片数量时,需要综合考虑数据量、查询性能、运维复杂度等多个因素:

数据量维度

每个分片承载的数据量不宜过大。根据社区最佳实践,建议每个分片的数据量控制在10TB以内(具体取决于硬件配置)。数据量过大会导致:

  • 单次Merge操作耗时过长
  • 节点故障恢复时间过久
  • 备份恢复窗口过大
分片数 ≈ CEILING(总数据量 / 单分片建议上限) 例如:总数据量50TB,单分片上限10TB → 至少需要5个分片

查询性能维度

更多的分片意味着查询可以并行在更多节点上执行,从而提升查询速度。但分片数过多也会带来协调开销的增加。根据经验:

  • OLAP场景(大量全表扫描):分片数与CPU核心总数呈近似线性关系
  • 点查场景(按主键查询):分片数不宜过多,避免增加网络路由开销

运维复杂度维度

分片数越多,集群的运维复杂度越高。每个分片都可能需要独立的监控、备份策略。建议分片数保持在几十个以内,超过100个分片会带来显著的运维负担。

7.2 副本数选择原则

副本数的黄金法则:奇数副本

与分布式系统的通用实践一致,ClickHouse副本数建议使用奇数(1、3、5)。这是因为:

  • 支持法定人数(Quorum)写入确认
  • insert_quorum配置下,可容忍(N-1)/2个副本故障而不影响写入
副本数可容忍故障数写入确认节点数存储开销适用场景
101开发测试
20(偶数,不推荐)2不推荐
312生产环境推荐
523金融级高可用

生产环境推荐配置:3副本(即每个分片有3份数据拷贝),可以在容忍1个副本故障的同时,提供良好的读负载均衡能力。

7.3 硬件规划建议

组件推荐配置说明
CPU16-64核核数越多,并行查询性能越好
内存64-256GB大内存可缓存更多热数据
磁盘SSD或NVMe避免使用HDD,Merge操作对磁盘IO要求高
网络10Gbps+副本间数据同步需要高带宽低延迟网络
ZooKeeper节点3或5节点独立部署,不与ClickHouse混布

8. 实战案例:规划一个支持百亿级数据的生产分布式集群架构方案

8.1 业务需求分析

假设我们有一个互联网广告投放分析系统,需要满足以下需求:

  • 数据规模:每日新增10亿条广告曝光记录,每条约200字节,日增约200GB;保留3年数据,总量约216TB
  • 查询场景:以时间范围查询为主,辅以广告主ID、广告计划ID的等值查询;有一定量的多表JOIN操作
  • 可用性要求:99.9% SLA,允许每年不超过8.76小时的停机时间
  • 写入要求:支持实时写入,端到端延迟不超过10秒

8.2 架构方案设计

基于以上需求,我们设计如下分布式集群架构:

集群拓扑

总数据量:216TB(压缩后约54TB,按4:1压缩比) 副本策略:每个分片3副本(高可用) 分片数量:6个分片(每分片约9TB数据,在10TB建议上限内) 分片1:节点A(副本1) | 节点B(副本2) | 节点C(副本3) 分片2:节点D(副本1) | 节点E(副本2) | 节点F(副本3) 分片3:节点G(副本1) | 节点H(副本2) | 节点I(副本3) 分片4:节点J(副本1) | 节点K(副本2) | 节点L(副本3) 分片5:节点M(副本1) | 节点N(副本2) | 节点O(副本3) 分片6:节点P(副本1) | 节点Q(副本2) | 节点R(副本3) ZooKeeper集群:3节点(独立部署)

节点硬件配置

规格项配置理由
CPU32核支持高并发查询
内存128GB缓存热数据,加速查询
磁盘2TB NVMe SSD × 6(RAID10)约12TB可用,容纳9TB数据+缓冲
网络10Gbps副本同步带宽保障

分片键设计

考虑到查询以时间范围 + 广告主ID为主,选择sipHash64(advertiser_id)作为分片键:

  • 广告主ID基数高,哈希分布均匀
  • 同一广告主的数据集中在少数分片,有利于缓存命中
-- 本地表(在每个节点上创建)CREATETABLEad_impressions_local(event_dateDate,event_timeDateTime,advertiser_id UInt64,campaign_id UInt64,impression_id String,cost Float64,-- ... 其他字段)ENGINE=ReplicatedMergeTree('/clickhouse/tables/{shard}/default/ad_impressions','{replica}')PARTITIONBYtoYYYYMM(event_date)ORDERBY(advertiser_id,event_date,event_time);-- 分布式表(用于应用层访问)CREATETABLEad_impressionsENGINE=Distributed('ad_cluster','default','ad_impressions_local',sipHash64(advertiser_id));

高可用保障

  • 每个分片3副本,允许1个副本故障不影响服务
  • ZooKeeper 3节点部署,允许1个节点故障
  • 定期备份到对象存储(如S3),用于灾难恢复

9. 总结与最佳实践

本文从宏观视角系统地介绍了ClickHouse分布式架构的两大支柱——副本与分片。以下是本文的核心要点总结:

核心概念回顾

  1. 副本解决高可用问题:多节点存储相同数据,支持故障自动切换和读负载均衡
  2. 分片解决扩展性问题:数据水平拆分到多节点,突破单机存储和计算上限
  3. 副本与分片是正交概念,可独立使用,也可组合使用

架构选择建议

  1. 生产环境应使用多副本多分片架构,通常每个分片配置3副本
  2. 分片数根据数据量和查询性能需求综合确定,建议控制在几十个以内
  3. 每个分片的数据量建议控制在10TB以内

技术选型建议

  1. 新集群优先使用ClickHouse Keeper替代ZooKeeper,性能更好且运维更简单
  2. 使用ReplicatedMergeTree系列引擎实现副本机制
  3. 使用Distributed表引擎作为分布式查询的入口层

下一步学习

在下一篇文章中,我们将深入讲解ClickHouse数据副本的具体配置方法,包括ZooKeeper/ClickHouse Keeper的详细配置、ReplicatedMergeTree的建表语法、宏变量(macros)的使用,以及完整的2分片2副本集群搭建实战。


上一篇【第43篇】ClickHouse时间日期函数与JSON解析
下一篇【第45篇】ClickHouse数据副本_ZooKeeper配置与副本定义


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 14:53:38

如何快速修复Visual C++运行库问题:终极完整指南

如何快速修复Visual C运行库问题:终极完整指南 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist Visual C运行库是Windows系统中至关重要的组件&#x…

作者头像 李华
网站建设 2026/5/20 14:53:35

PowerPoint公式排版革命:用LaTeX语法告别数学符号输入噩梦

PowerPoint公式排版革命:用LaTeX语法告别数学符号输入噩梦 【免费下载链接】latex-ppt Use LaTeX in PowerPoint 项目地址: https://gitcode.com/gh_mirrors/la/latex-ppt 还在为PowerPoint中复杂的数学公式输入而烦恼吗?作为科研人员、教师或学生…

作者头像 李华
网站建设 2026/5/20 14:52:02

Rufus实战指南:三步完成可启动USB制作与系统安装优化方案

Rufus实战指南:三步完成可启动USB制作与系统安装优化方案 【免费下载链接】rufus The Reliable USB Formatting Utility 项目地址: https://gitcode.com/GitHub_Trending/ru/rufus Rufus(The Reliable USB Formatting Utility)是一款专…

作者头像 李华
网站建设 2026/5/20 14:47:27

如何快速掌握B站视频下载:从新手到专家的完整BilibiliDown教程

如何快速掌握B站视频下载:从新手到专家的完整BilibiliDown教程 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_m…

作者头像 李华