短网址系统设计总结

需求评估

  • 输入数据:一个长网址、过期时间和一个自定义的别名
  • 输出数据:自定义别名或者随机生成的短网址,过期时间之前访问都会被重定向到原始地址。
  • 读多写少

实现原理:将短网址redirect到长网址(301/302跳转)

约束:

  • 过期即失效
  • 短网址唯一
  • 支持自定义短网址
  • QPS要求、低延迟、可靠性、安全性

系统设计

可行解

    1. 输入长域名,判断是否存在
    2. 生成一个未使用的短网址,并进行持久化
    1. 获取短网址,判断是否过期
    2. 正常则返回短网址

其他方面:

  • 使用延迟删除策略清理过期数据
  • 读时消重:返回的时候过滤重复元素
  • 写时消重:写时判断以避免重复写入
  • 短网址生成算法:
    • UUID:无法保证唯一性
    • 哈希:MurMurHash等方法,无法保证唯一性,考虑转为62进制
    • ID:使用7位62进制,即长度为7,由大小写字母加数字共62个字符组成
    • 雪花算法:转为62进制
  • 用户自定义:记录正在使用的ID,写入时判断是否存在

MySQL表结构如下:

id long_url short_url expire_time create_time delete_time

Redis键值设计:

k:长网址, v:短网址

吞吐量优化

  • 水平扩展:使用Nginx做负载均衡
  • 存储层:MySQL替换为持久化KV存储,比如RocksDB,若存在数据分析的需求,可以添加数仓
  • 索引优化:两个方面
    1. 写入时判需要判断长网址是否存在
    2. 读取时根据短网址查询长网址
  • 分片:短网址进行一致性哈希等方式计算分片位置。
  • 缓存层读多写少的系统使用缓存优化QPS
    • 使用bloom filter检查长网址是否存储,短网址是否分配
    • 直接在本地设计缓存
  • 业务层
    • 分布式ID生成需要考虑数据一致性问题
  • 网络层:降低广域延迟

可靠性优化

  • 存储层:考虑主从副本机制,增加数据可靠性
  • 提供跨机房的数据冗余备份,通过log同步数据
  • 监控业务集群,实现熔断、限流、扩容缩容等

安全性优化

  • 避免使用自增,防止逐个遍历
  • 防止DDos,对接口做限流,增加IP黑名单机制