网站首页 > java教程 正文
凌晨3点26分,你的手机突然炸了——
10亿次请求正在冲击服务器,CPU飙到100%!
更可怕的是:老板问你:"到底是哪个IP在攻击我们?"
如果支支吾吾答不上来,明天就可以收拾工位了…
别慌!今天我们用Redis+Java代码,彻底解决这个亿级数据下的"最热IP统计"难题!
▎01 方案对比:Redis五种统计方案谁最强?
(实测数据来自4核8G云服务器,10亿UV统计场景)
真实案例:某社交APP用Hash方案统计UV,服务器每天凌晨准时崩溃,改用HLL后成本直降99%
▎02 终极方案:RedisBloom TopK(压测代码)
Redis的Bloom模块提供了精确的TopK统计,原理如下:
Java实现代码(SpringBoot版):
@RestController
public class TopIPController {
@Resource
private RedisTemplate<String, String> redisTemplate;
// 统计IP访问
@PostMapping("/visit")
public void recordVisit(@RequestParam String ip) {
redisTemplate.opsForValue()
.setBit("ip_bitmap:" + ip, 1, true); // 用Bitmap去重
redisTemplate.opsForZSet()
.incrementScore("ip_rank", ip, 1); // ZSet计数
}
// 获取Top10 IP
@GetMapping("/top10")
public List<String> getTop10IP() {
return redisTemplate.opsForZSet()
.reverseRange("ip_rank", 0, 9);
}
// 使用BloomFilter版TopK(需Redis 5.0+)
public void initTopK() {
redisTemplate.execute((RedisCallback<Object>) connection -> {
connection.execute("TOPK.RESERVE", "ip_topk".getBytes(),
"10".getBytes(), // 保留Top10
"10000".getBytes(), // 计数器数量
"0.01".getBytes()); // 误差率1%
return null;
});
}
}
性能实测(10亿IP场景):
▎03 分片优化:百亿级数据的处理技巧
如果数据量超过单机Redis容量,就要用分片方案:
Java分片代码示例:
// 根据IP的CRC16分片
public int getShard(String ip) {
int slot = CRC16.crc16(ip.getBytes()) % 16384;
return slot / 5461; // 假设分3片
}
// 分片统计
public void shardedRecord(String ip) {
int shard = getShard(ip);
redisTemplates.get(shard).opsForZSet()
.incrementScore("ip_rank", ip, 1);
}
分片后性能提升:
- 内存压力分散到多台机器
- 查询吞吐量提升N倍(N=分片数)
▎04 防作弊:如何识别刷量IP?
识别异常IP的4个维度(附代码):
- 频率检测:1秒内请求超过100次
String key = "ip_limit:" + ip;
Long count = redisTemplate.opsForValue().increment(key);
redisTemplate.expire(key, 1, TimeUnit.SECONDS);
if(count > 100) throw new RuntimeException("刷量IP!");
- 设备指纹:相同UserAgent+IP组合
- 行为分析:只访问特定API的IP
- 地理位置:突发的境外IP请求
▎05 彩蛋:Redis模块安装指南
TopK功能需要RedisBloom模块,安装步骤:
# 1. 下载模块
wget https://github.com/RedisBloom/RedisBloom/archive/refs/tags/v2.4.5.tar.gz
# 2. 编译
make && cp redisbloom.so /path/to/modules/
# 3. 启动Redis时加载
redis-server --loadmodule /path/to/redisbloom.so
实战总结:
- 10万级以下
- 直接用ZSet
- 百万~十亿级
- TopK+分片
- 百亿级以上
- Flink+Redis分层存储
猜你喜欢
- 2025-04-30 多种负载均衡算法及其Java代码实现
- 2025-04-30 输入www.baidu.com背后经历了啥?说清楚这个,已经超过90%的人了
- 2025-04-30 优化MySQL:为什么你应该用 UNSIGNED INT 存储IP地址
- 2025-04-30 实模式下CPU如何获取数据及指令(实模式寻址方式)
- 2025-04-30 java基础都在这了,小主们拿去吧(java基础是指什么)
- 2025-04-30 盘点爬虫语言为何选择Python而不是Java
- 2025-04-30 搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇
- 2025-04-30 网络协议之TCP/IP协议(面试必考内容) - javaEE初阶 - 细节狂魔
- 2025-04-30 VPN技术(IPsec/L2TP/SSLVPN/PPTP)学习笔记
- 2025-04-30 74块钱一年的云服务器可以用来做什么?
你 发表评论:
欢迎- 最近发表
-
- 多种负载均衡算法及其Java代码实现
- 输入www.baidu.com背后经历了啥?说清楚这个,已经超过90%的人了
- 优化MySQL:为什么你应该用 UNSIGNED INT 存储IP地址
- 实模式下CPU如何获取数据及指令(实模式寻址方式)
- java基础都在这了,小主们拿去吧(java基础是指什么)
- 盘点爬虫语言为何选择Python而不是Java
- 搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇
- 网络协议之TCP/IP协议(面试必考内容) - javaEE初阶 - 细节狂魔
- 深夜报警!10亿次请求暴击,如何用Redis找出最热IP?
- VPN技术(IPsec/L2TP/SSLVPN/PPTP)学习笔记
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)