环境:ubuntu18.04 service版
一、准备工作
1.下载redis
①wget下载
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
②官网下载
2.开始安装
① 将redis-5.0.4.tar.gz上传到/home目录下
②解压redis-5.0.4.tar.gz
tar -zxvf redis-5.0.4.tar.gz
③进入redis-5.0.4文件夹
cd redis-5.0.4
④执行编译
make
<1>若没安装make
<2>执行
apt install make
<3>再次执行make
⑤进入到src
#执行编译源码到/usr/local/redis
make PREFIX=/usr/local/redis install
若出现
执行安装gcc
#安装gcc
apt-get install gcc
继续执行编译遇到
执行
make MALLOC=libc
再次执行安装,结果
说明已成功安装redis
⑤进入到/usr/local 发现多出了redis目录 则安装成功
拷贝/home/redis-5.0.4/redis.conf
cp /home/redis-5.0.4/redis.conf /usr/local/redis/bin
- 配置redis为后台启动
- 配置密码
#自动启动
vi /usr/local/redis/etc/redis.conf //将daemonize no 改成daemonize yes
#设置密码
vi /usr/local/redis/etc/redis.conf // requirepass test
⑥启动
./redis-service redis.conf
⑦查询进程
ps -ef|grep redis
成功安装redis
二、springboot集成redis
①在application.properties添加
#redis
spring.cache.redis.cache-null-values=false
#ip
spring.redis.host=ip
spring.redis.password=pwd
#端口
spring.redis.port=6379
#设置默认数据库编号
spring.redis.database=0
# 数据库连接超时时间,springboot2.0 中该参数的类型为Duration,这里在配置的时候需要指明单位
spring.redis.timeout=60s
#jedis
# 最大空闲连接数
spring.redis.jedis.pool.max-idle=500
# 最小空闲连接数
spring.redis.jedis.pool.min-idle=50
# 等待可用连接的最大时间,负数为不限制
spring.redis.jedis.pool.max-wait=-1s
# 最大活跃连接数,负数为不限制
spring.redis.jedis.pool.max-active=-1
②配置
package cn.north.demo.reids.conf;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@Data
@EqualsAndHashCode(callSuper=false)
public class JedisConf {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.database}")
private Integer database;
@Value("${spring.redis.timeout}")
private String timeout;
@Value("${spring.redis.jedis.pool.max-active}")
private Integer maxActive;
@Value("${spring.redis.jedis.pool.max-idle}")
private Integer maxIdle;
@Value("${spring.redis.jedis.pool.max-wait}")
private String maxWait;
@Value("${spring.redis.jedis.pool.min-idle}")
private Integer minIdle;
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(getMaxWait());
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMinIdle(minIdle);
return jedisPoolConfig;
}
@Bean
public RedisStandaloneConfiguration jedisConfig() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPort(port);
config.setDatabase(database);
config.setPassword(RedisPassword.of(password));
return config;
}
@Bean
public JedisPool jedisPool(){
return new JedisPool(jedisPoolConfig(), host,
port,getTimeout(),password,database);
}
public Integer getTimeout() {
return Integer.valueOf(timeout.substring(0,timeout.length()-1));
}
public Long getMaxWait() {
return Long.valueOf(maxWait.substring(0,maxWait.length()-1));
}
}
③工具类
package cn.north.demo.reids;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Redis工具类
* @author north
* @date 2019年2月25日
*/
@Component
public final class RedisUtil {
/**
* **opsForValue:**对应 String(字符串)
* **opsForZSet:**对应 ZSet(有序集合)
* **opsForHash:**对应 Hash(哈希)
* **opsForList:**对应 List(列表)
* **opsForSet:**对应 Set(集合)
* **opsForGeo:**对应 GEO(地理位置)
*/
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private JedisPool jedisPool;
//当前选定的数据库
private Integer dateBaseNum = 0;
// =============================common============================
public void setHash(String key, Object hash, Object value){
redisTemplate.opsForHash().put(key, hash, value);
}
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* Set hashKey对应的所有键值
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
/**
* 根据key获取Set中的所有值
* @param key 键
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 将set数据放入缓存
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
* @param key 键
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/**
* 获取list缓存的内容
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/***
* 获取所有
* @param key
* @return
*/
public List<Object> lGet(String key) {
try {
return redisTemplate.opsForList().range(key,0,lGetListSize(key));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
* @param key 键
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 切换当前redis数据库
* @param num 编号
* @return boolean
*/
public boolean setDateBase(Integer num){
try {
LettuceConnectionFactory jedisConnectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
jedisConnectionFactory.setDatabase(num);
redisTemplate.setConnectionFactory(jedisConnectionFactory);
jedisConnectionFactory.resetConnection();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 获取当前选定的数据库
* @return Integer
*/
public Integer getThisDateBaseNum(){
return dateBaseNum;
}
/**
* redis点阅一个频道
* @param subscriber 订阅者
* @param channel 频道名
* @return boolean
*/
public boolean subscribe(MessageListener subscriber, String channel){
try {
redisTemplate.getConnectionFactory().getConnection().subscribe(subscriber,channel.getBytes());
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 从redis连接池获取redis实例
*/
public <T> T get(String key, Class<T> clazz) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//对key增加前缀,即可用于分类,也避免key重复
String str = jedis.get(key);
T t = stringToBean(str, clazz);
return t;
} finally {
returnToPool(jedis);
}
}
/**
* 存储对象
*/
public <T> Boolean set(String key, T value, Integer timeout) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String str = beanToString(value);
if (str == null || str.length() <= 0) {
return false;
}
if (timeout <= 0) {
jedis.set(key, str);
} else {
jedis.setex(key, timeout, str);
}
return true;
} finally {
returnToPool(jedis);
}
}
/**
* 删除
*/
public boolean delete(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
long ret = jedis.del(key);
return ret > 0;
} finally {
returnToPool(jedis);
}
}
/**
* 判断key是否存在
*/
public <T> boolean exists(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
return jedis.exists(key);
} finally {
returnToPool(jedis);
}
}
/**
* 增加值
* Redis Incr 命令将 key 中储存的数字值增一。 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作
*/
public <T> Long incr(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
return jedis.incr(key);
} finally {
returnToPool(jedis);
}
}
/**
* 减少值
*/
public <T> Long decr(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
//自减1
return jedis.decr(key);
} finally {
returnToPool(jedis);
}
}
private void returnToPool(Jedis jedis) {
if (jedis != null) {
jedis.close();//不是关闭,只是返回连接池
}
}
public static <T> String beanToString(T value) {
if (value == null) {
return null;
}
Class<?> clazz = value.getClass();
if (clazz == int.class || clazz == Integer.class) {
return String.valueOf(value);
} else if (clazz == long.class || clazz == Long.class) {
return String.valueOf(value);
} else if (clazz == String.class) {
return (String) value;
} else {
return JSON.toJSONString(value);
}
}
public static <T> T stringToBean(String str, Class<T> clazz) {
if (str == null || str.length() <= 0 || clazz == null) {
return null;
}
if (clazz == int.class || clazz == Integer.class) {
return (T) Integer.valueOf(str);
} else if (clazz == long.class || clazz == Long.class) {
return (T) Long.valueOf(str);
} else if (clazz == String.class) {
return (T) str;
} else {
return JSON.toJavaObject(JSON.parseObject(str), clazz);
}
}
}