Skip to content

设计一个短链系统, 每日写入量百万,访问量千万 ,要求通过短链找到长链 10ms内,同时不能重复插入长链

设计一个短链系统,使用 Redis 作为缓存 提供高性能读写,数据库(如 MySQL)持久化存储,结合 分布式 ID 生成器Base62 编码 生成唯一短链。核心思路:短链映射长链通过键值对存储,Redis 保证低延迟查询,数据库加唯一索引防止重复插入。

关键需求与解决方案

  1. 性能要求
    • 每日写入量百万:约 11.6 次/秒,需高效写入。
    • 访问量千万:约 115 次/秒,需低延迟查询。
    • 10ms 内响应:Redis 单线程 O(1) 查询满足需求。
  2. 功能要求
    • 短链找长链:键值映射,短链为 key,长链为 value。
    • 不重复插入长链:数据库唯一索引 + Redis 查重。

系统设计

1. 架构组件

  • 客户端:用户提交长链或访问短链。
  • 应用服务:短链生成与查询逻辑(Java/Spring)。
  • Redis:缓存短链-长链映射,高频读写。
  • MySQL:持久化存储,防数据丢失。
  • ID 生成器:分布式唯一 ID(如雪花算法)。

2. 数据结构

  • Redis
    • Key:短链(如 abc123)。
    • Value:长链(如 https://example.com/...)。
  • MySQL
    • 表:short_url。
      • id:自增主键。
      • short_url:短链(唯一索引)。
      • long_url:长链(唯一索引)。
      • create_time:创建时间。

3. 核心流程

生成短链
  1. 接收长链:用户提交 https://example.com/...。
  2. 查重
    • 在 MySQL 查询 long_url,若存在,返回已有短链。
    • Redis 加布隆过滤器(可选),快速排除不存在的长链。
  3. 生成短链
    • 用雪花算法生成唯一 ID(如 64 位)。
    • ID 转为 Base62(0-9, a-z, A-Z),缩短长度(如 abc123)。
  4. 存储
    • 插入 MySQL(short_url=abc123, long_url=...),唯一索引防重复。
    • 同步写 Redis(SET abc123 "https://...")。
  5. 返回:短链 http://short.com/abc123。
查询长链
  1. 接收短链:用户访问 http://short.com/abc123。
  2. 查询 Redis
    • GET abc123,O(1) 操作,<1ms。
    • 若命中,返回长链。
  3. 回查 MySQL
    • 若 Redis 未命中,查 MySQL,加载到 Redis 并返回。
  4. 跳转:重定向到长链。

4. 性能优化

  • Redis 集群:分片存储,应对千万访问。
  • 异步写入:生成短链后,异步同步 MySQL,降低写入延迟。
  • 缓存预热:高频短链预加载到 Redis。
  • TTL:短链设过期时间(如 30 天),自动清理。

满足需求验证

  1. 写入量(百万/天)
    • Redis 写 QPS 可达万级,11.6 次/秒轻松支持。
    • MySQL 异步写入,单表支持百万级数据。
  2. 访问量(千万/天)
    • Redis 查询 <1ms,集群支持 115 次/秒以上。
    • 10ms 内响应有余。
  3. 不重复插入
    • MySQL long_url 唯一索引,插入冲突抛异常。
    • Redis 查重提前拦截。

延伸与面试角度

  • 扩展性
    • 分布式部署:多节点服务 + Redis 集群,应对更高流量。
    • 短链长度:Base62 可调进制,ID 空间支持亿级。
  • 一致性
    • Redis 宕机回查 MySQL,保证数据不丢。
    • 异步写加重试,确保 MySQL 最终一致。
  • 高可用
    • Redis 主从 + 哨兵,MySQL 主从复制。
  • 冲突处理
    • 雪花算法保证 ID 唯一,数据库索引防长链重复。
  • 优化点
    • 布隆过滤器减少无效查重。
    • CDN 加速短链跳转。

总结

短链系统用 Redis 提供高性能读写,MySQL 持久化存储,雪花算法 + Base62 生成唯一短链。Redis 查 <1ms 满足 10ms 要求,数据库唯一索引防重复。每日百万写、千万访轻松支持。面试时,可画架构图或强调 Redis 性能,展示设计能力。