短链接跳转(缓存穿透)
短链接跳转(缓存穿透)
penjc短链接跳转(缓存穿透)
功能概述
短链接跳转功能通过优化缓存策略,结合布隆过滤器、空值缓存和分布式锁,有效解决 缓存穿透 和 缓存击穿 问题。在高并发场景下确保系统的稳定性和性能。
功能流程
生成完整短链接 URL
- 根据请求的
shortUri
和serverName
拼接生成完整短链接 URL(fullShortUrl
)。
- 根据请求的
查询缓存
- 在 Redis 缓存中检查短链接是否存在。
- 若存在,直接返回原始链接进行重定向。
布隆过滤器校验
- 通过布隆过滤器快速判断短链接是否有效。
- 若不存在,直接返回无效状态,避免访问数据库。
查询空值缓存
- 检查 Redis 是否已缓存空值(标记无效短链接)。
- 若已缓存空值,直接返回无效状态,避免重复查询。
处理缓存击穿
- 若缓存和布隆过滤器均未命中,使用分布式锁(如 Redisson)防止并发查询。
- 获取锁后,再次检查缓存是否已更新。
查询数据库
- 在数据库中查询完整短链接的原始链接,并验证其状态(如未删除、已启用)。
- 若查询成功,将结果写入缓存并返回。
- 若查询失败,缓存空值,减少无效查询。
释放锁
- 无论查询成功或失败,均释放分布式锁,避免资源浪费。
缓存穿透与缓存击穿的解决方案
缓存穿透
- 问题:查询不存在的短链接,每次都穿透缓存,直接访问数据库。
- 解决方案:
- 使用布隆过滤器快速判断短链接是否存在。
- 对无效短链接缓存空值并设置过期时间,避免重复查询。
缓存击穿
- 问题:热点数据缓存失效导致大量并发请求直接访问数据库。
- 解决方案:
- 使用分布式锁(如 Redisson)控制并发查询,防止重复访问数据库。
- 重新加载热点数据到缓存,保证后续请求直接命中缓存。
关键代码逻辑
生成完整短链接
1 | String serverName = request.getServerName(); |
查询缓存
1 | String originalLink = stringRedisTemplate.opsForValue().get(String.format(GOTO_SHORT_LINK_KEY, fullShortUrl)); |
布隆过滤器校验
1 | boolean contains = shortUriCreateCachePenetrationBloomFilter.contains(fullShortUrl); |
查询空值缓存
1 | String gotoIsNullShortLink = stringRedisTemplate.opsForValue().get(String.format(GOTO_SHORT_IS_NULL_LINK_KEY, fullShortUrl)); |
分布式锁防止缓存击穿
1 | RLock lock = redissonClient.getLock(String.format("LOCK_GOTO_SHORT_LINK_KEY", fullShortUrl)); |
查询数据库
1 | LambdaQueryWrapper<ShortLinkDO> queryWrapper = Wrappers.lambdaQuery(ShortLinkDO.class) |
优点
高效缓存策略
- 使用 Redis 加速短链接跳转。
- 空值缓存减少无效数据库查询。
防止缓存穿透
- 使用布隆过滤器避免无效查询。
- 缓存空值,减少重复查询。
防止缓存击穿
- 分布式锁控制并发查询,避免缓存失效对数据库的冲击。
高并发支持
- 结合 Redis 和 Redisson 提供高并发性能支持。
示例
有效短链接跳转
- 输入短链接:
http://shortlink.com/abc123
- 重定向到原始链接:
http://example.com/page
无效短链接处理
- 输入短链接:
http://shortlink.com/invalid
- 布隆过滤器判定不存在,或缓存空值直接返回无效状态。
总结
通过 布隆过滤器、空值缓存 和 分布式锁 的组合,系统有效解决了缓存穿透与缓存击穿问题,确保短链接跳转功能在高并发场景下的稳定性和性能,特别适用于大规模短链接服务。
评论
匿名评论
✅ 你无需删除空行,直接评论以获取最佳展示效果