redis实践
CentOS7安装redis
-
添加redis压缩包
-
解压
-
make , make install
-
cp /root/redis-3.2.8/redis.conf /usr/local/redis/bin
-
修改配置文件
整合redis
redisutil
public class RedisUtil {
//创建链接池
private JedisPool jedisPool;
//初始化连接池
public void initJedisPool(String host,int port,int database) {
//创建一个配置类
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//设置连接池最大连接数
jedisPoolConfig.setMaxTotal(200);
//设置等待时间
jedisPoolConfig.setMaxWaitMillis(10*1000);
//设置最小剩余数
jedisPoolConfig.setMinIdle(10);
//开启获取连接池阻塞队列
jedisPoolConfig.setBlockWhenExhausted(true);
//在借用连接后,自检是否可用
jedisPoolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool(jedisPoolConfig,host,port,20*1000);
}
//获取jedis
public Jedis getJedis() {
Jedis jedis = jedisPool.getResource();
return jedis;
}
}
RedisConfig
@Configuration
public class RedisConfig {
@Value("${spring.redis.host:disable}")
private String host;
@Value("${spring.redis.port:0}")
private int port;
@Value("${spring.redis.database:0}")
private int database;
//将获取到的参数传入initJedisPool方法中
@Bean
public RedisUtil getRedisUtil() {
if ("disable".equals(host)) {
return null;
}
RedisUtil redisUtil = new RedisUtil();
redisUtil.initJedisPool(host,port,database);
return redisUtil;
}
}
application.properties
#redis的配置
spring.redis.host=192.168.113.132
spring.redis.port=6379
spring.redis.database=0
实践
@Override
public SkuInfo getSkuInfo(String skuId) {
// //保存到redis中
// Jedis jedis = redisUtil.getJedis();
//
// jedis.set("ok","测试");
// jedis.close();
SkuInfo skuInfo = null;
Jedis jedis = null;
//获取jedis
try {
jedis = redisUtil.getJedis();
//获取缓存中的数据
String key = ManageConst.SKUKEY_PREFIX+skuId+ManageConst.SKUKEY_SUFFIX;
//判断redis中是否有key
if (jedis.exists(key)) {
//在redis中取出来
String jedisString = jedis.get(key);
//转化为对象
skuInfo = JSON.parseObject(jedisString, SkuInfo.class);
return skuInfo;
}else {
skuInfo = getSkuInfoDB(skuId);
//放入redis中
String s = JSON.toJSONString(skuInfo);
jedis.setex(key,ManageConst.SKUKEY_TIMEOUT,s);
return skuInfo;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close();
}
}
return getSkuInfoDB(skuId);
}
private SkuInfo getSkuInfoDB(String skuId) {
SkuInfo skuInfo = skuInfoMapper.selectByPrimaryKey(skuId);
SkuImage skuImage = new SkuImage();
skuImage.setSkuId(skuId);
List<SkuImage> skuImageList = skuImageMapper.select(skuImage);
skuInfo.setSkuImageList(skuImageList);
return skuInfo;
}
redis分布式锁
redis实现分布式锁
解决缓存击穿问题:
(1)Redis:命令
# set sku:1:info “OK” NX PX 10000
EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
XX :只在键已经存在时,才对键进行设置操作。
ManageConst类
@Component
public class ManageConst {
public static final String SKUKEY_PREFIX="sku:";
public static final String SKUKEY_SUFFIX=":info";
public static final int SKUKEY_TIMEOUT=24*60*60;
public static final int SKULOCK_EXPIRE_PX=10000;
public static final String SKULOCK_SUFFIX=":lock";//分布式锁
}
修改代码:
@Override
public SkuInfo getSkuInfo(String skuId) {
// //保存到redis中
// Jedis jedis = redisUtil.getJedis();
//
// jedis.set("ok","测试");
// jedis.close();
SkuInfo skuInfo = null;
Jedis jedis = null;
//获取jedis
try {
jedis = redisUtil.getJedis();
//获取缓存中的数据
String key = ManageConst.SKUKEY_PREFIX+skuId+ManageConst.SKUKEY_SUFFIX;
//获取数据
String skuJson = jedis.get(key);
if (skuJson == null || skuJson.length() == 0) {
//尝试加锁
System.err.println("缓存中没有数据");
//set加锁
String skuLockKey = ManageConst.SKUKEY_PREFIX+skuId+ManageConst.SKULOCK_SUFFIX;
String lockKey = jedis.set(skuLockKey, "good", "NX", "PX", ManageConst.SKULOCK_EXPIRE_PX);
if ("OK".equals(lockKey)) {
//此时加锁成功
skuInfo = getSkuInfoDB(skuId);
//放入redis中
String s = JSON.toJSONString(skuInfo);
jedis.setex(key,ManageConst.SKUKEY_TIMEOUT,s);
//删除锁
jedis.del(lockKey);
return skuInfo;
}else {
//线程等待
Thread.sleep(1000);
//调用getSkuInfo方法
return getSkuInfo(skuId);
}
}else {
//在redis中取出来
String jedisString = jedis.get(key);
//转化为对象
skuInfo = JSON.parseObject(jedisString, SkuInfo.class);
return skuInfo;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close();
}
}
return getSkuInfoDB(skuId);
}
private SkuInfo getSkuInfoDB(String skuId) {
SkuInfo skuInfo = skuInfoMapper.selectByPrimaryKey(skuId);
SkuImage skuImage = new SkuImage();
skuImage.setSkuId(skuId);
List<SkuImage> skuImageList = skuImageMapper.select(skuImage);
skuInfo.setSkuImageList(skuImageList);
return skuInfo;
}
压力测试
-
安装ab工具
-
yum install httpd-tools
-
ab –n 1000-c 200 -p /opt/upprofile -T "application/x-www-form-urlencoded" 192.168.0.106:8084/55.html
(2)redisson分布式锁
导入依赖
-
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.11.1</version> </dependency>
-
@Override public SkuInfo getSkuInfo(String skuId) { // //保存到redis中 // Jedis jedis = redisUtil.getJedis(); // // jedis.set("ok","测试"); // jedis.close(); return getSkuInfoRedisson(skuId); // return getSkuInfoJedis(skuId); } private SkuInfo getSkuInfoRedisson(String skuId) { Config config = new Config(); config.useSingleServer().setAddress("redis://192.168.113.132:6379"); RedissonClient redissonClient = Redisson.create(config); //使用redisson调用getLock RLock myLock = redissonClient.getLock("myLock"); //加锁 myLock.lock(10, TimeUnit.SECONDS); //业务逻辑代码 SkuInfo skuInfo = null; Jedis jedis = null; //获取jedis try { jedis = redisUtil.getJedis(); //获取缓存中的数据 String key = ManageConst.SKUKEY_PREFIX+skuId+ManageConst.SKUKEY_SUFFIX; //判断redis中是否有key if (jedis.exists(key)) { //在redis中取出来 String jedisString = jedis.get(key); //转化为对象 skuInfo = JSON.parseObject(jedisString, SkuInfo.class); return skuInfo; }else { skuInfo = getSkuInfoDB(skuId); //放入redis中 String s = JSON.toJSONString(skuInfo); jedis.setex(key,ManageConst.SKUKEY_TIMEOUT,s); return skuInfo; } } catch (Exception e) { e.printStackTrace(); } finally { if (jedis != null) { jedis.close(); } //解锁 myLock.unlock(); } return getSkuInfoDB(skuId); }
评论区