一款基于c语言实现的高性能的非关系型数据库;
提供了五种数据类型,致力于使用数据结构帮助用户解决问题;
1.完全基于内存;
2.单线程,无需考虑线程切换;
3.NIO ,io复用模型;
4.非关系型数据库;
@Autowired
private RedisTemplate redisTemplate;
//通用1 给key设置失效时间
public void setKeyTime(String key,int time){
//一可死败儿
redisTemplate.expire(key,time, TimeUnit.SECONDS);
}
//通用2 获取key的失效时间
public void KeyTime(String key){
//一可死败儿
redisTemplate.getExpire(key);
}
//通用3 判断key是否存在
public boolean hasKey(String key){
return redisTemplate.hasKey(key);
}
//通用4 删除key
public void del(String[] keyArray){
redisTemplate.delete(keyArray);
}
redisTemplate.opsForValue()方法;
注意:使用increment方法时要注意序列化问题,如果value被序列化则无法使用爆出:
ERR value is not an integer or out of range
@RequestMapping(value ="/anon/getStirng", method = RequestMethod.GET)
//获取Stirng
public String getStirng(String key){
return (String) redisTemplate.opsForValue().get(key);
}
//设置Stirng
@RequestMapping(value = "/anon/setStirng",method = RequestMethod.GET)
public void SetStirng(String key,String value){
redisTemplate.opsForValue().set(key,value);
}
//设置String 并添加过期时间
@RequestMapping(value = "/anon/setStirngAndTime",method = RequestMethod.GET)
public void setStirngAndTime(String key,String value,int time){
redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);
}
//递增 存进去的值得是int对应类型的
@RequestMapping(value = "/anon/incr",method = RequestMethod.GET)
public Long incr(Long data){
if (!redisTemplate.hasKey("incrKey"))
stringRedisTemplate.opsForValue().set("incrKey", String.valueOf(1));
return stringRedisTemplate.opsForValue().increment("incrKey", data);
}
//递减少 存进去的值得是int对应类型的
@RequestMapping(value = "/anon/incr2",method = RequestMethod.GET)
public Long incr2(String key,Long data){
return redisTemplate.opsForValue().increment(key, -data);
}
redisTemplate.opsForList方法()
// 插入List
public void lSet(String key, List<Object> value) {
redisTemplate.opsForList().rightPushAll(key, value);
}
// 插入并指定过期时间
public void lSetAndTime(String key, List<Object> value,int time) {
redisTemplate.opsForList().rightPushAll(key, value,time,TimeUnit.SECONDS);
}
// 获取list内容
@RequestMapping(value = "/anon/lget",method = RequestMethod.GET)
public List lget(String key,int start,int end) {
if (!redisTemplate.hasKey(key)){
ArrayList<Object> objects = new ArrayList<>();
objects.add("1");
objects.add("2");
redisTemplate.opsForList().rightPushAll(key,objects);
}
return redisTemplate.opsForList().range(key, start, end);
}
// 获取list长度
public Long lgetSize(String key) {
return redisTemplate.opsForList().size(key);
}
// 移除N个值为value
public void lRemove(String key,int count,String value){
redisTemplate.opsForList().remove(key,count,value);
}
opsforSet();
// 添加一个set缓存
public long sSet(String key, Object...values) {
return redisTemplate.opsForSet().add(key, values);
}
// 添加一个set缓存2
public long sSet2(String key, String[] Array) {
return redisTemplate.opsForSet().add(key, Array);
}
// 获取值
public Set sGet(String key) {
return redisTemplate.opsForSet().members(key);
}
// 判断set中包含某个值
public boolean hasSet(String key ,String value){
return redisTemplate.opsForSet().isMember(key,value);
}
// 移除set中包含某个值
public long hasSet(String key ,String...value){
return redisTemplate.opsForSet().remove(key,value);
}
分布式锁注意的两个问题:
1.加锁的时候注意指定过期时间,如果不指定,那么一旦加锁的线程挂掉将会导致锁不会被释放;
2.加了过期时间可能会出现,在加锁期间内任务没有完成锁就被释放;所以需要一条守护线程进行续命;
加锁:加锁的时间使用的是当前时间+加锁时间,不是过期策略,比如加锁300ms,但是1s过去了锁还在,其他人想加锁进来自己判断加锁是否过期,过期则重新加锁否则加锁失败;
/**
* 最终加强分布式锁
* @param key key值
* @return 是否获取到
*/
public boolean lock(String key) {
String lock = LOCK_PREFIX + key;
// 利用lambda表达式
return (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1;
Boolean acquire = redisConnection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());
if (acquire) {
return true;
} else {
byte[] value = redisConnection.get(lock.getBytes());
if (Objects.nonNull(value) && value.length > 0) {
long expireTime = Long.parseLong(new String(value));
if (expireTime < System.currentTimeMillis()) {
// 如果锁已经过期
byte[] oldValue = redisConnection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
// 防止死锁
return Long.parseLong(new String(oldValue)) < System.currentTimeMillis();
}
}
}
return false;
}
});
}
解锁:
/**
* 删除锁
*
* @param key
*/
public void delete(String key) {
redisTemplate.delete(key);
}