Redis的安装
第一步:下载Redis安装版本
这里需要说明一点的是,新版的redis不够稳定,建议大家还是使用旧版本的redis,比如3.0.0版本。大家可以到http://download.csdn.net/detail/u012453843/9820041这个地址下载。
第二步:安装gcc环境
由于redis是由C语言编写的,它的运行需要C环境,因此我们需要先安装gcc。安装命令是yum install gcc-c++
第三步:将安装包上传到虚拟机
第四步:解压
tar -xvf redis-3.0.0.tar -C /usr/local/
第五步:编译安装
我们到/usr/local/redis-3.0.0目录下,要运行make和make install命令就要有Makefile这个文件,我们可以看到是有这个文件的。
先进行编译 make
再进行安装make install PREFIX=/usr/local/redis
安装完之后,我们到/usr/local目录下,可以看到redis目录,我们进入redis目录,在该目录下可以看到bin目录,进入到bin目录可以看到redis的客户端和服务端,如下所示。
第六步:启动redis服务端
第一种启动方式是直接使用./redis-server命令启动,如下所示(可以看到默认端口是6379),只不过这种启动会占用终端,如果我们按Ctrl+C就会停止redis-server。
第二种启动方式是使用配置文件启动(也叫后端启动),我们需要先到redis的安装目录下把redis.conf文件复制一份到/usr/local/redis/bin目录下。如下所示。
下面我们需要简单修改下redis.conf文件,把daemonize的值由默认的no修改为yes,这个配置是指定是否在后台运行。如下图所示。
下面使用后台启动
[root@redis bin]# ./redis-server redis.conf
要想查看是否正常启动了,可以使用ps -ef|grep redis或ps aux | grep redis,如下所示,可以看到已经正常启动了。
第七步:测试服务
使用./redis-cli连接上redis服务,然后使用ping命令,如果返回的是PONG,说明连接没问题。
Jedis的使用
上节课我们一起学习了Redis的安装,这节课我们一起学习下Redis的客户端Jedis的使用。
首先,在taotao-content-service工程添加对jedis的引用,如下所示。
<!-- Redis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
下面我们新建一个测试类来测试一下Jedis,如下所示。
package com.taotao.jedis;
import org.junit.Test;
import redis.clients.jedis.Jedis;
public class TestJedis {
@Test
public void testJedis(){
//创建jedis对象,需要指定Redis服务的IP和端口号
Jedis jedis = new Jedis("192.168.156.11", 6379);
//直接操作数据库
jedis.set("jedis-key", "hello jedis!");
//获取数据
String result = jedis.get("jedis-key");
System.out.println(result);
//关闭jedis
jedis.close();
}
}
上面的测试类方法由于每次都创建一个Jedis对象,这是不合理的,因为这样很耗资源,因此我们使用数据库连接池来处理,需要连接的时候从数据库连接池中去获取,用完连接记得关闭,这样连接池才能将资源回收。如下所示。
@Test
public void testJedisPool(){
//创建一个数据库连接池对象(单例,即一个系统共用一个连接池),需要指定服务的IP和端口号
JedisPool jedisPool = new JedisPool("192.168.156.11", 6379);
//从连接池中获得连接
Jedis jedis = jedisPool.getResource();
//使用jedis操作数据库(方法级别,就是说只是在该方法中使用,用完就关闭)
String result = jedis.get("jedis-key");
System.out.println(result);
//用完之后关闭jedis连接
jedis.close();
//系统关闭前先关闭数据库连接池
jedisPool.close();
}
5.4. Redis五种数据类型
5.4.1. String:key-value
redis命令不区分大小写,但是key区分的
redis中的数据都是字符串。
redis是单线程,(不适合存储比较大的数据)
使用incr 命令,如果key 不存在,会自动创建key 并自动+1.
set key value 设置值
get key 获取值
incr key 加一
decr key 减一
5.4.2. Hash: key-field-value
相当于一个key 对应一个map (map中又是key- value),
应用于归类
hset key field value 设置值
hget key field 获取值
hincrby key field num 设置增数量
5.4.3. List
List是有顺序可重复(数据结构中的:双链表,队列)
可作为链表 ,从左添加元素 也可以从右添加元素。
lpush list a b c d (从左添加元素)
rpush list 1 2 3 4 (从右边添加元素)
lrange list 0 -1 (从0 到 -1 元素查看:也就表示查看所有)
lpop list (从左边取,删除)
rpop list (从右边取,删除)
5.4.4. Set
Set 无顺序,不能重复
sadd set1 a b c d d (向set1中添加元素) 元素不重复
smembers set1 (查询元素)
srem set1 a (删除元素)
5.4.5. SortedSet(zset)
有顺序,不能重复
适合做排行榜 排序需要一个分数属性
zadd zset1 9 a 8 c 10 d 1 e (添加元素 zadd key score member )
(ZRANGE key start stop [WITHSCORES])(查看所有元素:zrange key 0 -1 withscores)
如果要查看分数,加上withscores.
zrange zset1 0 -1 (从小到大)
zrevrange zset1 0 -1 (从大到小)
zincrby zset2 score member (对元素member 增加 score)
5.5. key 命令
1.expire key second (设置key的过期时间)
2.ttl key (查看剩余时间)(-2 表示不存在,-1 表示已被持久化,正数表示剩余的时间)
3.persist key (清除过期时间,也即是持久化 持久化成功体提示 1 不成功0)。
4.del key: 删除key
5.EXISTS key
若key存在,返回1,否则返回0。
6.select 0 表示:选择0号数据库。默认是0号数据库
6.Redis持久化方案
Redis 数据都放在内存中。如果机器挂掉,内存的数据就不存在。
需要做持久化,讲内存中的数据保存在磁盘,下一次启动的时候就可以恢复数据到内存中。
1.RDB 快照形式 (定期将当前时刻的数据保存磁盘中)会产生一个dump.rdb文件
特点:会存在数据丢失,性能较好,数据备份。
2.AOF append only file (所有对redis的操作命令记录在aof文件中),恢复数据,重新执行一遍即可。
特点:每秒保存,数据比较完整,耗费性能。
redis 默认开启RDB
如下图:redis.conf中默认设置了保存规则及时间间隔
AOF开启设置:
修改 redis.conf 文件:
将appendonly 设置为yes
同时开启两个持久化方案,则按照 AOF的持久化放案恢复数据。
默认是按照rdb的方式恢复数据,如果开启了AOF,就是用AOF恢复数据,数据是存在于/usr/local/redis/bin/appendonly.aof文件中
Redis集群搭建
首先说一下,为何要搭建Redis集群。Redis是在内存中保存数据,而我们的电脑一般内存都不大,这也就意味着Redis不适合存储大数据。适合存储大数据的是Hadoop生态系统的HBase或者是MogoDB。Redis更适合处理高并发,一台设备的存储能力是很有限的,但是多台设备协同合作,就可以让内存增大很多倍,这就需要用到集群。
我们来看一下集群图,如下图所示。可以看到Redis集群是没有统一入口的,客户端连集群中的哪台设备都行,集群中各个设备之间都定时进行交互,以便知道节点是否还正常工作。
那么假如某个节点挂掉了怎么办?Redis集群是有容错投票机制的,如下图所示。浅黄色的那个节点向红色的那个节点发出ping命令,红色节点没有回应,这时浅黄色节点便认为这个节点可能挂掉了,它会投上一票,不过这时只是疑问,所以浅黄色节点画了一个"?",然后浅黄色节点告诉别的节点说这个红色的节点可能挂掉了,第二个节点去尝试和这个红色节点联系,发现也ping不同,于是第二个节点也认为这个红色节点挂掉了,第二个节点也投上一票,接着第三个节点去和红色节点联系,也联系不上,于是也投上一票,这样便三票了。Redis的容错投票机制是集群中过半数的节点认为某个节点挂了,那么就认定这个节点挂了。这时要看这个红色节点还有没有备用节点,如果没有备用节点了,那么整个集群将停止对外提供服务,如果有备份节点,那么会将备份节点扶正,继续对外提供服务。
那么为什么一个节点挂掉(并且没有备用节点)的话,整个集群都不能提供服务了呢?其实这跟Redis集群的存储机制有关,Redis集群内置了16384个哈希槽,当需要在Redis集群中放置一个key-value时,redis先对key使用crc16算法算出一个结果,然后把结果对16384求余数,这样每个key都会对应一个编号在0-16383之间的哈希槽,redis会根据节点数量大致均等的将哈希映射到不同的节点。我们以下图为例,我们把这16384个哈希槽分配到三个Server上,假如Server1上卡槽是0-5000,Server2上卡槽是5001-10000,Server3上卡槽是10001-16383。假如我们要保存字符串"hello",而"hello"经过crc16算法再对16384求余后是500,很显然应该存到Server1上,假如要存储的字符串"hello2"经过crc16算法再对16384求余后是11500,那么狠显然应该存到Server3上,同理,“hello3”、"hello1"被分别存到Server2和Server1上了。也就是说每个Server其实存储的内容是不一样的,这也就是为何某个节点挂掉后如果没有备用节点的话,整个集群都会挂掉,因为数据不全了啊。另外,关于每个服务器上卡槽的分布数量可以根据服务器的性能来定,性能好的可以多分配些卡槽,这样在它上面存储的内容也就多了。
下面我们来搭建Redis集群,由于集群的容错机制是超过半数的节点认为某节点挂掉就确认挂掉,因此我们搭建的集群最好是奇数台(>=3)。又由于为了高可用性,每个节点需要有备份节点,因此我们搭建Redis集群至少要有6台虚拟机。下面说下步骤:
第一步:新建6台虚拟机
大家可以参考http://blog.csdn.net/u012453843/article/details/68947589这篇博客进行搭建
第二步:为每台虚拟机安装redis
大家可以参考http://blog.csdn.net/u012453843/article/details/70254865这篇博客进行安装
第三步:修改配置文件
首先将解压包中的redis.conf文件复制到/usr/local/redis/bin目录下
[root@redis1 redis-3.0.0]# pwd
/usr/local/redis-3.0.0
[root@redis1 redis-3.0.0]# cp redis.conf /usr/local/redis/bin/
[root@redis1 redis-3.0.0]# cd /usr/local/redis/bin
[root@redis1 bin]# ll
总用量 15484
-rwxr-xr-x. 1 root root 4588854 4月 21 05:18 redis-benchmark
-rwxr-xr-x. 1 root root 22177 4月 21 05:18 redis-check-aof
-rwxr-xr-x. 1 root root 45395 4月 21 05:18 redis-check-dump
-rwxr-xr-x. 1 root root 4691761 4月 21 05:18 redis-cli
-rw-r--r--. 1 root root 41403 4月 21 05:28 redis.conf
lrwxrwxrwx. 1 root root 12 4月 21 05:18 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 6450289 4月 21 05:18 redis-server
[root@redis1 bin]#
接着修改redis.conf文件,需要修改两处地方,第一处是要开启后台运行功能,点击Xshell工具的"编辑"菜单,在下拉菜单中点击"查找",在查找对话框中输入"daemonize"即可搜索到相关配置,该配置原来默认值是"no",我们现在把它改为"yes"。
第二处修改是开启集群,在搜索框中输入"cluster-enabled"便可找到这项配置,该配置原来是被注释掉的,我们把前面的那个注释符"#"去掉,如下图所示。
这样第一台虚拟机便配置好了,由于六台虚拟机的这两项配置都一样,因此我们把刚修改好的这份配置文件复制到其它5台虚拟机上。
[root@redis1 bin]# scp redis.conf 192.168.156.16:/usr/local/redis/bin/
[root@redis1 bin]# scp redis.conf 192.168.156.17:/usr/local/redis/bin/
[root@redis1 bin]# scp redis.conf 192.168.156.18:/usr/local/redis/bin/
[root@redis1 bin]# scp redis.conf 192.168.156.19:/usr/local/redis/bin/
[root@redis1 bin]# scp redis.conf 192.168.156.20:/usr/local/redis/bin/
第四步:设置开机自启动
为了避免以后集群所有设备都手工启动redis,可以为这6台设备设置开机自启动,在/etc/rc.d/rc.local文件当中添加/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf这一行命令。
[root@redis1 bin]# vim /etc/rc.d/rc.local
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
touch /var/lock/subsys/local
/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf
第五步:启动六台设备的redis。
以其中一台设备为例,如下所示。
[root@redis1 bin]# /usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf
[root@redis1 bin]# ps aux|grep redis
root 6222 0.2 1.0 137456 2500 ? Ssl 07:00 0:00 /usr/local/redis/bin/redis-server *:6379 [cluster]
root 6256 0.0 0.3 103336 896 pts/1 S+ 07:00 0:00 grep redis
[root@redis1 bin]#
第六步:安装ruby环境
集群的搭建需要用到ruby环境,因此我们需要安装ruby环境,由于六台设备都需要安装ruby环境,因此我们直接在XShell工具的下面的输入框中输入安装命令(要确认当前 作用的窗口是所有窗口,就是左边的图标是多窗口图标,如果不是多窗口可以点击输入框右边的"三条横线"图标切换窗口)回车即可在六个窗口同时运行yum install ruby命令。
安装完ruby之后,我们安装rubygem(也就是ruby第三方包管理工具),使用命令yum install rubygems,如下图所示
安装完ruby和rubygems之后,我们需要安装ruby脚本运行所需要的一个包redis-3.0.0.gem。这个包大家可以到:http://download.csdn.net/detail/u012453843/9821251这个地址进行下载,下载完后上传到每台 设备的/usr/local/software目录下,如下所示。
[root@redis1 redis-3.0.0]# cd /usr/local/software/
[root@redis1 software]# ll
总用量 1388
-rw-r--r--. 1 root root 57856 4月 21 2017 redis-3.0.0.gem
-rw-r--r--. 1 root root 1358081 4月 20 11:15 redis-3.0.0.tar.gz
[root@redis1 software]#
下面来安装这个第三方包,在下面的那个输入框中输入gem install redis-3.0.0.gem然后回车,在六个窗口同时进行安装,其中一台的安装信息如下。
[root@redis1 software]# gem install redis-3.0.0.gem
Successfully installed redis-3.0.0
1 gem installed
Installing ri documentation for redis-3.0.0...
Installing RDoc documentation for redis-3.0.0...
[root@redis1 software]#
第七步:安装集群
上面做了那么多准备其实是为一个脚本文件(redis-trib.rb)服务的,这个脚本的位置在/usr/local/redis-3.0.0/src目录下,如下所示
[root@redis1 src]# pwd
/usr/local/redis-3.0.0/src
[root@redis1 src]# ll *.rb
-rwxrwxr-x. 1 root root 48141 4月 1 2015 redis-trib.rb
[root@redis1 src]#
为方便管理,我们把这个脚本复制到/usr/local/redis/bin目录下,如下所示
[root@redis1 src]# cp redis-trib.rb /usr/local/redis/bin
[root@redis1 src]#
下面正式搭建集群,命令中–replicas是指定每个节点备份的节点的数量,我们现在是每个节点备份一个,因此输入1。如下所示,可以看到从主节点是随机组成的,主节点是192.168.156.17、192.168.156.18、192.168.156.19这三台设备,192.168.156.15、192.168.156.16、192.168.20这三台是备用节点。Adding replica 192.168.156.16:6379 to 192.168.156.19:6379的意思是192.168.156.16作为192.168.156.19的从节点,同理,192.168.156.15作为了192.168.156.18的从节点,192.168.156.20作为了192.168.156.17的从节点。这样我们的集群便搭建完了。
[root@redis1 bin]# ./redis-trib.rb create --replicas 1 192.168.156.15:6379 192.168.156.16:6379 192.168.156.17:6379 192.168.156.18:6379 192.168.156.19:6379 192.168.156.20:6379
>>> Creating cluster
Connecting to node 192.168.156.15:6379: OK
Connecting to node 192.168.156.16:6379: OK
Connecting to node 192.168.156.17:6379: OK
Connecting to node 192.168.156.18:6379: OK
Connecting to node 192.168.156.19:6379: OK
Connecting to node 192.168.156.20:6379: OK
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.156.19:6379
192.168.156.18:6379
192.168.156.17:6379
Adding replica 192.168.156.16:6379 to 192.168.156.19:6379
Adding replica 192.168.156.15:6379 to 192.168.156.18:6379
Adding replica 192.168.156.20:6379 to 192.168.156.17:6379
S: 076bec0407edac2a4d10e4ceaf62d7edf85013ad 192.168.156.15:6379
replicates 42b5398f180aa12951de65757485de6202e9691f
S: bbe64932ee438edf6cb72023457dd503546434f4 192.168.156.16:6379
replicates 138fe0c66e6ee6f33b2f86ff878ad5e2766db281
M: 424f48fe202d6a963938b1073e1d898a1c06621a 192.168.156.17:6379
slots:10923-16383 (5461 slots) master
M: 42b5398f180aa12951de65757485de6202e9691f 192.168.156.18:6379
slots:5461-10922 (5462 slots) master
M: 138fe0c66e6ee6f33b2f86ff878ad5e2766db281 192.168.156.19:6379
slots:0-5460 (5461 slots) master
S: af52e00584397ef503e90cbf76b1aaae3265e9e2 192.168.156.20:6379
replicates 424f48fe202d6a963938b1073e1d898a1c06621a
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
Waiting for the cluster to join.......
>>> Performing Cluster Check (using node 192.168.156.15:6379)
M: 076bec0407edac2a4d10e4ceaf62d7edf85013ad 192.168.156.15:6379
slots: (0 slots) master
replicates 42b5398f180aa12951de65757485de6202e9691f
M: bbe64932ee438edf6cb72023457dd503546434f4 192.168.156.16:6379
slots: (0 slots) master
replicates 138fe0c66e6ee6f33b2f86ff878ad5e2766db281
M: 424f48fe202d6a963938b1073e1d898a1c06621a 192.168.156.17:6379
slots:10923-16383 (5461 slots) master
M: 42b5398f180aa12951de65757485de6202e9691f 192.168.156.18:6379
slots:5461-10922 (5462 slots) master
M: 138fe0c66e6ee6f33b2f86ff878ad5e2766db281 192.168.156.19:6379
slots:0-5460 (5461 slots) master
M: af52e00584397ef503e90cbf76b1aaae3265e9e2 192.168.156.20:6379
slots: (0 slots) master
replicates 424f48fe202d6a963938b1073e1d898a1c06621a
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@redis1 bin]#
Redis集群测试
上节课我们一起学习了怎样搭建一个六台设备的Redis集群,这节我们一起学习下如何测试集群。
首先启动Redis集群使用命令/usr/local/redis/bin/redis-trib.rb create --replicas 1 192.168.156.15:6379 192.168.156.16:6379 192.168.156.17:6379 192.168.156.18:6379 192.168.156.19:6379 192.168.156.20:6379进行启动,如下所示。可以看到192.168.156.18、192.168.156.19、192.168.156.20这三个节点是主节点,另外三个节点是从节点。槽号为0-5460的卡槽被分配到了192.168.156.20上,5461-10922被分配到了192.168.156.19上,10923-16383被分配到了192.168.156.18上。
[root@redis1 ~]# /usr/local/redis/bin/redis-trib.rb create --replicas 1 192.168.156.15:6379 192.168.156.16:6379 192.168.156.17:6379 192.168.156.18:6379 192.168.156.19:6379 192.168.156.20:6379
>>> Creating cluster
Connecting to node 192.168.156.15:6379: OK
Connecting to node 192.168.156.16:6379: OK
Connecting to node 192.168.156.17:6379: OK
Connecting to node 192.168.156.18:6379: OK
Connecting to node 192.168.156.19:6379: OK
Connecting to node 192.168.156.20:6379: OK
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.156.20:6379
192.168.156.19:6379
192.168.156.18:6379
Adding replica 192.168.156.17:6379 to 192.168.156.20:6379
Adding replica 192.168.156.16:6379 to 192.168.156.19:6379
Adding replica 192.168.156.15:6379 to 192.168.156.18:6379
S: 0cbe6fc270afa701156c5dc9c47dba522dd62737 192.168.156.15:6379
replicates 423f334654c3dfdacd39927e0528a95c38aa933f
S: 4eecf66148e88917b4ecf4b36e794a6e83e4fe85 192.168.156.16:6379
replicates b69de3b87aeefac1d4711dd644a8dd5815c56bec
S: 149c9e9a0e0febd581193df17d509ce4970e4163 192.168.156.17:6379
replicates 6808fa38709cac3a6ec4b232fd1e45980cbb0c96
M: 423f334654c3dfdacd39927e0528a95c38aa933f 192.168.156.18:6379
slots:10923-16383 (5461 slots) master
M: b69de3b87aeefac1d4711dd644a8dd5815c56bec 192.168.156.19:6379
slots:5461-10922 (5462 slots) master
M: 6808fa38709cac3a6ec4b232fd1e45980cbb0c96 192.168.156.20:6379
slots:0-5460 (5461 slots) master
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
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 192.168.156.15:6379)
M: 0cbe6fc270afa701156c5dc9c47dba522dd62737 192.168.156.15:6379
slots: (0 slots) master
replicates 423f334654c3dfdacd39927e0528a95c38aa933f
M: 4eecf66148e88917b4ecf4b36e794a6e83e4fe85 192.168.156.16:6379
slots: (0 slots) master
replicates b69de3b87aeefac1d4711dd644a8dd5815c56bec
M: 149c9e9a0e0febd581193df17d509ce4970e4163 192.168.156.17:6379
slots: (0 slots) master
replicates 6808fa38709cac3a6ec4b232fd1e45980cbb0c96
M: 423f334654c3dfdacd39927e0528a95c38aa933f 192.168.156.18:6379
slots:10923-16383 (5461 slots) master
M: b69de3b87aeefac1d4711dd644a8dd5815c56bec 192.168.156.19:6379
slots:5461-10922 (5462 slots) master
M: 6808fa38709cac3a6ec4b232fd1e45980cbb0c96 192.168.156.20:6379
slots:0-5460 (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
既然集群已经启动好了,我们使用redis客户端随意连接一台设备进行测试,比如我们连接192.168.156.16这台设备(这是个从节点,从属于192.168.156.19),如下所示(注意:一定要加上参数"-c"否则没办法重定向 到其它节点)。
[root@redis2 bin]# ./redis-cli -h 192.168.156.16 -p 6379 -c
192.168.156.16:6379>
连接上之后,我们先来保存key1,它的值是123,如下所示,可以看到,这个key1经过算法并对16384进行求余之后的数字是9189,这个槽号是在192.168.156.19上,因此key1被保存到了192.168.156.19上。
192.168.156.16:6379> set key1 123
-> Redirected to slot [9189] located at 192.168.156.19:6379
OK
192.168.156.19:6379>
我们再接着保存key2、key3、key4,如下所示,可以看到key2所对应的槽号是4998,显然是在192.168.156.20上,key3所对应的槽号也在0-5640,因此set key2的时候根本就没有重定向,还是停留在192.168.156.20上。key4所对应的槽号是13120,显然是在192.168.156.18上因此被保存到了192.168.156.18上。
192.168.156.19:6379> set key2 111
-> Redirected to slot [4998] located at 192.168.156.20:6379
OK
192.168.156.20:6379> set key3 aaa
OK
192.168.156.20:6379> set key4 bbb
-> Redirected to slot [13120] located at 192.168.156.18:6379
OK
192.168.156.18:6379>
我们可以使用命令cluster info查看集群的某些信息,如下所示,可以看到当前集群的状态是OK的,所有的槽号都已分配完毕,没有失败的节点。所有的节点数是6,当前提供服务的有3台
192.168.156.18: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:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:4
cluster_stats_messages_sent:10748
cluster_stats_messages_received:10748
192.168.156.18:6379>
还可以通过命令cluster nodes来查看节点信息。
192.168.156.18:6379> cluster nodes
423f334654c3dfdacd39927e0528a95c38aa933f 192.168.156.18:6379 myself,master - 0 0 4 connected 10923-16383
4eecf66148e88917b4ecf4b36e794a6e83e4fe85 192.168.156.16:6379 slave b69de3b87aeefac1d4711dd644a8dd5815c56bec 0 1492869406355 5 connected
0cbe6fc270afa701156c5dc9c47dba522dd62737 192.168.156.15:6379 slave 423f334654c3dfdacd39927e0528a95c38aa933f 0 1492869405340 4 connected
149c9e9a0e0febd581193df17d509ce4970e4163 192.168.156.17:6379 slave 6808fa38709cac3a6ec4b232fd1e45980cbb0c96 0 1492869402275 6 connected
6808fa38709cac3a6ec4b232fd1e45980cbb0c96 192.168.156.20:6379 master - 0 1492869408383 6 connected 0-5460
b69de3b87aeefac1d4711dd644a8dd5815c56bec 192.168.156.19:6379 master - 0 1492869407370 5 connected 5461-10922
192.168.156.18:6379>
下面使用JedisCluster来测试集群,我们在taotao-content-service工程的测试类中再添加一个测试方法(与第三十课结合学习),如下所示。运行,发现是可以正常输出"hello jedis cluster"的。
@Test
public void testJedisCluster(){
//创建构造参数Set类型,集合中每个元素是HostAndPort类型
Set<HostAndPort> nodes = new HashSet<>();
//向集合中添加节点
nodes.add(new HostAndPort("192.168.156.15", 6379));
nodes.add(new HostAndPort("192.168.156.16", 6379));
nodes.add(new HostAndPort("192.168.156.17", 6379));
nodes.add(new HostAndPort("192.168.156.18", 6379));
nodes.add(new HostAndPort("192.168.156.19", 6379));
nodes.add(new HostAndPort("192.168.156.20", 6379));
//创建JedisCluster对象
JedisCluster jedisCluster = new JedisCluster(nodes);
//直接使用jedisCluster,自带连接池,jedisCluster可以是单例的
jedisCluster.set("jedis-cluster", "hello jedis cluster");
String result = jedisCluster.get("jedis-cluster");
System.out.println(result);
//系统关闭前关闭jedisCluster
jedisCluster.close();
}
使用Spring来管理Redis单机版和集群版
我们知道Jedis在处理Redis的单机版和集群版时是完全不同的,有可能在开发的时候使用的是单机版,但是当项目上线后使用的则是集群版。这就需要能够方便的在单机版和集群版之间进行切换。我们的做法便是定义一个Jedis接口类,然后新建两个实现类来分别处理单机版和集群版,最后在Spring容器中进行配置管理即可。
首先在taotao-content-interface工程下新建一个包com.taotao.jedis.service并在该包下新建一个接口类JedisClient。
接着我们到taotao-content-service工程下新建一个com.taotao.jedis.service.impl包,并在该包下新建两个JedisClient的实现类,分别是单机版实现类JedisClientPool和集群版实现类JedisClientCluster。
我们先来测试单机版如何使用,我们在单机版实现类JedisClientPool当中可以看到使用注入的方式注入JedisPool,要注入,Spring容器当中便要管理这个Bean,因此我们在taotao-content-service工程的src/main/resources/spring目录下新建一个applicationContext-jedis.xml配置文件来专门管理Jedis客户端的使用,内容如下(注意:下面的配置文件中关于开启注解的配置是为了在测试类中测试代码而添加的,因为使用测试类测试的话,不会加载其它配置文件,因此没有开启注解,因此需要这句配置,测试完后记得要删掉这个配置。还有就是单机版配置的端口6999是我在redis.conf中配置的,之所以没用默认的6379是因为redis集群使用了该端口)。
针对applicationContext-jedis.xml配置文件的内容有一点需要说明一下,我们看看下图,applicationContext-service.xml文件配置的扫描包的范围是com.taotao.content.service,那么如果我们不指定要扫描com.taotao.jedis.service包的话,能不能把JedisPool注入进来呢?答案是可以的,因为下图中<context:component-scan base-package=“com.taotao.content.service”/>这句配置不仅指定了一个包扫描范围,还有一个功能就是开启注解(也就是同时具备两个功能),开启注解后写到Spring容器中的Bean都可以被外界成功注入。
下面我们新建一个测试类来进行测试,发现单机版没用问题
测试完了单机版,现在我们来测试集群版,在配置文件中注释掉单机版配置,添加集群版配置,如下所示。
我们再到集群中任何一个节点去检查一下,比如我在192.168.156.17这个节点上使用客户端连接集群,使用命令get jedisClient来获取它的值,发现jedisClien被保存到了槽号为13154的上面,该槽号在192.168.156.18上,如下所示,说明确实保存到集群当中了。
这样,以后我们只需修改Spring配置文件便可轻松在单机版和集群版进行切换。最后记得把applicationContext-jedis.xml文件中用于测试的开启注解的配置context:annotation-config/去掉,因为在applicationContext-service.xml文件中已经开启过注解了,系统运行会把所有的配置文件都加载进来,因此只需一处开启注解就可以了。
在业务逻辑中添加缓存
上节课我们一起学习了如何用Spring容器来管理Redis单机版和集群版实现。这节我们来学习下在业务中添加缓存。
Redis添加缓存有两种方式,一种是set,另一种是hset,这两种方式的不同之处是hset可以对key进行分类,查询的时候先查询类,然后再在该类下查询某个key的值,这样的效率肯定要比set方式存储的数据查询效率高。因此我们选择hset的方式来存储缓存信息。
我们是以首页大广告位的展示为例,我们便给hkey(分类)起个名字,叫"INDEX_CONTENT",为了不把代码写死,我们把它放到配置文件当中,taotao-content-service/src/main/resources/properties/resource.properties
添加了一个resource.properties文件,需要在Spring容器中扫描进去,我们把applicationContext-dao.xml文件中加载配置文件这一行做下修改,将db.properties修改为*.properties。这样properties目录下所有的以properties结尾的文件都会被加载进来。
下面我们修改taotao-content-service工程下的ContentServiceImpl.java中的getContentListByCid方法,如下所示。我们可以打断点查看一下第一次访问首页大广告位和第二次访问首页大广告位的情况。
缓存有个问题就是如果数据库中的数据做了修改,缓存是需要同步的,否则查询的还是老数据,因此凡是涉及增、删、改的操作都需要同步缓存。我们以添加内容为例。如下所示。
总结:
功能分析
查询内容列表时添加缓存。
1、查询数据库之前先查询缓存。
2、查询到结果,直接响应结果。
3、查询不到,缓存中没有需要查询数据库。
4、把查询结果添加到缓存中。
5、返回结果。
向redis中添加缓存:
Key:categoryId field
Value:内容列表。需要把java对象转换成json。
使用hash对key进行归类。
HASH_KEY:HASH
|–KEY:VALUE
|–KEY:VALUE
|–KEY:VALUE
|–KEY:VALUE
注意:添加缓存不能影响正常业务逻辑。
key field value
key自定义content
field内容分类的id
value列表的JSON字符串