
一、情景描述
本系统用于每天约 1000 万条信息数据的实时采集、匹配与归档。目标是根据账号和大区管理员的关键词设置,将信息归档到各自对应的索引中,并保证高性能和可扩展性。
主要功能
账号级信息归档
- 根据账号设置的关键词匹配相关信息。
- 将匹配到的信息存储到账号专属索引(weekIndex)。
- weekIndex 仅保存一周数据。
大区管理员信息汇总
- 收集相关账号下的文章。
- 匹配大区管理员设置的关键词。
- 符合规则的数据进入大区管理员索引。
二、核心流程设计
1️⃣ 账号信息匹配与存储
技术说明:
- ES 索引按周滚动,保证单索引数据量可控。
- MQ 消息只包含必要字段:文章 ID、账号 ID、匹配关键词等。
2️⃣ 大区管理员同步处理
步骤如下:
步骤 A:拉取 MQ 消息
大区管理员同步脚本拉取 MQ 消息,每条消息代表一篇文章(article_id)。
步骤 B:判断是否已处理
使用 Redis 去重,防止重复处理:
- ZSET: article:processed
- member = article_id
- score = timestamp
- 如果 Redis 中已存在,跳过;否则继续处理。
步骤 C:匹配大区管理员规则
步骤 D:存储关联关系
- 表结构示例:
- article_id
- user_id
- subject_id
- keyword
- create_time
- Redis::zAdd('article:dirty', time(), $article_id);
- member = article_id,score = 时间戳
- 用于定时任务批量更新 ES。
3️⃣ 定时任务 Scheduler
单进程处理流程:
- $articles = Redis::zPopMin('article:dirty', 100);
多进程优化方案:
三、系统特点与优化
| 高并发写入 | MySQL 只 append,避免 UPDATE/DELETE,支持高吞吐。 |
| ES 更新可控 | Redis ZSET + Scheduler 批量更新,避免热点更新。 |
| 多进程扩展 | MQ + Worker 模式,可水平扩展 ES 更新任务。 |
| 数据一致性 | MySQL 为事实源,Redis 仅做任务标记,保证任务可靠。 |
| 热点文章处理 | ZSET 使用 zPopMin 原子取出,新消息可重新入队,不丢失。 |
| 资源可控 | account weekIndex 按周滚动,大区索引可按时间/ID分片。 |
四、技术栈
- 数据存储:Elasticsearch(索引按周/分片)
- 缓存与去重:Redis ZSET(任务队列、去重)
- 消息队列:RabbitMQ/Kafka(文章更新、Worker 分发)
- 关系存储:MySQL(文章-用户-专题关联表)
- 开发语言:PHP(Webman 框架 + 多进程 Worker)
💡 总结
- MQ → MySQL → Redis → Scheduler → ES 的架构清晰可靠。
- Redis ZSET 和 MQ 联合使用,保证多进程安全和数据不丢失。
- MySQL 作为真实数据源,Worker 聚合 ES 时实时读取,确保信息最新。
- 支持未来数据量增长,通过批量处理和 Worker 扩展轻松应对。





