为啥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
cd redis-7.0.0
make && make install
# 启动Redis服务(后台运行)
nohup src/redis-server &
Tips:Redis默认端口6379,记得开防火墙哦!
2. 必会的5个Redis命令
连上Redis客户端(redis-cli
),试试这些命令:
-- 存数据(String类型)
SETuser:1001 "张三"
-- 取数据
GETuser:1001
-- 存哈希表(适合存对象)
HSET product:8888 name "手机" price 3999
-- 设置过期时间(30秒后自动删除)
EXPIRE product:888830
-- 查看内存信息
INFO memory
小白提问:Redis和MySQL有啥区别? 答案:MySQL数据存硬盘,Redis存内存,速度差100倍!
场景1:缓存穿透(查不存在的数据) 问题:黑客疯狂查不存在的ID,导致数据库被打爆。 解决:用空值缓存或布隆过滤器拦截。
// Java代码示例:查不到时缓存空值
public String getProduct(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小时
}
}
return value;
}
(代码参考:缓存空值防止穿透)
场景2:缓存雪崩(大量缓存同时过期) 解决:随机过期时间,比如300秒±60秒随机。
# Shell脚本批量设置随机过期时间
for i in {1..1000}; do
redis-cli SET "key_$i""value" EX $((300 + RANDOM % 60))
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必须玩明白:
// 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"); // 从右边弹出
# 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, int expireTime) {
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. 秒杀系统设计 步骤:
SET stock:1001 1000
-- Lua脚本(保证原子性)
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock > 0then
redis.call('DECR', KEYS[1])
return1-- 成功
else
return0-- 失败
end
1. 主从复制(一主二从)
配置文件redis.conf
:
# 主节点
bind 0.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次写操作就备份
appendonly yes# 开启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);
掌握Redis,你就能让数据库性能飞升,老板看了直呼“牛啊”!赶紧动手试试吧!