一、思路
-
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,有两种方式:
https://raw.githubusercontent.com/MSOpenTech/redis/3.0/src/redis-trib.rb 另存为文件 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>
<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)
;
}
}