Redis集群搭建,以及SpringBoot实现

一、思路

  • Java Redis实现程序设计
  • Redis集群架构图
概念特别说明:
1、redis集群:
针对redis服务器搭建部署而言,多个redis-server构建一个redis集群环境,对外提供redis服务。key根据redis内部策略(主要是Hash 虚拟槽分区 slot),分配到不同的redis-server服务器中
2、redis主从同步:
为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。为此, Redis 提供了复制(replication)功能,可以实现当一台数据库中的数据更新后,自动将更新的数据同步到其他数据库上。
3、区别:
主从服务器分工明确,主服务器用来写,从服务器用来读,一个主服务器,多个从服务器;集群就好比,多个主从服务器,比如:全国有多个主从服务器,分别处理各自区域的信息,这样可以减少单个主从服务器中主服务器的压力
4、slot特别说明
哈希槽的存在, 是为了能快速找到key所在的节点。一个redis集群包含2^16=16384个哈希槽,会分配给各个节点。可以通过槽的分配来控制不同节点的数据量和请求数。哈希槽通过顺时针来分片,即一个节点顺时针到下一个几点之间的槽属于下一个节点。
每一个key,通过公式slot=CRC16(key)/16384来计算属于哪个槽。
 
 

二、Redis集群部署具体实现

1、环境说明
本次Redis集群搭建部署是基于Windows开发环境
 
2、服务器规划
节点1:
127.0.0.1:6379  主   ok
127.0.0.1:6380  从   ok
 
节点2:
127.0.0.1:6479  主
 
节点3:
127.0.0.1:6579  主
 
3、部署步骤
(1)安装Redis
 
可以直接下载最近稳定版本的zip文件,无需进行安装,文件下载解压到目录:G:\MyPrivate\MyKit\Redis-x64-3.0.504
 
 
 
(2)修改Redis配置文件
 
A、以6379端口配置文件redis.windows.conf为例,其他端口6479配置文件redis.windows6479.conf、端口6579配置文件redis.windows6579.conf雷同
 
B、修改配置文件,关闭rdb内存快照方式,开启aof持久化方式,开启cluster
port 6379
 
#关闭rdb
#save 900 1
#save 300 10
#save 60 10000
dbfilename dump6379.rdb
 
#开启aof
appendonly yes
appendfilename "appendonly6379.aof"
appendfsync everysec
 
#配置集群信息
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
cluster-slave-validity-factor 10
cluster-migration-barrier 1
cluster-require-full-coverage yes
 
(3)启动Redis服务器
依次打开Dos窗口,切换到Redis安装目录cd G:\MyPrivate\MyKit\Redis-x64-3.0.504
执行命令:
redis-server.exe redis.windows.conf
redis-server.exe redis.windows6380.conf
redis-server.exe redis.windows6479.conf
redis-server.exe redis.windows6579.conf
 
 
 
(4)下载并安装Ruby,下载地址: http://railsinstaller.org/en
  设置系统环境变量,把C:\RailsInstaller\Ruby2.3.3\bin添加到系统环境变量中
 
 
 
(5)安装完毕之后,下载Ruby环境下Redis的驱动,考虑到兼容性,这里下载的是3.2.2版本,下载地址: https://rubygems.org/gems/redis/versions/3.2.2
下载完毕放置Redis安装目录下G:\MyPrivate\MyKit\Redis-x64-3.0.504\redis-3.2.2.gem
 
(6)安装Ruby Redis驱动
gem install --local G:\MyPrivate\MyKit\Redis-x64-3.0.504\redis-3.2.2.gem
 
(7)下载Redis官网提供的Redis集群Ruby脚本redis-trib.rb,有两种方式:
 
下载的文件放在Redis安装目录下
 
(8)创建Redis集群
打开Dos窗口,进入到Redis安装目录 G:\MyPrivate\MyKit\Redis-x64-3.0.504,执行:ruby redis-trib.rb create --replicas 0 127.0.0.1:6379 127.0.0.1:6479 127.0.0.1:6579,当出现提示的时候,手动输入yes
 
校验是否创建成功,输入命令:ruby redis-trib.rb check 127.0.0.1:6379
 
 
补充: redis-trib.rb命令
支持的操作如下:
1. create:创建集群
2. check:检查集群
3. info:查看集群信息
4. fix:修复集群
5. reshard:在线迁移slot
6. rebalance:平衡集群节点slot数量
7. add-node:添加新节点
8. del-node:删除节点
9. set-timeout:设置节点的超时时间
10. call:在集群所有节点上执行命令
11. import:将外部redis数据导入集群
 
 
添加slave节点
给127.0.0.1:6379添加slave节点127.0.0.1:6380,命令如下所示。
注意:slave节点的特性,数据来自于主节点,可以进行读写操作,写操作默认都会在Master节点上面进行处理
 
G:\MyPrivate\MyKit\Redis-x64-3.0.504> ruby redis-trib.rb add-node --slave 127.0.0.1:6380 127.0.0.1:6379
>>> Adding node 127.0.0.1:6380 to cluster 127.0.0.1:6379
>>> Performing Cluster Check (using node 127.0.0.1:6379)
M: d2d52e9453b367a96ad0b89973851efbb0452c08 127.0.0.1:6379
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
M: 36863046950bc37bd6462a6c977135f8d7c01449 127.0.0.1:6479
   slots:5461-10922 (5462 slots) master
   0 additional replica(s)
M: 9fa742639b82a080ac168b9a6c1943b54977371c 127.0.0.1:6579
   slots:10923-16383 (5461 slots) master
   0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 127.0.0.1:6379
>>> Send CLUSTER MEET to node 127.0.0.1:6380 to make it join the cluster.
Waiting for the cluster to join...
>>> Configure node as replica of 127.0.0.1:6379.
[OK] New node added correctly.
 
G:\MyPrivate\MyKit\Redis-x64-3.0.504> ruby redis-trib.rb check 127.0.0.1:6379
>>> Performing Cluster Check (using node 127.0.0.1:6379)
M: d2d52e9453b367a96ad0b89973851efbb0452c08 127.0.0.1:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 36863046950bc37bd6462a6c977135f8d7c01449 127.0.0.1:6479
   slots:5461-10922 (5462 slots) master
   0 additional replica(s)
S: d07c74d1bbdca97340867bed535259c4688a877d 127.0.0.1:6380
   slots: (0 slots) slave
   replicates d2d52e9453b367a96ad0b89973851efbb0452c08
M: 9fa742639b82a080ac168b9a6c1943b54977371c 127.0.0.1:6579
   slots:10923-16383 (5461 slots) master
   0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
 
G:\MyPrivate\MyKit\Redis-x64-3.0.504> ruby redis-trib.rb info 127.0.0.1:6379
127.0.0.1:6379 (d2d52e94...) -> 3 keys | 5461 slots | 1 slaves.
127.0.0.1:6479 (36863046...) -> 5 keys | 5462 slots | 0 slaves.
127.0.0.1:6579 (9fa74263...) -> 3 keys | 5461 slots | 0 slaves.
[OK] 11 keys in 3 masters.
0.00 keys per slot on average.
 
 
4、测试验证
(1)进入任一集群节点,可以通过cluster info 查询集群节点状态
 
C:\Users\jiangjiabao> G:
 
G:\> cd G:\MyPrivate\MyKit\Redis-x64-3.0.504
 
G:\MyPrivate\MyKit\Redis-x64-3.0.504> redis-cli.exe -c -p 6379
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:3
cluster_size:3
cluster_current_epoch:3
cluster_my_epoch:1
cluster_stats_messages_sent:619
cluster_stats_messages_received:614
127.0.0.1:6379> info cluster
# Cluster
cluster_enabled:1
 
(2)设置key,切换到不同的集群节点查询key
127.0.0.1:6379> set name yubing
-> Redirected to slot [5798] located at 127.0.0.1:6479
OK
127.0.0.1:6479> set age 39
-> Redirected to slot [741] located at 127.0.0.1:6379
OK
127.0.0.1:6379> set height 171
-> Redirected to slot [8223] located at 127.0.0.1:6479
OK
127.0.0.1:6479> hset 1004user name yubing
(integer) 1
 
 
127.0.0.1:6479> get name
"yubing"
127.0.0.1:6479> get age
-> Redirected to slot [741] located at 127.0.0.1:6379
"39"
127.0.0.1:6379> mgetall 1004user
(error) ERR unknown command 'mgetall'
127.0.0.1:6379> hgetall 1004user
-> Redirected to slot [10116] located at 127.0.0.1:6479
1) "name"
2) "yubing"
 

三、Java SpringBoot之Redis集群实现

 
1、代码结构如下所示
 
2、代码说明
(1)pom.xml添加依赖
<dependencies>
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-data-redis </artifactId>
</dependency>
<!--lettuce pool 缓存连接池 -->
<dependency>
<groupId> org.apache.commons </groupId>
<artifactId> commons-pool2 </artifactId>
</dependency>
 
<!--springboot 依赖 -->
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter </artifactId>
</dependency>
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-web </artifactId>
</dependency>
 
<dependency>
<groupId> org.projectlombok </groupId>
<artifactId> lombok </artifactId>
<optional> true </optional>
</dependency>
 
<dependency>
<groupId> com.alibaba </groupId>
<artifactId> fastjson </artifactId>
<version> 1.2.66 </version>R
</dependency>
 
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-test </artifactId>
<scope> test </scope>
<exclusions>
<exclusion>
<groupId> org.junit.vintage </groupId>
<artifactId> junit-vintage-engine </artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
 
application.properties配置文件
spring.application.name = exec-data-redis
server.port = 8081
 
#redis 连接配置型
spring.redis.database = 0
#spring.redis.host=127.0.0.1
#spring.redis.port=6379
#spring.redis.password=
 
#redis jedis 配置信息
## 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active = 8
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait = -1
## 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle = 8
## 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle = 0
## 连接超时时间(毫秒)
spring.redis.timeout = 1000
 
spring.redis.cluster.nodes = 192.168.8.196:6379,192.168.8.196:6479,192.168.8.196:6579,192.168.8.196:6380
spring.redis.cluster.max-redirects = 2
 
 
#redis lettuce 方式配置信息
#spring.redis.lettuce.pool.max-active=8
#spring.redis.lettuce.pool.max-wait=-1
#spring.redis.lettuce.pool.max-idle=8
#spring.redis.lettuce.pool.min-idle=0
 
 
(2)RedisConfig.java
package com.darben.execdatareids.config ;
 
import com.fasterxml.jackson.annotation. JsonAutoDetect ;
import com.fasterxml.jackson.annotation.PropertyAccessor ;
import com.fasterxml.jackson.databind.ObjectMapper ;
import org.springframework.cache.annotation. EnableCaching ;
import org.springframework.context.annotation. Bean ;
import org.springframework.context.annotation. Configuration ;
import org.springframework.data.redis.connection.RedisConnectionFactory ;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory ;
import org.springframework.data.redis.core.* ;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer ;
import org.springframework.data.redis.serializer.StringRedisSerializer ;
 
/**
* @Desc redis 配置
* @Date 2020-03-09
* @Author Darben
*/
@Configuration
@EnableCaching
public class RedisConfig {
 
/**
* @Description:
* @Param:
* @return: org.springframework.data.redis.core.RedisTemplate < java.lang.String , java.lang.Object >
* @date: 2020/3/9
*/
@Bean
public RedisTemplate<String , Object> redisTemplate (RedisConnectionFactory factory){
 
RedisTemplate<String , Object> template = new RedisTemplate<>() ;
// 配置连接工厂
template.setConnectionFactory(factory) ;
 
// 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis value 值(默认使用 JDK 的序列化方式)
Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object. class ) ;
 
ObjectMapper om = new ObjectMapper() ;
// 指定要序列化的域, field,get set, 以及修饰符范围, ANY 是都有包括 private public
om.setVisibility(PropertyAccessor. ALL , JsonAutoDetect .Visibility. ANY ) ;
om.enableDefaultTyping(ObjectMapper.DefaultTyping. NON_FINAL ) ;
jsonRedisSerializer.setObjectMapper(om) ;
 
template.setValueSerializer(jsonRedisSerializer) ;
template.setKeySerializer( new StringRedisSerializer()) ;
 
template.setHashValueSerializer(jsonRedisSerializer) ;
template.setHashKeySerializer( new StringRedisSerializer()) ;
template.afterPropertiesSet() ;
 
return template ;
}
 
/*@Bean
public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory factory){
 
RedisTemplate<String,Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
 
// 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis value 值(默认使用 JDK 的序列化方式)
Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
 
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域, field,get set, 以及修饰符范围, ANY 是都有包括 private public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jsonRedisSerializer.setObjectMapper(om);
 
template.setValueSerializer(jsonRedisSerializer);
template.setKeySerializer(new StringRedisSerializer());
 
template.setHashValueSerializer(jsonRedisSerializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
 
return template;
}*/
 
/* 以下 Bean 可以直接注入到 Service 中使用 */
 
/**
* @Description: Redis 字符串 型操作
* @Param:
* @return:
* @date: 2020/3/9
*/
@Bean
public ValueOperations<String , Object> valueOperations (RedisTemplate<String , Object> redisTemplate){
return redisTemplate.opsForValue() ;
}
 
/**
* @Description: List 型操作
* @Param:
* @return:
* @date: 2020/3/9
*/
@Bean
public ListOperations<String , Object> listOperations (RedisTemplate<String , Object> redisTemplate){
return redisTemplate.opsForList() ;
}
 
/**
* @Description: 无序集合 行操作
* @Param:
* @return:
* @date: 2020/3/9
*/
@Bean
public SetOperations<String , Object> setOperations (RedisTemplate<String , Object> redisTemplate){
return redisTemplate.opsForSet() ;
}
 
/**
* @Description: 有序集合 行操作
* @Param:
* @return:
* @date: 2020/3/9
*/
@Bean
public ZSetOperations<String , Object> zSetOperations (RedisTemplate<String , Object> redisTemplate){
return redisTemplate.opsForZSet() ;
}
 
/**
* @Description: hash 行操作
* @Param:
* @return:
* @date: 2020/3/9
*/
@Bean
public HashOperations<String , String , Object> hashOperations (RedisTemplate<String , Object> redisTemplate){
return redisTemplate.opsForHash() ;
}
 
}
 
(3)RedisUtils.java
 
import lombok.extern.slf4j. Slf4j ;
import org.springframework.beans.factory.annotation. Autowired ;
import org.springframework.data.redis.core.RedisTemplate ;
import org.springframework.stereotype. Component ;
import org.springframework.util.CollectionUtils ;
import org.springframework.util.StringUtils ;
 
import java.util.List ;
import java.util.Map ;
import java.util.concurrent.TimeUnit ;
 
/**
* @description: Redis 类组
* @author: darben
* @create: 2020-03-09 15:39
*/
@Component
@Slf4j
public class RedisUtils {
 
@Autowired
private RedisTemplate<String , Object> redisTemplate ;
 
public RedisUtils (RedisTemplate<String , Object> redisTemplate) {
this . redisTemplate = redisTemplate ;
}
 
/**
* @Description:
* @Param:
* key key
* time 失效 时间 位秒
* @return:
* @date: 2020/3/9
*/
public boolean expire (String key ,long time){
try {
if (time> 0 ){
redisTemplate .expire(key , time , TimeUnit. SECONDS ) ;
}
return true;
}
catch (Exception e){
log .error( "-> 设置 redis key 失效时间异常 " + e) ;
e.printStackTrace() ;
return false;
}
}
 
/**
* @Description: 查询 ke 时间
* @Param:
* @return: 时间 ( ) 返回 0 代表 永久有效
* @date: 2020/3/9
*/
public long getExpire (String key){
return redisTemplate .getExpire(key , TimeUnit. SECONDS ) ;
}
 
/**
* @Description:
* @Param: 集合,多 一起
* @return:
* @date: 2020/3/9
*/
public void delKeys (String ... key){
if (key!= null && key. length > 0 ){
if (key. length == 1 ){
redisTemplate .delete(key[ 0 ]) ;
}
else {
redisTemplate .delete(CollectionUtils. arrayToList (key)) ;
}
}
}
 
/**
* @Description:
* @Param: 单个进
* @return:
* @date: 2020/3/9
*/
public boolean del (String key){
if (!StringUtils. isEmpty (key)){
return redisTemplate .delete(key) ;
}
return true;
}
 
/**
* @Description: 持久化 key
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean persist (String key){
return redisTemplate .persist(key) ;
}
 
//String 结构类型处理
//..
 
/**
* @Description: 普通
* @Param:
* @return:
* @date: 2020/3/9
*/
public Object get (String key){
return StringUtils. isEmpty (key)? null : redisTemplate .opsForValue().get(key) ;
}
 
/**
* @Description: 普通 存存
* @Param:
* @return:
* @date: 2020/3/9
*/
public boolean set (String key , Object value){
try {
redisTemplate .opsForValue().set(key , value) ;
return true;
}
catch (Exception e){
log .error( "->set occur error " +e) ;
e.printStackTrace() ;
return false;
}
}
 
/**
* @Description: 普通 存存 + 时间
* @param key
* @param value
* @param time 时间 ( ) time 要大于 0 如果 time 小于等于 0 将设 置无限期
* @return:
* @date: 2020/3/9
*/
public boolean set (String key , Object value ,long time){
try {
redisTemplate .opsForValue().set(key , value , time , TimeUnit. SECONDS ) ;
return true;
}
catch (Exception e){
log .error( "->set occur error " +e) ;
e.printStackTrace() ;
return false;
}
}
 
/**
* @Description: incrby
* @Param:
* @return:
* @date: 2020/3/11
*/
public long incrby (String key ,long delta){
if (delta< 0 ){
throw new RuntimeException( " 递增因子必须大于 0" ) ;
}
return redisTemplate .opsForValue().increment(key , delta) ;
}
 
/**
* @Description: decryb 递减
* @Param:
* @return:
* @date: 2020/3/11
*/
public long decrby (String key ,long delta){
if (delta< 0 ){
throw new RuntimeException( " 递减因子必须大于 0" ) ;
}
return redisTemplate .opsForValue().decrement(key , -delta) ;
}
 
//list 链表结构类型处理
//..
 
/**
* @Description: 查询 key 对应 list 存的
* @Param:
* @return:
* @date: 2020/3/11
*/
public List<Object> lGet (String key ,long start ,long end){
try {
return redisTemplate .opsForList().range(key , start , end) ;
}
catch (Exception e){
log .error( "lGet occur error. " +e) ;
e.printStackTrace() ;
return null;
}
}
 
/**
* @Description: 查询 List 对应
* @Param:
* @return:
* @date: 2020/3/11
*/
public long lGetListSize (String key){
try {
return redisTemplate .opsForList().size(key) ;
}
catch (Exception e){
log .error( "lGetListSize occur error." +e) ;
e.printStackTrace() ;
return 0 ;
}
}
 
/**
* @Description: 索引 list 中的
* @Param:
* @return:
* @date: 2020/3/11
*/
public Object lGetByIndex (String key ,long index){
try {
return redisTemplate .opsForList().index(key , index) ;
}
catch (Exception e){
log .error( "lGetByIndex occur error. " +e) ;
e.printStackTrace() ;
return null;
}
}
 
/**
* @Description: 将数 据存 list
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean rPush (String key , Object value){
try {
redisTemplate .opsForList().rightPush(key , value) ;
return true;
}
catch (Exception e){
log .error( "rPush occur error. " + e) ;
e.printStackTrace() ;
return false;
}
}
 
/**
* @Description:
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean rPush (String key , Object value ,long time){
try {
redisTemplate .opsForList().rightPush(key , value) ;
if (time > 0 ){
expire(key , time) ;
}
return true;
}
catch (Exception e){
log .error( "rPush with expire occur error. " + e) ;
e.printStackTrace() ;
return false;
}
}
 
/**
* @Description: list 行存
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean rPush (String key , List<Object> list){
try {
redisTemplate .opsForList().rightPushAll(key , list) ;
return true;
}
catch (Exception e){
log .error( "rPushAll occur error. " + e) ;
return false;
}
}
 
/**
* @Description: list 行存 + 时间
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean rPush (String key , List<Object> list ,long time){
try {
redisTemplate .opsForList().rightPushAll(key , list) ;
if (time> 0 ){
expire(key , time) ;
}
return true;
}
catch (Exception e){
log .error( "rPushAll occur error. " + e) ;
return false;
}
}
 
/**
* @Description: 根据索引修改 list 中的某 条数
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean lUpdateIndexValue (String key ,long index , Object value){
try {
redisTemplate .opsForList().set(key , index , value) ;
return true;
} catch (Exception e) {
log .error( "lUpdateIndexValue occur error." +e) ;
e.printStackTrace() ;
return false;
}
}
 
 
//HashMap 结构类型处理
//..
 
/**
* @Description: key 对应 map 指定 profile
* @Param:
* @return:
* @date: 2020/3/11
*/
public Object hGet (String key , String profile){
return redisTemplate .opsForHash().get(key , profile) ;
}
 
/**
* @Description: key 对应 Hash
* @Param:
* @return:
* @date: 2020/3/11
*/
public Map<Object , Object> hMget (String key){
return redisTemplate .opsForHash().entries(key) ;
}
 
/**
* @Description: 储值 HashMap
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean hMset (String key , Map<String , Object> map){
try {
redisTemplate .opsForHash().putAll(key , map) ;
return true;
}
catch (Exception e){
log .error( "->hmset occur error " +e) ;
e.printStackTrace() ;
return false;
}
}
 
/**
* @Description: HashMap + 时间
* @Param:
* @return:
* @date: 2020/3/11
*/
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){
log .error( "->hmset with expire time occur error " +e) ;
e.printStackTrace() ;
return false;
}
}
 
/**
* @Description: 向一 hash 表中放入 , 如果不存在 将创
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean hSet (String key , String profiel , Object value , Long time){
try {
redisTemplate .opsForHash().put(key , profiel , value) ;
if (time != null && time.longValue()> 0 ){
expire(key , time) ;
}
return true;
}
catch (Exception e){
log .error( "->hset with expire time occur error " +e) ;
e.printStackTrace() ;
return false;
}
}
 
/**
* @Description: Hash 表中的
* @Param:
* @return:
* @date: 2020/3/11
*/
public void hDel (String key , Object ... profile){
redisTemplate .opsForHash().delete(key , profile) ;
}
 
/**
* @Description: hash 表中是否有 key
* @Param:
* @return:
* @date: 2020/3/11
*/
public boolean hHasKey (String key , String profile){
return redisTemplate .opsForHash().hasKey(key , profile) ;
}
 
 
}
 
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值