springBoot2.*使用redis集群/单机方法
在springboot1.x
系列中,其中使用的是jedis
,但是到了springboot2.x
其中使用的是Lettuce
。 此处springboot2.x
,所以使用的是Lettuce
。
关于jedis
跟lettuce
的区别:
- Lettuce 和 Jedis 的定位都是Redis的client,所以他们当然可以直接连接redis server。
- Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接
- Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
新建一个springboot工程,添加如下pom依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redis依赖commons-pool 这个依赖一定要添加 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
application.yml
配置一下redis
服务器的地址(其中nodes为集群redis的参数 host为单机redis的参数)
#REDIS
redis:
cache:
nodes: #-192.168.1.2:7001 前面使用 -
host: localhost:6379
password:
maxIdle:
minIdle:
maxTotal:
maxWaitMillis: 5000
redis配置类:
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;
import java.util.Set; @Configuration
public class RedisConfiguration {
@Value("${spring.redis.cache.nodes:}")
private String nodes;
@Value("${spring.redis.cache.host:}")
private String host;
@Value("${spring.redis.cache.password:}")
private String password;
@Value("${spring.redis.cache.maxIdle:}")
private Integer maxIdle;
@Value("${spring.redis.cache.minIdle:}")
private Integer minIdle;
@Value("${spring.redis.cache.maxTotal:}")
private Integer maxTotal;
@Value("${spring.redis.cache.maxWaitMillis:}")
private Long maxWaitMillis; @Bean
LettuceConnectionFactory lettuceConnectionFactory() {
// 连接池配置
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxIdle(maxIdle == null ? 8 : maxIdle);
poolConfig.setMinIdle(minIdle == null ? 1 : minIdle);
poolConfig.setMaxTotal(maxTotal == null ? 8 : maxTotal);
poolConfig.setMaxWaitMillis(maxWaitMillis == null ? 5000L : maxWaitMillis);
LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder()
.poolConfig(poolConfig)
.build();
// 单机redis
RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
redisConfig.setHostName(host==null||"".equals(host)?"localhost":host.split(":")[0]);
redisConfig.setPort(Integer.valueOf(host==null||"".equals(host)?"6379":host.split(":")[1]));
if (password != null && !"".equals(password)) {
redisConfig.setPassword(password);
} // 哨兵redis
// RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration(); // 集群redis
/*RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
Set<RedisNode> nodeses = new HashSet<>();
String[] hostses = nodes.split("-");
for (String h : hostses) {
h = h.replaceAll("\\s", "").replaceAll("\n", "");
if (!"".equals(h)) {
String host = h.split(":")[0];
int port = Integer.valueOf(h.split(":")[1]);
nodeses.add(new RedisNode(host, port));
}
}
redisConfig.setClusterNodes(nodeses);
// 跨集群执行命令时要遵循的最大重定向数量
redisConfig.setMaxRedirects(3);
redisConfig.setPassword(password);*/ return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration);
} @Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(lettuceConnectionFactory);
//序列化类
MyRedisSerializer myRedisSerializer = new MyRedisSerializer();
//key序列化方式
template.setKeySerializer(myRedisSerializer);
//value序列化
template.setValueSerializer(myRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(myRedisSerializer);
return template;
} static class MyRedisSerializer implements RedisSerializer<Object> { @Override
public byte[] serialize(Object o) throws SerializationException {
return serializeObj(o);
} @Override
public Object deserialize(byte[] bytes) throws SerializationException {
return deserializeObj(bytes);
} /**
* 序列化
* @param object
* @return
*/
private static byte[] serializeObj(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
throw new RuntimeException("序列化失败!", e);
}
} /**
* 反序列化
* @param bytes
* @return
*/
private static Object deserializeObj(byte[] bytes) {
if (bytes == null){
return null;
}
ByteArrayInputStream bais = null;
try {
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
throw new RuntimeException("反序列化失败!", e);
}
}
}
} 上
现在就可以正常的使用redis了 示例
注入:
@Autowired
private RedisTemplate<String, Object> redisTemplate;
添加:
redisTemplate.opsForValue().set(key, value);
添加,设置过期时间:
redisTemplate.opsForValue().set(key, obj, expireTime, TimeUnit.SECONDS);
获取:
Object o = redisTemplate.opsForValue().get(key);
删除:
redisTemplate.delete(key);
还可以根据自己需要编写一个类RedisService,方便以后使用
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseBody; import java.util.concurrent.TimeUnit;
import static java.util.Objects.hash;
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redis; /**
* 添加
* @param key
* @param value
*/
@ResponseBody
public void set(String key,String value){
redis.opsForValue().set(key,value);
} /**
* 添加并设置一个过期时间
* @param key
* @param value
* @param timeout 时间
* @param unit
* TimeUnit.DAYS //天
* TimeUnit.HOURS //小时
* TimeUnit.MINUTES //分钟
* TimeUnit.SECONDS //秒
* TimeUnit.MILLISECONDS //毫秒
*/
public void set(String key, String value, long timeout,TimeUnit unit){
redis.opsForValue().set(key,value,timeout,unit);
}
/**
* 添加并设置一个过期时间默订秒
* @param key
* @param value
* @param timeout 时间 秒
*/
public void set(String key, String value, long timeout){
redis.opsForValue().set(key,value,timeout,TimeUnit.SECONDS);
}
/**
* 将指定param的值设置为1,{@param param}会经过hash计算进行存储。
*
* @param key bitmap结构的key
* @param param 要设置偏移的key,该key会经过hash运算。
* @param value true:即该位设置为1,否则设置为0
* @return 返回设置该value之前的值。
*/
public Boolean setBit(String key,String param,boolean value){
return redis.opsForValue().setBit(key,hash(param),value);
}
/**
* 获取
* @param key
*/
public Object get(String key){
return redis.opsForValue().get(key);
} /**
* 删除
* @param key
*/
public void del(String key){
redis.delete(key);
}
/**
* 获取key大小
* @param key bitmap结构的key
*/
public Long size(String key){
return redis.opsForValue().size(key);
}
}
注入:
@Autowired
private RedisService redis;添
添加:
redis.set("usename","NX",9);//到期时间 秒
获取:
redis.get("usename");
springBoot2.*使用redis集群/单机方法的更多相关文章
- 峰Redis学习(10)Redis 集群(单机多节点集群和多机多节点集群)
单机多节点集群:参考博客:http://blog.java1234.com/blog/articles/326.html 多机多节点集群:参考博客:http://blog.java1234.com/b ...
- Redis集群搭建的三种方式
一.Redis主从 1.1 Redis主从原理 和MySQL需要主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生性能瓶颈,特别是在读压力上,为了分担压力,Redis支持主从复制. ...
- redis在Windows下以后台服务一键搭建集群(单机--伪集群)
redis在Windows下以后台服务一键搭建集群(单机--伪集群) 一.概述 此教程介绍如何在windows系统中同一台机器上布置redis伪集群,同时要以后台服务的模式运行.布置以脚本的形式,一键 ...
- SpringBoot2.0 整合 Redis集群 ,实现消息队列场景
本文源码:GitHub·点这里 || GitEE·点这里 一.Redis集群简介 1.RedisCluster概念 Redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的 ...
- Springboot2.x集成lettuce连接redis集群报超时异常Command timed out after 6 second(s)
文/朱季谦 背景:最近在对一新开发Springboot系统做压测,发现刚开始压测时,可以正常对redis集群进行数据存取,但是暂停几分钟后,接着继续用jmeter进行压测时,发现redis就开始突然疯 ...
- redis单机安装以及简单redis集群搭建
安装环境: 两台虚拟机都是Centos 7.0 IP分别为:192.168.149.132 192.168.149.133 Redis采用的版本是redis-3.2.4 集群是采用两台虚拟机模拟8个 ...
- linux系统centOS7下搭建redis集群中ruby版本过低问题的解决方法
问题描述: 在Centos7中,通过yum安装ruby的版本是2.0.0,但是如果有些应用需要高版本的ruby环境,比如2.2,2.3,2.4... 那就有点麻烦了,譬如:我准备使用redis官方给的 ...
- Springboot2.0访问Redis集群
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作高性能的key-value数据库.缓存和消息中间件,掌握它是程序员的必备技能,下面是一个springboot访问redis的 ...
- 一种简单实现Redis集群Pipeline功能的方法及性能测试
上一篇文章<redis pipeline批量处理提高性能>中我们讲到redis pipeline模式在批量数据处理上带来了很大的性能提升,我们先来回顾一下pipeline的原理,redis ...
随机推荐
- Ditto剪贴板增强工具
1.简介 Ditto是一款强大的Windows剪贴板增强工具,它支持64位操作系统,而且完全免费,绿色开源,支持中文,而且还有免安装的绿色版本. 开启Ditto后,不会有任何程序界面出现,它只是默默地 ...
- Docker基本命令入门
本文介绍Docker基本的操作命令,包括对镜像容器的获取,查看,保存,启停等操作. 1. 检查docker的版本: docker version docker -v 2. 搜索名字叫做tutorial ...
- 表达式树扩展 动态生成表达式树插件 Sy.ExpressionBuilder。
CURD中,基础查询我感觉还是很烦人的一个浪费时间的工作,我经历过远古时代的GetAll(string name,int age),这种方式写服务的时候真的是心中一万个草泥马飞过,后面逐渐的变成了传一 ...
- CF786C Till I Collapse
题目分析 首先,对于这道题,可以用贪心以一个\(O(n)\)的复杂度求解一个\(k\)的值 暴力是\(O(n^2)\)的复杂度,当然过不了. 我们手推一下样例,会发现,答案满足单调性,于是,果断想到二 ...
- YBT 1633:【例 3】Sumdiv
http://ybt.ssoier.cn:8088/problem_show.php?pid=1633 A^B 快速幂求结果,所有约数和,可以通过组合来进行得到. 技巧,通过递归得到1~n次的和.su ...
- 聊聊同步、异步、阻塞、非阻塞以及IO模型
前言 在使用Netty改造手写RPC框架的时候,需要给大家介绍一些相关的知识,这样很多东西大家就可以看明白了,手写RPC是一个支线任务,后续重点仍然是Kubernetes相关内容. 阻塞与非阻塞 同步 ...
- 【Java】数组
文章目录 数组 一.数组的定义 二.数组的声明与创建 三.内存分析 四.三种初始化 五.数组的四个基本特点 六.数组边界 七.数组的使用 八.多维数组 九.Arrays类 十.稀疏数组 数组 一.数组 ...
- Chrome插件:提醒你正在摸鱼,摸鱼的时候知道自己在摸鱼,减少摸鱼的时间和频率。
stop-mess-around 项目介绍 减少摸鱼的时间和频率的Chrome插件:在上班/学习期间很容易下意识的打开摸鱼网站,插件帮助我们减少摸鱼的时间和频率,提高我们上班和学习的效率,节省时间用于 ...
- 用Win +R运行快速启动各种程序
许多人认为Windows的Win+R运行就是摆设,除了开cmd和shutdown外毫无用处.其实Win+R是可以用于各种快捷启动的. Win+R可以视作执行一条cmd命令,要用他运行程序,理论上必须输 ...
- 从容器镜像的选择-alpine 说起
在 容器崛起之前,Alpine 还是个无名之辈,可能是因为大家并不是很关心操作系统本身的大小,毕竟大家只关心业务数据和文档,程序.库文件和系统本身的大小通常可以忽略不计. 容器技术席卷整个软件产业之后 ...