为啥Redis是DBA的“新宠”?
你肯定听过这句话:“缓存用得好,升职加薪早”。作为DBA,MySQL、Oracle玩得溜,但Redis才是高并发场景下的“扛把子”。
举个 :
假设你的服务器每秒要处理10万次请求,MySQL扛不住怎么办?这时候Redis的内存读写能力(每秒读10万次、写8万次)就能救命!它能像“闪电侠”一样,把热点数据存在内存里,让用户秒开页面,数据库压力瞬间减半。
1. 安装Redis(Aimalinux版)
用你擅长的Shell脚本,一条命令搞定:
# 下载+编译安装
wget http://download.redis.io/releases/redis-7.0.0.tar.gz
tar xzf redis-7.0.0.tar.gz
cdredis-7.0.0
make && make install
# 启动Redis服务(后台运行)
nohupsrc/redis-server &
Tips:Redis默认端口6379,记得开防火墙哦!
2. 必会的5个Redis命令
连上Redis客户端(redis-cli
),试试这些命令:
小白提问:Redis和MySQL有啥区别?
答案:MySQL数据存硬盘,Redis存内存,速度差100倍!
场景1:缓存穿透(查不存在的数据)
问题:黑客疯狂查不存在的ID,导致数据库被打爆。
解决:用空值缓存或布隆过滤器拦截。
// Java代码示例:查不到时缓存空值
publicStringgetProduct(String id){
Stringkey="product:"+ id;
Stringvalue=redis.get(key);
if(value ==null) {
value = db.query("SELECT * FROM product WHERE id=?", id);
if(value ==null) {
redis.setex(key,300,"");// 空值缓存5分钟
}else{
redis.setex(key,3600, value);// 正常数据缓存1小时
}
}
returnvalue;
}
(代码参考:缓存空值防止穿透)
场景2:缓存雪崩(大量缓存同时过期)
解决:随机过期时间,比如300秒±60秒随机。
# Shell脚本批量设置随机过期时间
foriin{1..1000};do
redis-cli SET"key_$i""value"EX $((300+ RANDOM `))
done
场景3:热点Key扛不住(比如爆款商品)
解决:本地缓存+Redis多副本。比如用Java的Guava Cache:
LoadingCache<String, String> localCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.SECONDS)
.build(key -> redis.get(key));// 本地缓存10秒
Redis核心玩法:5种数据结构+Java实战
“别光会set/get!Redis数据结构才是精髓!”
Redis不是简单的Key-Value存储,它支持5种数据结构,DBA必须玩明白:
:存数字、JSON、甚至图片二进制
// Java代码:用Jedis操作String
Jedisjedis=newJedis("localhost");
jedis.set("user:1001","{'name':'老王','age':28}");// 存用户信息
Stringuser=jedis.get("user:1001");// 0.1毫秒读取!
:存对象属性,避免多次查询
// 存商品详情
Map<String, String> product =newHashMap<>();
product.put("price","99.99");
product.put("stock","1000");
jedis.hset("product:888", product);
:实现消息队列、最新订单
// 模拟订单队列
jedis.lpush("order:queue","order1001","order1002");
StringlatestOrder=jedis.rpop("order:queue");// 从右边弹出
:去重+交集运算,搞UV统计
#Shell脚本:统计当日活跃用户
redis-cli SADD active_users:20240507 "user1001" "user1002"
redis-cli SCARD active_users:20240507 # 直接拿到总数!
:排行榜神器
// 游戏玩家积分排行
jedis.zadd("game_rank",5000,"player1");
jedis.zadd("game_rank",8000,"player2");
Set<String> top3 = jedis.zrevrange("game_rank",0,2);// 前三名秒出!
1. 分布式锁(防止超卖)
用Redis的SETNX
命令实现锁:
// 加锁
publicbooleanlock(String key, String value,intexpireTime){
Stringresult=jedis.set(key, value,"NX","EX", expireTime);
return"OK".equals(result);
}
// 解锁(Lua脚本保证原子性)
Stringscript="if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value));
注意:锁的value用UUID,防止误删其他线程的锁。
2. 秒杀系统设计
步骤:
库存预热:提前把库存扣减到Redis。
SET stock:1001 1000
用户抢购时,用Lua脚本原子性扣减库存:
-- Lua脚本(保证原子性)
localstock =tonumber(redis.call('GET', KEYS[1]))
ifstock >0then
redis.call('DECR', KEYS[1])
return1-- 成功
else
return0-- 失败
end
1. 主从复制(一主二从)
配置文件redis.conf
:
# 主节点
bind0.0.0.0
port 6379
# 从节点配置
replicaof 主节点IP 6379
启动后,主节点写数据,从节点自动同步。
2. 哨兵模式(自动故障转移)
哨兵配置文件sentinel.conf
:
sentinel monitor mymaster 主节点IP 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
效果:主节点挂了,哨兵自动选新主,业务无感知。
3. Cluster集群(分片存储)
启动6个节点(3主3从),用命令创建集群:
redis-cli --cluster create 节点1IP:端口 节点2IP:端口 ... --cluster-replicas 1
数据自动分片到不同节点,支持横向扩展。
1. 数据持久化
:定时全量备份,适合灾难恢复。
:记录每条写命令,数据更安全。
配置redis.conf
:
save 900 1 # 15分钟内有1次写操作就备份
appendonlyyes# 开启AOF
2. 性能监控
用redis-cli info
查看关键指标:
redis-cli info stats | grep instantaneous_ops_per_sec # 每秒操作数
redis-cli info memory | grep used_memory_human # 内存使用量
3. 连接池优化(Java版)
JedisPoolConfigconfig=newJedisPoolConfig();
config.setMaxTotal(100); // 最大连接数
config.setMaxIdle(20); // 最大空闲连接
JedisPoolpool=newJedisPool(config,"redis-host",6379);
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。