- design-seckill.md: 秒杀系统设计 - design-shorturl.md: 短链接系统设计 - design-lbs.md: LBS附近的人系统设计 - design-im.md: 即时通讯系统设计 - design-feed.md: 社交信息流系统设计 Each document includes: - Requirements analysis and data volume assessment - Technical challenges - System architecture design - Database design - Caching strategies - Scalability considerations - Practical project experience - Alibaba P7 level additional points Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
14 KiB
14 KiB
短链接系统设计
需求分析和数据量评估
需求分析
- 核心功能:长链接转短链接、短链接跳转、统计分析
- 业务场景:短信营销、社交媒体分享、广告推广
- QPS评估:日点击量10亿次,峰值QPS 3万+
- 数据规模:短链接10亿+,日生成1000万+
数据量评估
- 短链接表:10亿条,日均写入1000万次
- 原始链接表:10亿条,日均读取10亿次
- 访问统计表:100亿+条,日增1亿+
- 用户表:1000万+,日均查询100万次
核心技术难点
1. 高并发写入
- 短链接生成需要高性能
- 避免数据库写入瓶颈
- 分布式ID生成
2. 高性能读取
- 毫秒级响应时间
- 缓存命中率优化
- 全球CDN加速
3. 长链接查重
- 重复链接检测
- 去重策略设计
- 一致性保证
4. 统计准确性
- 实时统计延迟
- 统计数据准确性
- 分布式计数器
系统架构设计
总体架构
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ CDN/Edge │ │ Load Balance │ │ API Gateway │
│ Cache │◄──►│ (Anycast) │◄──►│ (Gateway) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
┌───────────────────────────────────┼───────────────────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 短链接服务 │ │ 统计服务 │ │ 监控服务 │
│ (微服务) │ │ (微服务) │ │ (微服务) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────────────────┼───────────────────────────────────┘
│
┌───────────────────────────────────┼───────────────────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Redis集群 │ │ 消息队列 │ │ 数据库集群 │
│ (缓存+计数器)│ │ (Kafka) │ │ (MySQL分库分表)│
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
┌───────────────────────────────────┼───────────────────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 时序数据库 │ │ 数据仓库 │ │ 搜索引擎 │
│ (InfluxDB) │ │ (ClickHouse) │ │ (Elasticsearch)│
└─────────────────┘ └─────────────────┘ └─────────────────┘
关键组件
1. 流量层
- CDN/Edge:全球加速,缓存热点短链接
- 负载均衡:Anycast IP,就近接入
- API网关:限流、路由、认证
2. 服务层
- 短链接服务:核心业务逻辑
- 统计服务:访问统计和报表
- 管理服务:后台管理系统
- 监控服务:实时监控告警
3. 存储层
- Redis集群:缓存和计数器
- MySQL集群:主从复制,分库分表
- 时序数据库:时序数据存储
- 搜索引擎:链接检索和分析
4. 分析层
- 数据仓库:离线数据分析
- OLAP引擎:实时查询分析
- 报表系统:业务报表展示
数据库设计
短链接表
CREATE TABLE `short_url` (
`id` bigint NOT NULL AUTO_INCREMENT,
`short_code` varchar(10) NOT NULL COMMENT '短链接编码',
`long_url` text NOT NULL COMMENT '原始长链接',
`domain` varchar(255) NOT NULL COMMENT '自定义域名',
`title` varchar(255) DEFAULT NULL COMMENT '页面标题',
`description` text COMMENT '页面描述',
`keywords` varchar(500) DEFAULT NULL COMMENT '关键词',
`user_id` bigint DEFAULT NULL COMMENT '用户ID',
`is_custom` tinyint NOT NULL DEFAULT 0 COMMENT '是否自定义',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
`expire_at` datetime DEFAULT NULL COMMENT '过期时间',
`click_count` int NOT NULL DEFAULT 0 COMMENT '点击次数',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_short_code` (`short_code`),
KEY `idx_long_url` (`long_url`(255)),
KEY `idx_user_id` (`user_id`),
KEY `idx_expire_at` (`expire_at`),
KEY `idx_domain` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
访问记录表
CREATE TABLE `url_access_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`short_code` varchar(10) NOT NULL COMMENT '短链接编码',
`ip` varchar(45) NOT NULL COMMENT '访问IP',
`user_agent` text COMMENT '用户代理',
`referer` text COMMENT '来源页面',
`country` varchar(50) DEFAULT NULL COMMENT '国家',
`region` varchar(50) DEFAULT NULL COMMENT '地区',
`city` varchar(50) DEFAULT NULL COMMENT '城市',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_short_code` (`short_code`),
KEY `idx_created_at` (`created_at`),
KEY `idx_ip` (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
统计表
CREATE TABLE `url_stats` (
`id` bigint NOT NULL AUTO_INCREMENT,
`short_code` varchar(10) NOT NULL COMMENT '短链接编码',
`date` date NOT NULL COMMENT '统计日期',
`total_clicks` int NOT NULL DEFAULT 0 COMMENT '总点击次数',
`unique_clicks` int NOT NULL DEFAULT 0 COMMENT '独立点击次数',
`by_country` json DEFAULT NULL COMMENT '国家分布',
`by_region` json DEFAULT NULL COMMENT '地区分布',
`by_device` json DEFAULT NULL COMMENT '设备分布',
`by_browser` json DEFAULT NULL COMMENT '浏览器分布',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_date_code` (`date`, `short_code`),
KEY `idx_short_code` (`short_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
用户表
CREATE TABLE `short_url_user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT '用户ID',
`username` varchar(50) NOT NULL COMMENT '用户名',
`email` varchar(100) NOT NULL COMMENT '邮箱',
`domain` varchar(255) DEFAULT NULL COMMENT '自定义域名',
`api_key` varchar(64) DEFAULT NULL COMMENT 'API密钥',
`quota` int NOT NULL DEFAULT 1000 COMMENT '配额',
`used` int NOT NULL DEFAULT 0 COMMENT '已使用',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`),
UNIQUE KEY `uk_api_key` (`api_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
缓存策略
Redis缓存设计
// 短链接缓存
const SHORT_URL_CACHE_PREFIX = 'short_url:';
const SHORT_URL_CACHE_TTL = 86400; // 24小时
// 访问计数器
const CLICK_COUNT_PREFIX = 'click:';
const CLICK_COUNT_TTL = 60; // 1分钟
// 布隆过滤器
const BLOOM_FILTER_PREFIX = 'bloom:';
const BLOOM_FILTER_SIZE = 1000000000; // 10亿
// 限流计数器
const RATE_LIMIT_PREFIX = 'rate_limit:';
const RATE_LIMIT_TTL = 60; // 1分钟
缓存策略
-
多级缓存:
- 本地缓存:Caffeine
- 分布式缓存:Redis Cluster
- CDN缓存:边缘节点
-
缓存更新策略:
- Write Through:写入同时更新缓存
- Write Back:异步更新缓存
- Refresh Ahead:预加载热点数据
-
缓存预热:
- 热门短链接预加载
- 统计数据预计算
- 静态资源预缓存
布隆过滤器实现
public class BloomFilter {
private final BitSet bitSet;
private final int size;
private final int[] hashSeeds;
public BloomFilter(int size, int hashCount) {
this.size = size;
this.bitSet = new BitSet(size);
this.hashSeeds = new int[hashCount];
Random random = new Random();
for (int i = 0; i < hashCount; i++) {
hashSeeds[i] = random.nextInt();
}
}
public void add(String key) {
for (int seed : hashSeeds) {
int hash = Math.abs((key.hashCode() ^ seed) % size);
bitSet.set(hash, true);
}
}
public boolean mightContain(String key) {
for (int seed : hashSeeds) {
int hash = Math.abs((key.hashCode() ^ seed) % size);
if (!bitSet.get(hash)) {
return false;
}
}
return true;
}
}
扩展性考虑
1. 水平扩展
- 无状态服务:短链接服务无状态化
- 数据分片:按短链接编码分片
- 读写分离:主库写入,从库读取
2. 垂直扩展
- 服务拆分:API服务、统计服务、管理服务
- 数据分层:热数据、温数据、冷数据
- 多级缓存:本地、Redis、CDN
3. 全球化部署
- CDN加速:全球节点部署
- 地域化存储:按地域分片
- 灾备切换:多机房容灾
4. 监控告警
- 实时监控:QPS、响应时间、错误率
- 业务监控:点击量、转化率
- 异常告警:服务异常、数据异常
实际项目经验
1. 技术栈选择
- 前端:React + TypeScript
- 后端:Spring Boot + Node.js
- 数据库:MySQL + Redis
- 缓存:Redis Cluster
- 消息队列:Kafka
- 监控:Prometheus + Grafana
2. 性能优化
- 短链接生成:Snowflake算法
- 缓存优化:多级缓存策略
- 数据库优化:分库分表、索引优化
- 网络优化:HTTP/2、Keep-Alive
3. 运维部署
- 容器化:Docker + Kubernetes
- CI/CD:Jenkins + GitLab
- 监控告警:ELK Stack + AlertManager
- 压测:JMeter + Locust
4. 安全设计
- HTTPS:全链路加密
- API限流:防刷、防攻击
- 数据脱敏:敏感信息加密
- 访问控制:API密钥认证
阿里P7加分项
1. 架构设计能力
- 高可用架构:99.99%可用性
- 高性能架构:支持亿级QPS
- 全球化架构:全球CDN加速
2. 技术深度
- 分布式算法:一致性哈希、布隆过滤器
- 缓存优化:多级缓存策略
- 数据库优化:分库分表、读写分离
3. 业务理解
- 营销业务:理解短链接在营销中的应用
- 用户行为:分析点击行为模式
- 数据统计:实时统计和离线分析
4. 团队管理
- 技术团队:带领15人+团队
- 项目管控:管理亿级用户项目
- 技术方案:主导技术架构设计
5. 前沿技术
- Serverless:短链接函数化
- 边缘计算:边缘节点处理
- AI应用:智能推荐、异常检测
面试常见问题
1. 短链接如何生成?
- 随机字符:生成随机字符串
- 自增序列:数据库自增ID
- 哈希算法:MD5/SHA1取前几位
- Base62编码:数字转62进制
2. 如何避免短链接冲突?
- 布隆过滤器:快速检测重复
- 数据库唯一索引:保证唯一性
- 重试机制:冲突时重新生成
3. 如何实现高并发生成?
- 预生成:批量生成短链接
- 分布式ID:Snowflake算法
- 内存缓存:减少数据库访问
4. 如何统计点击数据?
- 实时统计:Redis计数器
- 异步处理:消息队列存储
- 离线分析:数据仓库计算
5. 如何保证短链接安全?
- 链接过滤:过滤恶意链接
- 访问控制:黑白名单
- HTTPS加密:防止劫持
- IP限制:防刷机制