分布式微服务系统架构第172集:Kafka、MongoDB、Redis、MySQL

加群联系作者vx:xiaoda0423

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

https://1024bat.cn/

https://github.com/webVueBlog/fastapi_plus

https://webvueblog.github.io/JavaPlusDoc/

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

物联网(IoT,Internet of Things)产品的实现原理,其核心是**"感知 → 传输 → 处理 → 应用"**四个环节。可以分解为以下几个层次:


1. 感知层(设备端)

  • 作用:让物理世界中的设备"能感知"。

  • 技术原理

    • 传感器:采集环境数据(温度、湿度、位置、加速度、图像、声音等)。

    • 执行器:接收控制指令并作用于物理世界(开关电机、点亮灯光、调节阀门)。

    • 嵌入式系统:通常用单片机、ARM 芯片或模组(如 ESP32、STM32、瑞芯微、展锐等)运行轻量化固件,负责数据采集与初步处理。


2. 网络层(通信传输)

  • 作用:让设备"能联网"。

  • 通信方式

    • 短距离:Wi-Fi、Bluetooth、ZigBee、LoRa、NFC。

    • 广域网:4G/5G、NB-IoT、LTE-M、卫星通信。

    • 协议栈:MQTT、CoAP、HTTP/HTTPS、Modbus 等。

  • 网关角色:部分 IoT 产品使用网关(例如智能家居网关)来统一接入不同协议的设备,并转发到云端。


3. 平台层(云端/边缘端处理)

  • 作用:让数据"能计算"。

  • 实现原理

    • 数据接入:IoT 平台(阿里云 IoT、华为 IoT Core、自建 MQTT Broker)接收设备上报的数据。

    • 数据处理:通过流处理、大数据分析、规则引擎进行实时计算。

    • 存储:使用时序数据库(如 InfluxDB、TimescaleDB)、大数据平台(HDFS、ClickHouse)存储历史数据。

    • 边缘计算:在靠近设备的边缘服务器预处理数据,降低延迟与流量压力。


4. 应用层(用户与业务)

  • 作用:让数据"能服务"。

  • 表现形式

    • 可视化:通过 App、小程序、Web 平台展示设备状态、历史趋势、告警。

    • 控制:远程下发指令(如开关空调、调整灯光、远程升级固件 OTA)。

    • 智能化:结合 AI/大数据进行预测与自动化控制(如电动车电池换电调度、智慧城市红绿灯控制)。


5. 安全与运维(横向支撑)

  • 安全机制

    • 数据加密(TLS/DTLS、AES)、身份认证(JWT、证书)、访问控制。
  • 设备运维

    • OTA 升级(远程固件更新)、日志监控、异常检测、自动恢复。

一句话总结

物联网产品通过 传感器采集数据 → 网络上传输 → 平台处理分析 → 应用层呈现与控制,实现了"物理世界数字化 + 数字世界反向控制物理世界"的闭环。


一、拓扑与主机规格(按环境分层)

环境 Kafka MongoDB Redis MySQL 建议主机
Dev/测试 1 节点(KRaft 单点) 单机(非副本集) 单机 单机 1 台 8C/16G/200G SSD
Staging 3 Broker(KRaft) 3 节点副本集(PSA) 3 主 + 3 从(Sentinel 3) 主从 1+1(或 MGR 3) 5--7 台 8--16C/32G/本地 SSD
Prod 3--5 Broker(KRaft) 3 节点副本集(PSA) 3 主 + 3 从(Sentinel 3)或 Redis Cluster 6 节点 MySQL 主从 1+1 或 MGR 3--5 各集群独立;Kafka/Mongo 强烈建议用本地 NVMe SSD;万兆网

磁盘:Kafka/Mongo/MySQL 一律 NVMe SSD、本地盘 ;Redis 优先内存,但 AOF/RDB 在本地 SSD。

网络:万兆(或 ≥5 Gbps)+ 独立业务网段;Broker/DB 间低延迟尤为关键。

容器化:生产建议 Kubernetes ;最简先上 docker-compose 验证。


二、Linux 通用与 I/O 调优(所有节点)

内核 & ulimit(/etc/security/limits.d/99-sys.conf):

go 复制代码
* soft nofile 1048576
* hard nofile 1048576
* soft nproc  1048576
* hard nproc  1048576
root soft core unlimited

sysctl(/etc/sysctl.d/99-sys.conf):

go 复制代码
vm.swappiness=1
vm.max_map_count=262144
vm.dirty_ratio=10
vm.dirty_background_ratio=5
fs.file-max=2097152
net.core.somaxconn=65535
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=15
net.ipv4.ip_local_port_range=1024 65000

生效:sysctl --system

THP & NUMA(Mongo/Redis 节点强烈建议):

go 复制代码
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

挂载建议:

  • 数据盘 ext4/xfs,挂载时加 noatime,nodiratime

  • 独立分区:/var/lib/kafka/var/lib/mongo/var/lib/mysql/var/lib/redis

时钟与时区:

go 复制代码
timedatectl set-ntp true
timedatectl set-timezone Asia/Singapore

安全与网络:

  • 最小化安全组端口:

    • Kafka:外部客户端 9092(或你的外部端口),控制器内部 9093(内网)。

    • Mongo:27017 内网放行。

    • Redis:6379 内网放行;Sentinel 26379 内网放行。

    • MySQL:3306 内网放行。

  • 必开 TLS/密码;生产禁公网直连数据库与 Redis。


三、各中间件要点配置

1) Kafka(KRaft 模式,建议 3--5 Broker)

目录:/etc/kafka/,数据:/var/lib/kafka

server.properties(每个 broker 都要,ID/监听地址不同):

go 复制代码
process.roles=broker,controller
node.id=1
controller.quorum.voters=1@kafka-1:9093,2@kafka-2:9093,3@kafka-3:9093

listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
advertised.listeners=PLAINTEXT://<broker内网IP或域名>:9092
inter.broker.listener.name=PLAINTEXT
controller.listener.names=CONTROLLER

log.dirs=/var/lib/kafka/logs
num.network.threads=8
num.io.threads=16
socket.send.buffer.bytes=1048576
socket.receive.buffer.bytes=1048576
socket.request.max.bytes=104857600

# 生产建议
num.partitions=6
default.replication.factor=3
min.insync.replicas=2
unclean.leader.election.enable=false
log.retention.hours=168
log.segment.bytes=1073741824
log.cleanup.policy=delete

首次格式化 KRaft 元数据(仅一次):

go 复制代码
KAFKA_CLUSTER_ID=$(kafka-storage.sh random-uuid)
kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c /etc/kafka/server.properties

随后 systemd 或容器启动每个 broker 即可。

生产补充:

  • 建专用 内网域名advertised.listeners;避免客户端连公网。

  • 跨机房/多集群用 MirrorMaker2 做容灾同步。

  • 监控:kafka_exporter + Prometheus + Grafana。


2) MongoDB(3 节点副本集)

目录:/etc/mongod.conf,数据:/var/lib/mongo

mongod.conf(每节点相同,只是 bindIP/hostname 不同):

go 复制代码
storage:
  dbPath: /var/lib/mongo
  wiredTiger:
    engineConfig:
      cacheSizeGB: 8           # 约为内存的 30--50%
systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  logAppend: true
net:
  port: 27017
  bindIp: 0.0.0.0
replication:
  replSetName: rs0
security:
  authorization: enabled
processManagement:
  fork: false

初始化副本集(在任一节点 mongo shell 执行):

go 复制代码
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo-1:27017", priority: 2 },
    { _id: 1, host: "mongo-2:27017", priority: 1 },
    { _id: 2, host: "mongo-3:27017", priority: 0, arbiterOnly: false }
  ]
})

生产补充:

  • 关闭 THP、设置 vm.swappiness=1

  • 独立磁盘,预留充足 IOPS。

  • 备份:mongodump快照 ;重要业务建议用 物理快照 + Oplog


3) Redis(Sentinel 或 Cluster)

方案 A:Sentinel(3 个 Sentinel,主从 1+1 起步)

redis.conf(master/slave 类似):

go 复制代码
port 6379
bind 0.0.0.0
protected-mode yes
requirepass <STRONG_PASSWORD>
masterauth <STRONG_PASSWORD>
appendonly yes
appendfsync everysec
save 900 1
save 300 10
save 60 10000
maxmemory <按节点内存设置,如 24gb>
maxmemory-policy volatile-lru

sentinel.conf(3 台各一份):

go 复制代码
port 26379
bind 0.0.0.0
sentinel monitor mymaster <master-host> 6379 2
sentinel auth-pass mymaster <STRONG_PASSWORD>
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000

方案 B:Redis Cluster(3 主 3 从,适合大容量/横向扩展)

  • redis-cli --cluster create ... 初始化;

  • 注意 持久化 + 自动故障切换 配合业务一致性。

生产补充:

  • 尽量 公网暴露;只对内网放行。

  • 监控:redis_exporter

  • 大 key、热 key、慢查询追踪要开启。


4) MySQL(8.0+,主从或 MGR)

目录:/etc/my.cnf,数据:/var/lib/mysql

my.cnf(生产最小集):

go 复制代码
[mysqld]
user=mysql
bind-address=0.0.0.0
server_id=1                 # 每节点唯一
gtid_mode=ON
enforce_gtid_consistency=ON
log_bin=/var/lib/mysql/mysql-bin
binlog_format=ROW
binlog_expire_logs_seconds=604800

# InnoDB
innodb_buffer_pool_size=24G # 约内存60--70%
innodb_log_file_size=2G
innodb_flush_log_at_trx_commit=1
innodb_flush_method=O_DIRECT
innodb_io_capacity=2000

# 连接
max_connections=2000
table_open_cache=4000
open_files_limit=1000000

# 字符集
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

# 其他
sql_mode=STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

主从快速搭建(概要):

  1. 主库创建复制账号:

    go 复制代码
    CREATE USER 'repl'@'%' IDENTIFIED BY 'REPL_P@ss!';
    GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
    FLUSH PRIVILEGES;
  2. 从库执行:

    go 复制代码
    CHANGE REPLICATION SOURCE TO
      SOURCE_HOST='mysql-master', SOURCE_PORT=3306,
      SOURCE_USER='repl', SOURCE_PASSWORD='REPL_P@ss!',
      SOURCE_AUTO_POSITION=1;
    START REPLICA;
    SHOW REPLICA STATUS\G

生产补充:

  • 强烈建议 MGR(Group Replication) 做多主/单主高可用。

  • 备份:xtrabackup(热备)+ binlog;做 定期恢复演练

  • 监控:mysqld_exporter + 慢日志 + Performance Schema。


四、容器化快速起步(单机 docker-compose 验证)

适合在一台 8C/16G/200G SSD 机器验证联通性,生产再上 K8s。

go 复制代码
version: "3.8"
services:
# Kafka (KRaft 单机,仅供联调)
  kafka:
    image: bitnami/kafka:latest
    ports: ["9092:9092"]
    environment:
      - KAFKA_CFG_PROCESS_ROLES=broker,controller
      - KAFKA_CFG_NODE_ID=1
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka:9093
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=PLAINTEXT
      - ALLOW_PLAINTEXT_LISTENER=yes
    volumes:
      - ./data/kafka:/bitnami/kafka
    restart: unless-stopped

  mongo:
    image: mongo:7
    command: ["--bind_ip_all"]
    ports: ["27017:27017"]
    volumes:
      - ./data/mongo:/data/db
    restart: unless-stopped

  redis:
    image: redis:7
    command: ["redis-server","--appendonly","yes","--requirepass","redisP@ss!"]
    ports: ["6379:6379"]
    volumes:
      - ./data/redis:/data
    restart: unless-stopped

  mysql:
    image: mysql:8
    environment:
      - MYSQL_ROOT_PASSWORD=RootP@ss!
      - MYSQL_DATABASE=appdb
    command: ["mysqld","--default-authentication-plugin=mysql_native_password"]
    ports: ["3306:3306"]
    volumes:
      - ./data/mysql:/var/lib/mysql
    restart: unless-stopped

备注:仅用于联调 。生产务必启用 TLS、内网域名、密码保管(KMS/Secrets) ,并将 Kafka 拆成 3+ 节点,Mongo 副本集,Redis Sentinel/Cluster,MySQL 主从/MGR。


五、备份与巡检

  • Kafka :以主题/分区为维度做保留策略(log.retention.hours),跨集群用 MirrorMaker2 做异地复制。

  • MongoDBmongodump + 定期快照(或卷快照);保留 oplog 满足增量恢复。

  • Redis:AOF+RDB 均启用,AOF 重写窗口在业务低峰;主从切换演练。

  • MySQLxtrabackup 热备 + binlog 增量;周度 恢复演练

  • 监控:Prometheus + Grafana + Exporters(kafka/mongo/redis/mysql/node)+ 告警通道。

  • 日志:集中化(Loki/ELK),至少保 7--14 天。


六、你可以立刻执行的小清单

  1. 先在一台测试机用上面的 docker-compose 验证四件套连通。

  2. 按"二、Linux 调优"在目标节点批量设置 limitssysctl

  3. 生产环境:按"三"用 3 台 Kafka、3 台 Mongo、6 台 Redis(3+3)、2--3 台 MySQL 起集群。

  4. Prometheus + Grafana,接入各 exporters。

  5. 配置 自动备份恢复演练(脚本 + 日历排期)。


相关推荐
调皮的木木3 小时前
架构师成长之路 04:缓存进阶避坑:Value 存储防污染、数据同步最优方案,再也不怕宕机拖垮 DB
redis·缓存·系统架构
间彧4 小时前
Redis分布式锁过期时间如何设置
redis
Dobby_054 小时前
【Hadoop】ZooKeeper:分布式系统的协调核心与一致性保障
大数据·hadoop·分布式·zookeeper
十八旬4 小时前
苍穹外卖项目实战(day11-1)-记录实战教程、问题的解决方法以及完整代码
服务器·数据库·windows·redis
掘金-我是哪吒4 小时前
分布式微服务系统架构第174集:kafka硬件配置
分布式·微服务·架构·kafka·系统架构
间彧4 小时前
好用的redis可视化管理工具
redis
权^5 小时前
Hadoop 保姆级搭建手册:突出教程的细致和易上手
大数据·hadoop·分布式
赴前尘5 小时前
kafka 2.12_3.9.1 版本修复 Apache Commons BeanUtils 访问控制错误漏洞(CVE-2025-48734)
分布式·kafka·apache
haveyb5 小时前
10分钟快速部署PHP+Nginx+MySQL+Redis开发环境
redis·mysql·nginx·docker·php