redis-4.0.10集群安装(3台机器,6个node),以及在Spring项目中的集成,redis操作工具类

1 Redis安装

redis高可用的三种常见的集群方式:redis sentinel 、redis cluster(多主机+分布式)、redis sharding。接下来主要介绍redis sentinel的部署过程。

1.1 Redis集群安装 (3台机器,6个node)

1.1.1安装前准备

yum install -y gcc
make MALLOC=libc

1.1.2 下载redis软件,解压

将redis上传至/home/bigdata/software,解压redis

cd /home/bigdata/software 
tar -zxvf redis-4.0.10.tar.gz -C /home/bigdata/installed
cd /home/bigdata/installed/redis-4.0.10

1.1.3.创建想要安装的目录:

mkdir -p /usr/local/redis/redis-4.0.10 

1.1.3.编译:

make PREFIX=/usr/local/redis/redis-4.0.10 install(root权限或sudo)

1.1.4.源码目录拷贝redis.conf配置文件

cp redis.conf /usr/local/redis/ redis-4.0.10/redis.conf(可以 在解压的tar.gz包里找到默认的redis.conf

1.1.5.添加环境变量到/etc/profile

#redis
export REDIS_HOME=/usr/local/redis/redis-4.0.10
export PATH=$PATH:$REDIS_HOME/bin

配置完成之后,退出,执行:

source /etc/profile

1.1.6.修改redis配置文件

a、daemonize:改成yes,允许以守护进程方式启动,必改。 
b、bind:默认仅允许本机连上,注释掉以便让任何机器都可以连(为了安全开启密码) c、requirepass改下密码 (test_redis,集群的话暂时不配置)
d、port:默认6379即可。默认端口会比较方便,无需改。 
e、dir:改成/usr/local/redis/redis-4.0.10/standalone 指定rdb、aof文件的生成目录,dir不能指定为文件。可用相对和绝对路径。另外相对路 径是相对于执行启动脚本的目录。配置成./data,在哪里执行启动命令,就在哪里找./data目 录,如果找不到则不能启动。这里写绝对路径会好点。 
f、logfile:可用指定为空。也可以指定到"/usr/local/redis/redis-4.0.10/standalone/6379.log"(文件名随意取会自动产生) 
g、dbfilename:rdb的文件名,改成dump-6379.rdb (产生的路径随dir的配置) 
h、appendonly改成yes i、appendfilename改成appendonly-6379.aof (产生的路径随dir的配置)

启动redis:

[root@bigdata1 redis-4.0.10]# bin/redis-server /usr/local/redis/redis-4.0.10/redis.conf

查看redis进程:

[root@bigdata1 redis-4.0.10]# ps -ef | grep redis
root     13079     1  0 14:07 ?        00:00:00 bin/redis-server *:
root     13096 11631  0 14:07 pts/2    00:00:00 grep --color=auto r
[root@bigdata1 redis-4.0.10]#

连接Redis:

[root@bigdata1 redis-4.0.10] cd /usr/local/redis/redis-4.0.10
[root@bigdata1 redis-4.0.10]# bin/redis-cli -h bigdata1 -p 6379 -a test_redis
Warning: Using a password with '-a' option on the command line interface may not be safe.
bigdata1:6379>

通过此部,可以知道单个redis集群安装完成。

关闭Redis:

方式一:直接kill进程
方式二:redis-cli shutdown(无密码)或 redis-cli a test_redis shutdown(有密 码)

su - root -c 'redis-server /usr/local/redis/redis-4.0.10/redis.conf'

1.2集群安装:

修改/usr/local/redis/redis-4.0.10/redis.conf中的内容,改变下面的内容

cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
protected-mode no

在三台机器上分别复制/usr/local/redis/redis-4.0.10 为 /usr/local/redis/redis-4.0.10-2
将里面的port 改成6378,所有的/usr/local/redis/redis-4.0.10-2/redis.conf 中的redis-4.0.10改成redis-4.0.10-2

安装ruby

[root@bigdata1 software]# cd /home/bigdata/software
[root@bigdata1 software]# tar -zxvf ruby-2.3.3.tar.gz -C /home/bigdata/installed/
[root@bigdata1 software]# cd /home/bigdata/installed/ruby-2.3.3
[root@bigdata1 ruby-2.3.3]# ./configure --prefix=/usr/local/ruby/ruby-2.3.3
[root@bigdata1 ruby-2.3.3]# make #耗时长 
[root@bigdata1 ruby-2.3.3]#y make install

配置ruby的环境变量:

[root@bigdata1 ruby-2.3.3]# vim /etc/profile


# ruby
export RUBY_HOME=/usr/local/ruby/ruby-2.3.3
export PATH=$PATH:$RUBY_HOME/bin

source /etc/profile

安装rubygems:
进入rubygems官网,下载最新的rubygems包。

https://rubygems.org/pages/download#formats

进入

cd /home/bigdata/installed
unzip rubygems-2.7.7.zip
[root@bigdata2 installed]# cd rubygems-2.7.7/ 

然后安装,命令如下:

ruby setup.rb

2)查看ruby v是否能到版本,能得到版本说明安装好了,同时表示ruby加入到环境变 量中了
3)安装好ruby后还要安装openssl,否则尝试gem install redis时会出现如下错误
Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non‐HTTPS sources,则到Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non‐HTTPS sources

4)在安装openssl之前,执行如下命令,输入y同意

yum install --enablerepo=centosplus openssl-devel

5)进入ruby2.3.1目录的ext/openssl目录,执行ruby extconf.rb

[root@bigdata1 ruby-2.3.3]# cd /home/bigdata/installed/ruby-2.3.3/ext/openssl
[root@bigdata1 openssl]# ruby extconf.rb
[root@bigdata1 openssl]# make
[root@bigdata1 openssl]# make install
[root@bigdata1 openssl]# openssl version查看openssl的版本,证明安装好了

6)使用gem安装redis

[root@bigdata2 bin]# pwd
/home/bigdata/installed/rubygems-2.7.7/bin
[root@bigdata2 bin]# ./gem install redis --version 4.0.10 

执行redis的创建集群命令创建集群
进入redis的源码目录:

[root@bigdata1 src]# cd /usr/local/redis/redis/src

将redis-trib.rb拷贝到redis的安装目录(3台机器上分别执行下面的操作):

[root@bigdata1 src]# cp redis-trib.rb /usr/local/redis/redis-4.0.10
[root@bigdata1 src]# cp redis-trib.rb /usr/local/redis/redis-4.0.10-2

查看redis-trib.rb的用法

[root@bigdata2 src]# ./redis-trib.rb
Usage: redis-trib <command> <options> <arguments ...>

  create          host1:port1 ... hostN:portN
                  --replicas <arg>
  check           host:port
  info            host:port
  fix             host:port
                  --timeout <arg>
  reshard         host:port
                  --from <arg>
                  --to <arg>
                  --slots <arg>
                  --yes
                  --timeout <arg>
                  --pipeline <arg>
  rebalance       host:port
                  --weight <arg>
                  --auto-weights
                  --use-empty-masters
                  --timeout <arg>
                  --simulate
                  --pipeline <arg>
                  --threshold <arg>
  add-node        new_host:new_port existing_host:existing_port
                  --slave
                  --master-id <arg>
  del-node        host:port node_id
  set-timeout     host:port milliseconds
  call            host:port command arg arg .. arg
  import          host:port
                  --from <arg>
                  --copy
                  --replace
  help            (show this help)

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
[root@bigdata2 src]#

启动各各redis节点,然后启动集群
下面的xxx.xxx.xxx.为ip的前缀

[root@bigdata1 src]#./redis-trib.rb create --replicas 1 xxx.xxx.xxx.140:6379 xxx.xxx.xxx.140:6378 xxx.xxx.xxx.141:6379 xxx.xxx.xxx.141:6378 xxx.xxx.xxx.142:6379 xxx.xxx.xxx.142:6378
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
bigdata1:6379
bigdata2:6379
bigdata3:6379
Adding replica bigdata2:6378 to bigdata1:6379
Adding replica bigdata3:6378 to bigdata2:6379
Adding replica bigdata1:6378 to bigdata3:6379
M: ffff2d324488baa6612d80d326cc15ce560c5375 bigdata1:6379
   slots:0-5460 (5461 slots) master
S: a4c2b4a75824a58e3b8c4c378da9abbc1bce37db bigdata1:6378
   replicates 9b2cddbe060c292fb53b0925c46e7d4385a2203d
M: 30bc072f6efc950932f63e22a12b2ed3f3da167a bigdata2:6379
   slots:5461-10922 (5462 slots) master
S: 0b90a52a4931dfdd0f50ffb507ba779e32d3446a bigdata2:6378
   replicates ffff2d324488baa6612d80d326cc15ce560c5375
M: 9b2cddbe060c292fb53b0925c46e7d4385a2203d bigdata3:6379
   slots:10923-16383 (5461 slots) master
S: dd05a7c04115d28b9fc0ebbfbfca59ccdfe556c4 bigdata3:6378
   replicates 30bc072f6efc950932f63e22a12b2ed3f3da167a
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
/usr/local/ruby/ruby-2.3.3/lib/ruby/gems/2.3.0/gems/redis-4.0.1/lib/redis/client.rb:119:in `call': ERR Invalid node address specified: bigdata1:6379 (Redis::CommandError)
    from /usr/local/ruby/ruby-2.3.3/lib/ruby/gems/2.3.0/gems/redis-4.0.1/lib/redis.rb:2764:in `block in method_missing'
    from /usr/local/ruby/ruby-2.3.3/lib/ruby/gems/2.3.0/gems/redis-4.0.1/lib/redis.rb:45:in `block in synchronize'
    from /usr/local/ruby/ruby-2.3.3/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
    from /usr/local/ruby/ruby-2.3.3/lib/ruby/gems/2.3.0/gems/redis-4.0.1/lib/redis.rb:45:in `synchronize'
    from /usr/local/ruby/ruby-2.3.3/lib/ruby/gems/2.3.0/gems/redis-4.0.1/lib/redis.rb:2763:in `method_missing'
    from ./redis-trib.rb:941:in `block in join_cluster'
    from ./redis-trib.rb:939:in `each'
    from ./redis-trib.rb:939:in `join_cluster'
    from ./redis-trib.rb:1431:in `create_cluster_cmd'
    from ./redis-trib.rb:1830:in `<main>'
[root@bigdata1 src]#

配置完成之后,执行下面的命令进行查看

 [root@bigdata1 redis-4.0.10]# bin/redis-cli -h bigdata1 -p 6379 -a test_redis
Warning: Using a password with '-a' option on the command line interface may not be safe.
bigdata1:6379> cluster info    #查看集群状态
cluster_state:fail
cluster_slots_assigned:5461
cluster_slots_ok:5461
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:1
cluster_size:1
cluster_current_epoch:1
cluster_my_epoch:1
cluster_stats_messages_sent:0
cluster_stats_messages_received:0
bigdata1:6379> cluster nodes   #查看节点信息
5f1f88c2a4869c51ae57d3f4537bf8da19d070f3 xxx.xxx.xxx.142:6378@16378 slave 64a3926e25023c1d391afb88c2850dfdad72657c 0 1530777080000 6 connected
64a3926e25023c1d391afb88c2850dfdad72657c xxx.xxx.xxx.141:6379@16379 master - 0 1530777080000 3 connected 5461-10922
9f0840b083f5223c0c2278b1e75351bc1172d960 xxx.xxx.xxx.142:6379@16379 master - 0 1530777080673 5 connected 10923-16383
5539fdec71b6be6ebc48a36ba4c642a92b27a215 xxx.xxx.xxx.141:6378@16378 slave 7f51d465030d468bcfae748fdf7760f33a469c0c 0 1530777082677 4 connected
7f51d465030d468bcfae748fdf7760f33a469c0c xxx.xxx.xxx.140:6379@16379 myself,master - 0 1530777081000 1 connected 0-5460
34b0cf0efcaefd3f6de8cdbcdb5d0b9b417c836a xxx.xxx.xxx.140:6378@16378 slave 9f0840b083f5223c0c2278b1e75351bc1172d960 0 1530777081675 5 connected
bigdata1:6379> 

同样可以使用命令:

[root@bigdata2 src]# ./redis-trib.rb info bigdata1:6379
bigdata1:6379 (ffff2d32...) -> 0 keys | 5461 slots | 0 slaves.
[OK] 0 keys in 1 masters.
0.00 keys per slot on average.
[root@bigdata2 src]# ./redis-trib.rb info bigdata1:6378
bigdata1:6378 (a4c2b4a7...) -> 0 keys | 0 slots | 0 slaves.
[OK] 0 keys in 1 masters.
0.00 keys per slot on average.
[root@bigdata2 src]# ./redis-trib.rb info bigdata2:6378
bigdata2:6378 (0b90a52a...) -> 0 keys | 0 slots | 0 slaves.
[OK] 0 keys in 1 masters.
0.0 keys per slot on average.

再如:

[root@bigdata2 redis-4.0.10]# bin/redis-cli -h bigdata2
bigdata2:6379> info
# Server
redis_version:4.0.10
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:8302a44837507475
redis_mode:cluster
os:Linux 3.10.0-693.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.5
process_id:19732
run_id:81a5378421b525b1c97351322949b030c93cc567
tcp_port:6379
uptime_in_seconds:2941
uptime_in_days:0
hz:10
lru_clock:3973023
executable:/usr/local/redis/redis-4.0.10/bin/redis-server
config_file:/usr/local/redis/redis-4.0.10/redis.conf

# Clients
connected_clients:2
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:1529224
used_memory_human:1.46M
used_memory_rss:9994240
used_memory_rss_human:9.53M
used_memory_peak:1559408
used_memory_peak_human:1.49M
used_memory_peak_perc:98.06%
used_memory_overhead:1511488
used_memory_startup:1445000
used_memory_dataset:17736
used_memory_dataset_perc:21.06%
total_system_memory:16547332096
total_system_memory_human:15.41G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:6.53
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1530696738
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:0
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0
aof_current_size:0
aof_base_size:0
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0

# Stats
total_connections_received:4
total_commands_processed:17
instantaneous_ops_per_sec:0
total_net_input_bytes:55966
total_net_output_bytes:30041
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Replication
role:master
connected_slaves:0
master_replid:330bc27779b0a28f762a8725d37adff9cde477af
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:1.13
used_cpu_user:0.78
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Cluster
cluster_enabled:1

# Keyspace
bigdata2:6379>

在直接使用jedis使用程序连接的时候,报如下问题:

redis.clients.jedis.exceptions.JedisClusterException:CLUSTERDOWN The cluster is down

解决办法是:
./redis-trib.rb check xxx.xxx.xxx.142:6379 通过这种命令检查各各节点。发现会报如下问题:

[ERR] Not all 16384 slots are covered by nodes

./redis-trib.rb fix xxx.xxx.xxx.142:6379 通过这个命令解决上面的问题

查看当前redis的连接数量,使用:info clients。

[root@bigdata1 redis-4.0.10-2]# bin/redis-cli -h bigdata1
bigdata1:6379> info clients
# Clients
connected_clients:3
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

查看支持的最大连接数使用config get maxclients

bigdata1:6379> config get maxclients
1) "maxclients"
2) "10000"
bigdata1:6379>

关闭redis的保护模式:

[root@bigdata1 redis-4.0.10-2]# bin/redis-cli -h bigdata3 -p 6379 -a test_redis
[root@bigdata1 redis-4.0.10-2]# bin/redis-cli -h bigdata3 -p 6378 -a test_redis
Warning: Using a password with '-a' option on the command line interface may not be safe.
bigdata3:6378> config get protected-mode
1) "protected-mode"
2) "yes"
bigdata3:6378> config set protected-mode "no"
OK

1.3 和Spring继承

1.3.1 添加maven pom依赖

<aspectjweaver.version>1.8.3</aspectjweaver.version>
<redis.clients.version>2.9.0</redis.clients.version>


<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspectjweaver.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>${redis.clients.version}</version>
</dependency>

1.3.2 编写Spring的属性文件

#JedisPoolConfig的参数
#最大连接数,发现当每次最小话300的时候,在第18次启动的时候启动不起来了,连接不够了。
redis.pool.maxTotal=4000
#最大空闲时间
redis.pool.maxIdle=300
#最小连接数
redis.pool.minIdle=5
#每次最大连接数
redis.pool.numTestsPerEvictionRun=1024
#释放扫描的扫描间隔
redis.pool.timeBetweenEvictionRunsMillis=30000
#连接的最小空闲时间
redis.pool.minEvictableIdleTimeMillis=1800000
#连接控歘按时间多久后释放,当空闲时间>该值且空闲连接>最大空闲连接数时直接释放
redis.pool.softMinEvictableIdleTimeMillis=10000
#获得链接时的最大等待毫秒数,小于0:阻塞不确定时间,默认-1
redis.pool.maxWaitMillis=3000
#在获得链接的时候检查有效性,默认false
redis.pool.testOnBorrow=true
#在空闲时检查有效性,默认false
redis.pool.testWhileIdle=true
#连接耗尽时是否阻塞,false报异常,true阻塞超时,默认true
redis.pool.blockWhenExhausted=false
#RedisClusterConfiguration配置
redis.maxRedirects=5

#主机和端口号
redis.host1=xxx.xxx.xxx.140
redis.port1=6379

redis.host2=xxx.xxx.xxx.140
redis.port2=6378

redis.host3=xxx.xxx.xxx.141
redis.port3=6379

redis.host4=xxx.xxx.xxx.141
redis.port4=6378

redis.host5=xxx.xxx.xxx.142
redis.port5=6379

redis.host6=xxx.xxx.xxx.142
redis.port6=6378

redis.password=test_redis
redis.dataBase=0

#单redis节点
redis.host=xxx.xxx.xxx.141
redis.port=6377

1.3.2 添加Spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置redis-->
    <!-- redis 相关配置 -->
    <bean id="baseRedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大连接数 -->
        <property name="maxTotal" value="${redis.pool.maxTotal}" />
        <!-- 最大空闲时间 -->
        <property name="maxIdle" value="${redis.pool.maxIdle}" />
        <!-- 最小连接数 -->
        <property name="minIdle" value="${redis.pool.minIdle}" />
        <!-- 每次最大连接数 -->
        <property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}" />
        <!-- 释放扫描的扫描间隔 -->
        <property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}" />
        <!-- 连接的最小空闲时间 -->
        <property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}" />
        <!-- 连接控歘按时间多久后释放,当空闲时间>该值且空闲连接>最大空闲连接数时直接释放 -->
        <property name="softMinEvictableIdleTimeMillis" value="${redis.pool.softMinEvictableIdleTimeMillis}" />
        <!-- 获得链接时的最大等待毫秒数,小于0:阻塞不确定时间,默认-1 -->
        <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
        <!-- 在获得链接的时候检查有效性,默认false -->
        <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
        <!-- 在空闲时检查有效性,默认false -->
        <property name="testWhileIdle" value="${redis.pool.testWhileIdle}" />
        <!-- 连接耗尽时是否阻塞,false报异常,true阻塞超时,默认true -->
        <property name="blockWhenExhausted" value="${redis.pool.blockWhenExhausted}" />
    </bean>

    <!--配置RedisClusterConfiguration-->
    <bean id="baseRedisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
        <property name="maxRedirects" value="${redis.maxRedirects}" />
        <property name="clusterNodes">
            <set>
                <bean class="org.springframework.data.redis.connection.RedisClusterNode">
                    <constructor-arg name="host" value="${redis.host1}" />
                    <constructor-arg name="port" value="${redis.port1}"/>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisClusterNode">
                    <constructor-arg name="host" value="${redis.host2}" />
                    <constructor-arg name="port" value="${redis.port2}" />
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisClusterNode">
                    <constructor-arg name="host" value="${redis.host3}" />
                    <constructor-arg name="port" value="${redis.port3}" />
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisClusterNode">
                    <constructor-arg name="host" value="${redis.host4}" />
                    <constructor-arg name="port" value="${redis.port4}" />
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisClusterNode">
                    <constructor-arg name="host" value="${redis.host5}" />
                    <constructor-arg name="port" value="${redis.port5}" />
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisClusterNode">
                    <constructor-arg name="host" value="${redis.host6}" />
                    <constructor-arg name="port" value="${redis.port6}" />
                </bean>
            </set>
        </property>
    </bean>

    <!-- 单个redis场景设置,单集的时候放开下面的代码 -->
    <bean id="baseJedisConnFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
        <property name="hostName" value="${redis.host}" />
        <property name="port" value="${redis.port}" />
        <property name="password" value ="${redis.password}" />
        <property name="usePool" value="true" />
        <property name="poolConfig" ref="baseRedisPoolConfig" />
    </bean>

    <!--集群场景下的配置,集群的时候,放开下面的配置-->
    <!--<bean id="baseJedisConnFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
        <constructor-arg name="poolConfig" ref="baseRedisPoolConfig" />
        <constructor-arg name="clusterConfig" ref="baseRedisClusterConfiguration" />
        &lt;!&ndash;<property name="password" value ="${redis.password}" />&ndash;&gt;
        <property name="usePool" value="true" />
        <property name="database" value="${redis.dataBase}" />
    </bean>-->

    <!-- redis template definition -->
    <bean id="baseRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="baseJedisConnFactory" />
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
    </bean>

    <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
        <property name="connectionFactory" ref="baseJedisConnFactory" />
    </bean>

    <bean id="redisUtil" class="com.xxx.redis.util.RedisUtil">
        <property name="stringRedisTemplate" ref="stringRedisTemplate" />
        <property name="redisTemplate" ref="baseRedisTemplate"/>
    </bean>
</beans>

1.4 示例redis操作的代码

package com.xxx.redis.util;

import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;

import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

/**
 * Redis工具类
 *
 * 参考地址:http://hbxflihua.iteye.com/blog/2328156
 *           (GitHub文档: https://github.com/whvcse/RedisUtil )
 *
 * @author WangFan
 * @date 2018-02-24 下午03:09:50
 * @version 1.1 (GitHub文档: https://github.com/whvcse/RedisUtil )
 */
public class RedisUtil {
    private StringRedisTemplate stringRedisTemplate;
    private RedisTemplate<Serializable, Object> redisTemplate;

    public StringRedisTemplate getStringRedisTemplate() {
        return stringRedisTemplate;
    }

    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public RedisTemplate<Serializable, Object> getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate<Serializable, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /** -------------------key相关操作--------------------- */

    /**
     * 删除key
     *
     * @param key
     */
    public void delete(String key) {
        stringRedisTemplate.delete(key);
    }

    /**
     * 批量删除key
     *
     * @param keys
     */
    public void delete(Collection<String> keys) {
        stringRedisTemplate.delete(keys);
    }

    /**
     * 序列化key
     *
     * @param key
     * @return
     */
    public byte[] dump(String key) {
        return stringRedisTemplate.dump(key);
    }

    /**
     * 是否存在key
     *
     * @param key
     * @return
     */
    public Boolean hasKey(String key) {
        return stringRedisTemplate.hasKey(key);
    }

    /**
     * 设置过期时间
     *
     * @param key
     * @param timeout
     * @param unit
     * @return
     */
    public Boolean expire(String key, long timeout, TimeUnit unit) {
        return stringRedisTemplate.expire(key, timeout, unit);
    }

    /**
     * 设置过期时间
     *
     * @param key
     * @param date
     * @return
     */
    public Boolean expireAt(String key, Date date) {
        return stringRedisTemplate.expireAt(key, date);
    }

    /**
     * 查找匹配的key
     *
     * @param pattern
     * @return
     */
    public Set<String> keys(String pattern) {
        return stringRedisTemplate.keys(pattern);
    }

    /**
     * 将当前数据库的 key 移动到给定的数据库 db 当中
     *
     * @param key
     * @param dbIndex
     * @return
     */
    public Boolean move(String key, int dbIndex) {
        return stringRedisTemplate.move(key, dbIndex);
    }

    /**
     * 移除 key 的过期时间,key 将持久保持
     *
     * @param key
     * @return
     */
    public Boolean persist(String key) {
        return stringRedisTemplate.persist(key);
    }

    /**
     * 返回 key 的剩余的过期时间
     *
     * @param key
     * @param unit
     * @return
     */
    public Long getExpire(String key, TimeUnit unit) {
        return stringRedisTemplate.getExpire(key, unit);
    }

    /**
     * 返回 key 的剩余的过期时间
     *
     * @param key
     * @return
     */
    public Long getExpire(String key) {
        return stringRedisTemplate.getExpire(key);
    }

    /**
     * 从当前数据库中随机返回一个 key
     *
     * @return
     */
    public String randomKey() {
        return stringRedisTemplate.randomKey();
    }

    /**
     * 修改 key 的名称
     *
     * @param oldKey
     * @param newKey
     */
    public void rename(String oldKey, String newKey) {
        stringRedisTemplate.rename(oldKey, newKey);
    }

    /**
     * 仅当 newkey 不存在时,将 oldKey 改名为 newkey
     *
     * @param oldKey
     * @param newKey
     * @return
     */
    public Boolean renameIfAbsent(String oldKey, String newKey) {
        return stringRedisTemplate.renameIfAbsent(oldKey, newKey);
    }

    /**
     * 返回 key 所储存的值的类型
     *
     * @param key
     * @return
     */
    public DataType type(String key) {
        return stringRedisTemplate.type(key);
    }

    /** -------------------string相关操作--------------------- */

    /**
     * 设置指定 key 的值
     * @param key
     * @param value
     */
    public void setString(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    /**
     * 获取指定 key 的值
     * @param key
     * @return
     */
    public String getString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * 返回 key 中字符串值的子字符
     * @param key
     * @param start
     * @param end
     * @return
     */
    public String getRange(String key, long start, long end) {
        return stringRedisTemplate.opsForValue().get(key, start, end);
    }

    /**
     * 将给定 key 的值设为 value ,并返回 key 的旧值(old value)
     *
     * @param key
     * @param value
     * @return
     */
    public String getAndSet(String key, String value) {
        return stringRedisTemplate.opsForValue().getAndSet(key, value);
    }

    /**
     * 对 key 所储存的字符串值,获取指定偏移量上的位(bit)
     *
     * @param key
     * @param offset
     * @return
     */
    public Boolean getBit(String key, long offset) {
        return stringRedisTemplate.opsForValue().getBit(key, offset);
    }

    /**
     * 批量获取
     *
     * @param keys
     * @return
     */
    public List<String> multiGet(Collection<String> keys) {
        return stringRedisTemplate.opsForValue().multiGet(keys);
    }

    /**
     * 设置ASCII码, 字符串'a'的ASCII码是97, 转为二进制是'01100001', 此方法是将二进制第offset位值变为value
     *
     * @param key
     * @param offset
     *            位置
     * @param value
     *            值,true为1, false为0
     * @return
     */
    public boolean setBit(String key, long offset, boolean value) {
        return stringRedisTemplate.opsForValue().setBit(key, offset, value);
    }

    /**
     * 将值 value 关联到 key ,并将 key 的过期时间设为 timeout
     *
     * @param key
     * @param value
     * @param timeout
     *            过期时间
     * @param unit
     *            时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES
     *            秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     */
    public void setEx(String key, String value, long timeout, TimeUnit unit) {
        stringRedisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    /**
     * 只有在 key 不存在时设置 key 的值
     *
     * @param key
     * @param value
     * @return 之前已经存在返回false,不存在返回true
     */
    public boolean setIfAbsent(String key, String value) {
        return stringRedisTemplate.opsForValue().setIfAbsent(key, value);
    }

    /**
     * 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始
     *
     * @param key
     * @param value
     * @param offset
     *            从指定位置开始覆写
     */
    public void setRange(String key, String value, long offset) {
        stringRedisTemplate.opsForValue().set(key, value, offset);
    }

    /**
     * 获取字符串的长度
     *
     * @param key
     * @return
     */
    public Long size(String key) {
        return stringRedisTemplate.opsForValue().size(key);
    }

    /**
     * 批量添加
     *
     * @param maps
     */
    public void multiSet(Map<String, String> maps) {
        stringRedisTemplate.opsForValue().multiSet(maps);
    }

    /**
     * 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
     *
     * @param maps
     * @return 之前已经存在返回false,不存在返回true
     */
    public boolean multiSetIfAbsent(Map<String, String> maps) {
        return stringRedisTemplate.opsForValue().multiSetIfAbsent(maps);
    }

    /**
     * 增加(自增长), 负数则为自减
     *
     * @param key
     * @param increment
     * @return
     */
    public Long incrBy(String key, long increment) {
        return stringRedisTemplate.opsForValue().increment(key, increment);
    }

    /**
     *
     * @param key
     * @param increment
     * @return
     */
    public Double incrByFloat(String key, double increment) {
        return stringRedisTemplate.opsForValue().increment(key, increment);
    }

    /**
     * 追加到末尾
     *
     * @param key
     * @param value
     * @return
     */
    public Integer append(String key, String value) {
        return stringRedisTemplate.opsForValue().append(key, value);
    }

    /** -------------------hash相关操作------------------------- */

    /**
     * 获取存储在哈希表中指定字段的值
     *
     * @param key
     * @param field
     * @return
     */
    public Object hGet(String key, String field) {
        return stringRedisTemplate.opsForHash().get(key, field);
    }

    /**
     * 获取所有给定字段的值
     *
     * @param key
     * @return
     */
    public Map<Object, Object> hGetAll(String key) {
        return stringRedisTemplate.opsForHash().entries(key);
    }

    /**
     * 获取所有给定字段的值
     *
     * @param key
     * @param fields
     * @return
     */
    public List<Object> hMultiGet(String key, Collection<Object> fields) {
        return stringRedisTemplate.opsForHash().multiGet(key, fields);
    }

    public void hPut(String key, String hashKey, String value) {
        stringRedisTemplate.opsForHash().put(key, hashKey, value);
    }

    public void hPutAll(String key, Map<String, String> maps) {
        stringRedisTemplate.opsForHash().putAll(key, maps);
    }

    /**
     * 仅当hashKey不存在时才设置
     *
     * @param key
     * @param hashKey
     * @param value
     * @return
     */
    public Boolean hPutIfAbsent(String key, String hashKey, String value) {
        return stringRedisTemplate.opsForHash().putIfAbsent(key, hashKey, value);
    }

    /**
     * 删除一个或多个哈希表字段
     *
     * @param key
     * @param fields
     * @return
     */
    public Long hDelete(String key, Object... fields) {
        return stringRedisTemplate.opsForHash().delete(key, fields);
    }

    /**
     * 查看哈希表 key 中,指定的字段是否存在
     *
     * @param key
     * @param field
     * @return
     */
    public boolean hExists(String key, String field) {
        return stringRedisTemplate.opsForHash().hasKey(key, field);
    }

    /**
     * 为哈希表 key 中的指定字段的整数值加上增量 increment
     *
     * @param key
     * @param field
     * @param increment
     * @return
     */
    public Long hIncrBy(String key, Object field, long increment) {
        return stringRedisTemplate.opsForHash().increment(key, field, increment);
    }

    /**
     * 为哈希表 key 中的指定字段的整数值加上增量 increment
     *
     * @param key
     * @param field
     * @param delta
     * @return
     */
    public Double hIncrByFloat(String key, Object field, double delta) {
        return stringRedisTemplate.opsForHash().increment(key, field, delta);
    }

    /**
     * 获取所有哈希表中的字段
     *
     * @param key
     * @return
     */
    public Set<Object> hKeys(String key) {
        return stringRedisTemplate.opsForHash().keys(key);
    }

    /**
     * 获取哈希表中字段的数量
     *
     * @param key
     * @return
     */
    public Long hSize(String key) {
        return stringRedisTemplate.opsForHash().size(key);
    }

    /**
     * 获取哈希表中所有值
     *
     * @param key
     * @return
     */
    public List<Object> hValues(String key) {
        return stringRedisTemplate.opsForHash().values(key);
    }

    /**
     * 迭代哈希表中的键值对
     *
     * @param key
     * @param options
     * @return
     */
    public Cursor<Entry<Object, Object>> hScan(String key, ScanOptions options) {
        return stringRedisTemplate.opsForHash().scan(key, options);
    }

    /** ------------------------list相关操作---------------------------- */

    /**
     * 通过索引获取列表中的元素
     *
     * @param key
     * @param index
     * @return
     */
    public String lIndex(String key, long index) {
        return stringRedisTemplate.opsForList().index(key, index);
    }

    /**
     * 获取列表指定范围内的元素
     *
     * @param key
     * @param start
     *            开始位置, 0是开始位置
     * @param end
     *            结束位置, -1返回所有
     * @return
     */
    public List<String> lRange(String key, long start, long end) {
        return stringRedisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 存储在list头部
     *
     * @param key
     * @param value
     * @return
     */
    public Long lLeftPush(String key, String value) {
        return stringRedisTemplate.opsForList().leftPush(key, value);
    }

    /**
     *
     * @param key
     * @param value
     * @return
     */
    public Long lLeftPushAll(String key, String... value) {
        return stringRedisTemplate.opsForList().leftPushAll(key, value);
    }

    /**
     *
     * @param key
     * @param value
     * @return
     */
    public Long lLeftPushAll(String key, Collection<String> value) {
        return stringRedisTemplate.opsForList().leftPushAll(key, value);
    }

    /**
     * 当list存在的时候才加入
     *
     * @param key
     * @param value
     * @return
     */
    public Long lLeftPushIfPresent(String key, String value) {
        return stringRedisTemplate.opsForList().leftPushIfPresent(key, value);
    }

    /**
     * 如果pivot存在,再pivot前面添加
     *
     * @param key
     * @param pivot
     * @param value
     * @return
     */
    public Long lLeftPush(String key, String pivot, String value) {
        return stringRedisTemplate.opsForList().leftPush(key, pivot, value);
    }

    /**
     *
     * @param key
     * @param value
     * @return
     */
    public Long lRightPush(String key, String value) {
        return stringRedisTemplate.opsForList().rightPush(key, value);
    }

    /**
     *
     * @param key
     * @param value
     * @return
     */
    public Long lRightPushAll(String key, String... value) {
        return stringRedisTemplate.opsForList().rightPushAll(key, value);
    }

    /**
     *
     * @param key
     * @param value
     * @return
     */
    public Long lRightPushAll(String key, Collection<String> value) {
        return stringRedisTemplate.opsForList().rightPushAll(key, value);
    }

    /**
     * 为已存在的列表添加值
     *
     * @param key
     * @param value
     * @return
     */
    public Long lRightPushIfPresent(String key, String value) {
        return stringRedisTemplate.opsForList().rightPushIfPresent(key, value);
    }

    /**
     * 在pivot元素的右边添加值
     *
     * @param key
     * @param pivot
     * @param value
     * @return
     */
    public Long lRightPush(String key, String pivot, String value) {
        return stringRedisTemplate.opsForList().rightPush(key, pivot, value);
    }

    /**
     * 通过索引设置列表元素的值
     *
     * @param key
     * @param index
     *            位置
     * @param value
     */
    public void lSet(String key, long index, String value) {
        stringRedisTemplate.opsForList().set(key, index, value);
    }

    /**
     * 移出并获取列表的第一个元素
     *
     * @param key
     * @return 删除的元素
     */
    public String lLeftPop(String key) {
        return stringRedisTemplate.opsForList().leftPop(key);
    }

    /**
     * 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param key
     * @param timeout
     *            等待时间
     * @param unit
     *            时间单位
     * @return
     */
    public String lBLeftPop(String key, long timeout, TimeUnit unit) {
        return stringRedisTemplate.opsForList().leftPop(key, timeout, unit);
    }

    /**
     * 移除并获取列表最后一个元素
     *
     * @param key
     * @return 删除的元素
     */
    public String lRightPop(String key) {
        return stringRedisTemplate.opsForList().rightPop(key);
    }

    /**
     * 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param key
     * @param timeout
     *            等待时间
     * @param unit
     *            时间单位
     * @return
     */
    public String lBRightPop(String key, long timeout, TimeUnit unit) {
        return stringRedisTemplate.opsForList().rightPop(key, timeout, unit);
    }

    /**
     * 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
     *
     * @param sourceKey
     * @param destinationKey
     * @return
     */
    public String lRightPopAndLeftPush(String sourceKey, String destinationKey) {
        return stringRedisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
                destinationKey);
    }

    /**
     * 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param sourceKey
     * @param destinationKey
     * @param timeout
     * @param unit
     * @return
     */
    public String lBRightPopAndLeftPush(String sourceKey, String destinationKey,
            long timeout, TimeUnit unit) {
        return stringRedisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
                destinationKey, timeout, unit);
    }

    /**
     * 删除集合中值等于value得元素
     *
     * @param key
     * @param index
     *            index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素;
     *            index<0, 从尾部开始删除第一个值等于value的元素;
     * @param value
     * @return
     */
    public Long lRemove(String key, long index, String value) {
        return stringRedisTemplate.opsForList().remove(key, index, value);
    }

    /**
     * 裁剪list
     *
     * @param key
     * @param start
     * @param end
     */
    public void lTrim(String key, long start, long end) {
        stringRedisTemplate.opsForList().trim(key, start, end);
    }

    /**
     * 获取列表长度
     *
     * @param key
     * @return
     */
    public Long lLen(String key) {
        return stringRedisTemplate.opsForList().size(key);
    }

    /** --------------------set相关操作-------------------------- */

    /**
     * set添加元素
     *
     * @param key
     * @param values
     * @return
     */
    public Long sAdd(String key, String... values) {
        return stringRedisTemplate.opsForSet().add(key, values);
    }

    /**
     * set移除元素
     *
     * @param key
     * @param values
     * @return
     */
    public Long sRemove(String key, Object... values) {
        return stringRedisTemplate.opsForSet().remove(key, values);
    }

    /**
     * 移除并返回集合的一个随机元素
     *
     * @param key
     * @return
     */
    public String sPop(String key) {
        return stringRedisTemplate.opsForSet().pop(key);
    }

    /**
     * 将元素value从一个集合移到另一个集合
     *
     * @param key
     * @param value
     * @param destKey
     * @return
     */
    public Boolean sMove(String key, String value, String destKey) {
        return stringRedisTemplate.opsForSet().move(key, value, destKey);
    }

    /**
     * 获取集合的大小
     *
     * @param key
     * @return
     */
    public Long sSize(String key) {
        return stringRedisTemplate.opsForSet().size(key);
    }

    /**
     * 判断集合是否包含value
     *
     * @param key
     * @param value
     * @return
     */
    public Boolean sIsMember(String key, Object value) {
        return stringRedisTemplate.opsForSet().isMember(key, value);
    }

    /**
     * 获取两个集合的交集
     *
     * @param key
     * @param otherKey
     * @return
     */
    public Set<String> sIntersect(String key, String otherKey) {
        return stringRedisTemplate.opsForSet().intersect(key, otherKey);
    }

    /**
     * 获取key集合与多个集合的交集
     *
     * @param key
     * @param otherKeys
     * @return
     */
    public Set<String> sIntersect(String key, Collection<String> otherKeys) {
        return stringRedisTemplate.opsForSet().intersect(key, otherKeys);
    }

    /**
     * key集合与otherKey集合的交集存储到destKey集合中
     *
     * @param key
     * @param otherKey
     * @param destKey
     * @return
     */
    public Long sIntersectAndStore(String key, String otherKey, String destKey) {
        return stringRedisTemplate.opsForSet().intersectAndStore(key, otherKey,
                destKey);
    }

    /**
     * key集合与多个集合的交集存储到destKey集合中
     *
     * @param key
     * @param otherKeys
     * @param destKey
     * @return
     */
    public Long sIntersectAndStore(String key, Collection<String> otherKeys,
            String destKey) {
        return stringRedisTemplate.opsForSet().intersectAndStore(key, otherKeys,
                destKey);
    }

    /**
     * 获取两个集合的并集
     *
     * @param key
     * @param otherKeys
     * @return
     */
    public Set<String> sUnion(String key, String otherKeys) {
        return stringRedisTemplate.opsForSet().union(key, otherKeys);
    }

    /**
     * 获取key集合与多个集合的并集
     *
     * @param key
     * @param otherKeys
     * @return
     */
    public Set<String> sUnion(String key, Collection<String> otherKeys) {
        return stringRedisTemplate.opsForSet().union(key, otherKeys);
    }

    /**
     * key集合与otherKey集合的并集存储到destKey中
     *
     * @param key
     * @param otherKey
     * @param destKey
     * @return
     */
    public Long sUnionAndStore(String key, String otherKey, String destKey) {
        return stringRedisTemplate.opsForSet().unionAndStore(key, otherKey, destKey);
    }

    /**
     * key集合与多个集合的并集存储到destKey中
     *
     * @param key
     * @param otherKeys
     * @param destKey
     * @return
     */
    public Long sUnionAndStore(String key, Collection<String> otherKeys,
            String destKey) {
        return stringRedisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey);
    }

    /**
     * 获取两个集合的差集
     *
     * @param key
     * @param otherKey
     * @return
     */
    public Set<String> sDifference(String key, String otherKey) {
        return stringRedisTemplate.opsForSet().difference(key, otherKey);
    }

    /**
     * 获取key集合与多个集合的差集
     *
     * @param key
     * @param otherKeys
     * @return
     */
    public Set<String> sDifference(String key, Collection<String> otherKeys) {
        return stringRedisTemplate.opsForSet().difference(key, otherKeys);
    }

    /**
     * key集合与otherKey集合的差集存储到destKey中
     *
     * @param key
     * @param otherKey
     * @param destKey
     * @return
     */
    public Long sDifference(String key, String otherKey, String destKey) {
        return stringRedisTemplate.opsForSet().differenceAndStore(key, otherKey,
                destKey);
    }

    /**
     * key集合与多个集合的差集存储到destKey中
     *
     * @param key
     * @param otherKeys
     * @param destKey
     * @return
     */
    public Long sDifference(String key, Collection<String> otherKeys,
            String destKey) {
        return stringRedisTemplate.opsForSet().differenceAndStore(key, otherKeys,
                destKey);
    }

    /**
     * 获取集合所有元素
     *
     * @param key
     * @return
     */
    public Set<String> setMembers(String key) {
        return stringRedisTemplate.opsForSet().members(key);
    }

    /**
     * 随机获取集合中的一个元素
     *
     * @param key
     * @return
     */
    public String sRandomMember(String key) {
        return stringRedisTemplate.opsForSet().randomMember(key);
    }

    /**
     * 随机获取集合中count个元素
     *
     * @param key
     * @param count
     * @return
     */
    public List<String> sRandomMembers(String key, long count) {
        return stringRedisTemplate.opsForSet().randomMembers(key, count);
    }

    /**
     * 随机获取集合中count个元素并且去除重复的
     *
     * @param key
     * @param count
     * @return
     */
    public Set<String> sDistinctRandomMembers(String key, long count) {
        return stringRedisTemplate.opsForSet().distinctRandomMembers(key, count);
    }

    /**
     *
     * @param key
     * @param options
     * @return
     */
    public Cursor<String> sScan(String key, ScanOptions options) {
        return stringRedisTemplate.opsForSet().scan(key, options);
    }

    /**------------------zSet相关操作--------------------------------*/

    /**
     * 添加元素,有序集合是按照元素的score值由小到大排列
     *
     * @param key
     * @param value
     * @param score
     * @return
     */
    public Boolean zAdd(String key, String value, double score) {
        return stringRedisTemplate.opsForZSet().add(key, value, score);
    }

    /**
     *
     * @param key
     * @param values
     * @return
     */
    public Long zAdd(String key, Set<TypedTuple<String>> values) {
        return stringRedisTemplate.opsForZSet().add(key, values);
    }

    /**
     *
     * @param key
     * @param values
     * @return
     */
    public Long zRemove(String key, Object... values) {
        return stringRedisTemplate.opsForZSet().remove(key, values);
    }

    /**
     * 增加元素的score值,并返回增加后的值
     *
     * @param key
     * @param value
     * @param delta
     * @return
     */
    public Double zIncrementScore(String key, String value, double delta) {
        return stringRedisTemplate.opsForZSet().incrementScore(key, value, delta);
    }

    /**
     * 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
     *
     * @param key
     * @param value
     * @return 0表示第一位
     */
    public Long zRank(String key, Object value) {
        return stringRedisTemplate.opsForZSet().rank(key, value);
    }

    /**
     * 返回元素在集合的排名,按元素的score值由大到小排列
     *
     * @param key
     * @param value
     * @return
     */
    public Long zReverseRank(String key, Object value) {
        return stringRedisTemplate.opsForZSet().reverseRank(key, value);
    }

    /**
     * 获取集合的元素, 从小到大排序
     *
     * @param key
     * @param start
     *            开始位置
     * @param end
     *            结束位置, -1查询所有
     * @return
     */
    public Set<String> zRange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().range(key, start, end);
    }

    /**
     * 获取集合元素, 并且把score值也获取
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<TypedTuple<String>> zRangeWithScores(String key, long start,
            long end) {
        return stringRedisTemplate.opsForZSet().rangeWithScores(key, start, end);
    }

    /**
     * 根据Score值查询集合元素
     *
     * @param key
     * @param min
     *            最小值
     * @param max
     *            最大值
     * @return
     */
    public Set<String> zRangeByScore(String key, double min, double max) {
        return stringRedisTemplate.opsForZSet().rangeByScore(key, min, max);
    }

    /**
     * 根据Score值查询集合元素, 从小到大排序
     *
     * @param key
     * @param min
     *            最小值
     * @param max
     *            最大值
     * @return
     */
    public Set<TypedTuple<String>> zRangeByScoreWithScores(String key,
            double min, double max) {
        return stringRedisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
    }

    /**
     *
     * @param key
     * @param min
     * @param max
     * @param start
     * @param end
     * @return
     */
    public Set<TypedTuple<String>> zRangeByScoreWithScores(String key,
            double min, double max, long start, long end) {
        return stringRedisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max,
                start, end);
    }

    /**
     * 获取集合的元素, 从大到小排序
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<String> zReverseRange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().reverseRange(key, start, end);
    }

    /**
     * 获取集合的元素, 从大到小排序, 并返回score值
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<TypedTuple<String>> zReverseRangeWithScores(String key,
            long start, long end) {
        return stringRedisTemplate.opsForZSet().reverseRangeWithScores(key, start,
                end);
    }

    /**
     * 根据Score值查询集合元素, 从大到小排序
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Set<String> zReverseRangeByScore(String key, double min,
            double max) {
        return stringRedisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
    }

    /**
     * 根据Score值查询集合元素, 从大到小排序
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Set<TypedTuple<String>> zReverseRangeByScoreWithScores(
            String key, double min, double max) {
        return stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(key,
                min, max);
    }

    /**
     *
     * @param key
     * @param min
     * @param max
     * @param start
     * @param end
     * @return
     */
    public Set<String> zReverseRangeByScore(String key, double min,
            double max, long start, long end) {
        return stringRedisTemplate.opsForZSet().reverseRangeByScore(key, min, max,
                start, end);
    }

    /**
     * 根据score值获取集合元素数量
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Long zCount(String key, double min, double max) {
        return stringRedisTemplate.opsForZSet().count(key, min, max);
    }

    /**
     * 获取集合大小
     *
     * @param key
     * @return
     */
    public Long zSize(String key) {
        return stringRedisTemplate.opsForZSet().size(key);
    }

    /**
     * 获取集合大小
     *
     * @param key
     * @return
     */
    public Long zZCard(String key) {
        return stringRedisTemplate.opsForZSet().zCard(key);
    }

    /**
     * 获取集合中value元素的score值
     *
     * @param key
     * @param value
     * @return
     */
    public Double zScore(String key, Object value) {
        return stringRedisTemplate.opsForZSet().score(key, value);
    }

    /**
     * 移除指定索引位置的成员
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Long zRemoveRange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().removeRange(key, start, end);
    }

    /**
     * 根据指定的score值的范围来移除成员
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Long zRemoveRangeByScore(String key, double min, double max) {
        return stringRedisTemplate.opsForZSet().removeRangeByScore(key, min, max);
    }

    /**
     * 获取key和otherKey的并集并存储在destKey中
     *
     * @param key
     * @param otherKey
     * @param destKey
     * @return
     */
    public Long zUnionAndStore(String key, String otherKey, String destKey) {
        return stringRedisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey);
    }

    /**
     *
     * @param key
     * @param otherKeys
     * @param destKey
     * @return
     */
    public Long zUnionAndStore(String key, Collection<String> otherKeys,
            String destKey) {
        return stringRedisTemplate.opsForZSet()
                .unionAndStore(key, otherKeys, destKey);
    }

    /**
     * 交集
     *
     * @param key
     * @param otherKey
     * @param destKey
     * @return
     */
    public Long zIntersectAndStore(String key, String otherKey,
            String destKey) {
        return stringRedisTemplate.opsForZSet().intersectAndStore(key, otherKey,
                destKey);
    }

    /**
     * 交集
     *
     * @param key
     * @param otherKeys
     * @param destKey
     * @return
     */
    public Long zIntersectAndStore(String key, Collection<String> otherKeys,
            String destKey) {
        return stringRedisTemplate.opsForZSet().intersectAndStore(key, otherKeys,
                destKey);
    }

    /**
     *
     * @param key
     * @param options
     * @return
     */
    public Cursor<TypedTuple<String>> zScan(String key, ScanOptions options) {
        return stringRedisTemplate.opsForZSet().scan(key, options);
    }

    /**
     * 存储map值 : 参考文档:https://www.jianshu.com/p/7bf5dc61ca06
     * @param key           :表示存储map的key
     * @param mapData       :存储的map值
     * @param timeout       :超时时间,-1:表示用不过期
     * @param unit          :时间单位
     */
    public void setMap(String key, Map<Object,Object> mapData, Long timeout, TimeUnit unit) {
        //下面是方案一
        //for (Map.Entry<String,Object> entry : mapData.entrySet()) {
        //  redisTemplate.opsForHash().put(key,entry.getKey(),entry.getValue());
        //}

        redisTemplate.opsForHash().putAll(key,mapData);

        if (timeout.longValue() >= 0L) {
            redisTemplate.expire(key, timeout.longValue(), unit);
        }
    }

    /**
     * 往redis 中key的map中添加 (mapKey,mapValue)
     * 参考网址:https://www.jianshu.com/p/7bf5dc61ca06
     *
     * @param key           :redis中代表map的key值
     * @param mapKey        :map中key为mapKey
     * @param mapValue      :map中的value值为mapValue
     */
    public void putMapOneKV(String key,String mapKey,Object mapValue) {
        redisTemplate.opsForHash().put(key,mapKey,mapValue);
    }

    /**
     * 删除redis 为key的map中的hashKeys这些值
     * @param key
     * @param mapKyes
     * @return
     */
    public void deleteMapOneK(String key,String... mapKyes) {
        for (String hashKey : mapKyes) {
            redisTemplate.opsForHash().delete(key,hashKey);
        }
    }

    /**
     * 删除map值
     * @param key
     */
    public void deleteMap(String key) {
        //设置key过期
        redisTemplate.expire(key, 0, TimeUnit.MILLISECONDS);
    }

    /**
     * 获取到redis 中key的map对象
     * @param key     :reids中的key值
     * @return
     */
    public Map<Object,Object> getMap(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 获取到redis中存储的map的值的数量
     * @param key
     * @return
     */
    public Long getMapSize(String key) {
        return redisTemplate.opsForHash().size(key);
    }

    /**
     * 读取缓存,此种场景存值的时候使用的是setObject
     *
     * @param key
     * @return
     */
    public Object getObject(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    /**
     * 存值方法,如果存的时候使用setObject方法,取参的时候请用getObject方法
     * @param key
     * @param value
     * @return
     */
    public Object setObject(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

}

猜你喜欢

转载自blog.csdn.net/toto1297488504/article/details/81009487