分布式微服务系统架构第164集:架构懂了就来了解数据库存储扩展千亿读写

加群联系作者vx:xiaoda0423

仓库地址:webvueblog.github.io/JavaPlusDoc...

1024bat.cn/

github.com/webVueBlog/...

webvueblog.github.io/JavaPlusDoc...

点击勘误issues,哪吒感谢大家的阅读

架构懂了就来了解数据库存储扩展千亿读写

一键可用的三档假设(你直接选)

档位 峰值写入 W (条/s) 单行大小 R (字节) 热数据保留 T (天) 适用场景
A 保守 50,000 200 30 早期 PoC / 小规模上线
B 均衡(推荐) 200,000 300 30(热)+ 180(温) 典型 IoT/日志明细
C 激进 1,000,000 500 30(热)+ 365(温) 海量设备/重分析

说明:热数据 放 OLTP/时序/列式集群用于线上与报表;温/冷数据分层到 ClickHouse + 对象存储。


关键资源测算(已算好,可直接用)

(经验公式:Kafka 分区≈W/5k;OLTP 分片≈W/10k;Redis 分片≈(0.1×W)/50k;吞吐(MB/s)=W×R/1e6)

A 保守(5 万写/s,200B,30 天)

  • Kafka :≈ 10 分区(建议 3--4 台 broker 起步)
  • OLTP 分片 (MySQL+Vitess 或 TiDB):≈ 5 分片
  • Redis Cluster :≈ 1 分片(假设 10% 写入走状态存取)
  • 入口吞吐 :≈ 10 MB/s
  • ClickHouse 存储 (仅热 30 天;压缩后≈原始/3):≈ 8.64 TB (无副本);RF=217.28 TB

B 均衡(20 万写/s,300B,热 30 天 + 温 180 天)

  • Kafka :≈ 40 分区(建议 6--8 broker)

  • OLTP 分片 :≈ 20 分片(倾向 TiDB 降低运维复杂度)

  • Redis Cluster :≈ 1 分片(0.1×W 假设)

  • 入口吞吐 :≈ 60 MB/s

  • ClickHouse(热 30 天) :压缩后≈ 51.84 TBRF=2103.68 TB

  • ClickHouse(温 180 天) :压缩后≈ 311.04 TBRF=2622.08 TB

    建议:温数据落分层存储 (HDD/对象存储 + S3 Cache),并用物化视图/预聚合显著降体量。

C 激进(100 万写/s,500B,热 30 天 + 温 365 天)

  • Kafka :≈ 200 分区(建议 12--16 broker)

  • OLTP 分片 :≈ 100 分片(强烈建议 TiDB/CockroachDB)

  • Redis Cluster :≈ 2 分片(按 10% 写入估算)

  • 入口吞吐 :≈ 500 MB/s

  • ClickHouse(热 30 天) :压缩后≈ 144 TBRF=2288 TB

  • ClickHouse(温 365 天) :压缩后≈ 5,256 TBRF=210,512 TB

    必须做冷热分层 + 强预聚合 + 近实时明细裁剪(比如明细仅保留 7--14 天)。


跨地域多活怎么选?

  • 不多活 / 同城双活 (推荐起步): 事务库同城多副本;Kafka 多 AZ;ClickHouse 分片跨 AZ。RPO≈0,RTO 分钟级

  • 异地灾备(Active-Passive) : 生产 Region 全量,异地 异步 复制(TiCDC/Debezium→Kafka→下游)。写延迟最低,RPO 秒级

  • 异地多活(Active-Active)

    • 强一致多活 (跨区共识):写延迟受 RTT 影响,适合读多写少按业务键做就地写入(CockroachDB/TiDB 多区域表位置信策)。
    • 最终一致多活 (推荐 IoT):每区本地落库 + Kafka Mirror 做跨区汇聚,冲突用业务键/时间戳解决。写入延迟最低,但对一致性要求要"可最终一致"。

现在就能落地的小蓝图(按"均衡档")

  • 入口:Kafka(40 分区,acks=all,幂等生产者,压缩 lz4/zstd)
  • 事务库:TiDB(3 TiKV×N,按 20 分片规模起步;或 MySQL+Vitess 20 分片)
  • 缓存 :Redis Cluster(起 3--6 节点,1--2 分片;Key 设计含哈希标签 {deviceId}
  • 分析:ClickHouse(热 30 天:建议 4--6 分片×2 副本起步,分层存储)
  • CDC:TiCDC/Debezium → Kafka → ClickHouse/ES/缓存回填
  • 分区策略 :事务库按 device_id, ts 复合主键 + 按日/周分区 ;CH PARTITION BY toYYYYMMDD(ts) ORDER BY (device_id, ts) + TTL

目标拆解(两种常见场景)

  • 场景 A:1000 亿总数据量(长期沉淀) 例:IoT/日志/交易明细累计 1000 亿行。
  • 场景 B:超高吞吐(持续写入/查询) 例:峰值 20--200 万条/秒写入,实时查询。

下面给你可落地的架构与选型。

架构蓝图(通用且好落地)

  1. 入口层(写入解耦):Kafka / Pulsar(写入缓冲、削峰、重放、顺序性)
  2. 在线事务库(强一致、主业务):MySQL(分库分表/ Vitess) / PostgreSQL(Citus) / NewSQL(TiDB / CockroachDB / OceanBase)
  3. 热 Key/实时状态:Redis Cluster / Aerospike / Scylla(KV 毫秒级读写)
  4. 时序/明细分析:ClickHouse / Pinot / Druid(列式 + 分区,近实时 OLAP)
  5. 搜索:OpenSearch / Elasticsearch(全文检索、模糊查)
  6. CDC/数据流:Debezium/TiCDC → Kafka → ClickHouse(离线与实时打通)
  7. 冷存/归档:对象存储(S3/OSS/COS)+ 冷分区 TTL

核心思想:写入用日志(Kafka)解耦,OLTP 只做强一致交易,OLAP/时序做大吞吐分析,状态查询走 KV。CQRS + 分层存储。

怎么选数据库(一句话攻略)

  • 强一致交易

    • 小规模先 MySQL 单机 → 读写分离 → 分库分表 → VitessShardingSphere
    • 一步到位选 TiDB/CockroachDB/OceanBase(分布式事务、自动水平扩展)。
  • 超高写 & 时序/明细分析ClickHouse (MergeTree 家族)或 Pinot/Druid

  • 实时状态/排行榜/会话Redis Cluster(哈希槽、Pipeline、Lua 原子)。

  • 全文搜索OpenSearch/ES(注意写入背压、刷新间隔)。

  • KV 超大规模且持久化Aerospike/ScyllaDB(低延迟、可持久化)。

容量与分片估算(手把手)

  • 吞吐估算 : 假设 1000 万设备、每分钟 1 次上报 → 10,000,000 / 60 ≈ 166,666 次/秒 写入。
  • Kafka 分区数 (保守每分区 5k msg/s): 166,666 / 5,000 ≈ 34 分区(取 48/64 方便均衡)。
  • OLTP 分片数 (保守每分片 10k 写/s): 166,666 / 10,000 ≈ 17 分片(取 24),每分片主从复制。
  • 存储估算 : 1000 亿行 × 100B/行 ≈ 10 TB 原始 ;复制因子 3 → 30 TB ; 索引与额外列粗略 ×2 → ~60 TB(放在列式/对象存储更省)。

表设计与分区(示例)

OLTP(TiDB/MySQL + Vitess):按业务键 + 时间分库分表,避免热点。

sql 复制代码
-- 设备上报明细(事务库:写入 + 最近短期查询)
CREATE TABLE device_event_202508 (
  device_id    BIGINT NOT NULL,
  ts           DATETIME NOT NULL,
  evt_type     TINYINT NOT NULL,
  payload      JSON,
  PRIMARY KEY (device_id, ts)  -- 复合主键,利于范围查询
) PARTITION BY RANGE COLUMNS(ts) (
  PARTITION p20250801 VALUES LESS THAN ('2025-08-02'),
  PARTITION p20250802 VALUES LESS THAN ('2025-08-03'),
  -- 每日/每周分区,便于冷热分离与快速清理
);

时序/分析(ClickHouse):按天/周分区,排序键放查询维度。

sql 复制代码
CREATE TABLE events_local ON CLUSTER cluster_3r3s
(
  device_id  UInt64,
  ts         DateTime,
  evt_type   UInt8,
  v          Float64,
  payload    String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/events_local', '{replica}')
PARTITION BY toYYYYMMDD(ts)
ORDER BY (device_id, ts)
TTL ts + INTERVAL 180 DAY TO VOLUME 'cold';  -- 180 天后走冷存

Redis(热数据/状态)

  • Key 设计:dev:{deviceId}:stat,哈希结构;
  • 哈希标签{deviceId} 保证同一设备落同槽,降低跨槽多键操作;
  • 开启 Pipeline、合理 tcp-keepalive禁用大 Lua 脚本长阻塞。

写入链路与幂等

  1. 入口 → Kafkaacks=all,幂等生产者,开启压缩)

  2. 消费入库

    • OLTP:批量写 (500--1k 批),失败重试 + 幂等键(device_id+ts 或业务 id);
    • 分析:Kafka → ClickHouse Kafka 引擎 / 自研 Sink(大批量、列式友好)。
  3. CDC:OLTP 变更 → Debezium/TiCDC → Kafka → 下游(ES、ClickHouse、缓存回填)。

查询路径(QPS 高时要分层)

  • 强一致/交易查询 → OLTP(MySQL/TiDB)
  • 状态/排行榜/首页秒开 → Redis
  • 报表/聚合/多维分析 → ClickHouse/Pinot(Pre-Aggregation + 物化视图)
  • 搜索 → OpenSearch(定时/实时索引)

典型配置要点(踩坑少)

  • MySQL/InnoDBbinlog_format=ROWsync_binlog=1(强一致)、innodb_flush_log_at_trx_commit=1;分表用 Vitess/ShardingSphere 管理路由。
  • PostgreSQL :连接池 PgBouncer ,声明式分区,Citus 做分布式。
  • Kafkamin.insync.replicas=2(RF=3),保留策略基于时间/大小;消费者组 max.poll.records 控制批量。
  • ClickHouse :MergeTree 系列,max_partitions_per_insert_block 合理;写入尽量大批;冷热分层 + TTL。
  • Redis :Cluster,合理 hash-max-ziplist-entries 等小对象优化,不要在主线程做重型 Lua。
  • ES/OpenSearch :写入用大批量 Bulk,降低刷新频率(refresh_interval),映射固定字段类型,避免动态映射爆炸。

分阶段扩容路线图

  • Phase 0(< 每秒 2 万写):MySQL 主从 + Redis,ClickHouse 单集群小规模,Kafka 6--12 分区。
  • Phase 1(~10 万写/s):Vitess/TiDB/Citus 上线;Kafka 32--64 分区;ClickHouse 3--6 分片×3 副本;Redis Cluster 6--12 分片。
  • Phase 2(~20--50 万写/s) :多 Region 同城双活/两地三中心;跨 Region 采用异步复制 + 最终一致;ES/ClickHouse 做冷热分层与成本优化。
  • Phase 3(>50 万写/s & 1000 亿级总量) :OLTP 只保留近 7--30 天,长期落列式 + 对象存储;索引窄化;精细化限流与降级。

你现在就能用的最小闭环(结合你常用栈:Java + Kafka + Redis + MySQL)

  1. Kafka 入口(分区按 hash(deviceId)%Nacks=all,幂等生产者)
  2. MySQL → Vitess 或直接 TiDB 做事务与强一致
  3. Redis Cluster 做设备实时状态/首页
  4. ClickHouse 承接 Kafka 明细(近实时分析 + 报表)
  5. CDC(TiCDC/Debezium)把交易变更送到 Kafka,再同步到下游(ES/ClickHouse/缓存)
  6. 数据生命周期:OLTP 仅保留近数据,ClickHouse 分区 + TTL,冷数据上云存储

反模式(尽量别踩)

  • 试图用 一个数据库 同时搞事务 + 高并发写 + 大规模分析
  • 无分区的大表:删除/归档会把库打爆
  • 盲目 主从读扩 扛写入:写放大、复制延迟一来就炸
  • ES 当主库(事务一致性要求高的场景)
  • Redis 当数据库(需要强一致/持久就别这么干)
相关推荐
寻月隐君7 分钟前
Rust 实战:从零构建一个多线程 Web 服务器
后端·rust·github
草梅友仁1 小时前
草梅 Auth 1.3.0 发布与 GitHub 动态 | 2025 年第 32 周草梅周报
开源·github·ai编程
Livingbody1 小时前
FastMCP In Action之 Server详解
后端
GetcharZp2 小时前
C++ Boost 从入门到精通:让你的代码飞起来
c++·后端
北'辰2 小时前
DeepSeek智能考试系统智能体
前端·后端·架构·开源·github·deepseek
hrrrrb2 小时前
【Spring Boot 快速入门】八、登录认证(二)统一拦截
hive·spring boot·后端
在未来等你2 小时前
RabbitMQ面试精讲 Day 16:生产者优化策略与实践
中间件·面试·消息队列·rabbitmq
_風箏4 小时前
OpenSSH【安装 03】远程代码执行漏洞CVE-2024-6387修复(cp: 无法创建普通文件“/usr/sbin/sshd“:文本文件忙问题处理)
后端
用户89535603282204 小时前
Gin 框架核心架构解析
后端·go