集群搭建系列教程4:虚拟机模拟搭建redis集群服务
原创教程,未经允许,不得转载
集群搭建系列教程4
redis集群使用场景:数据容灾
搭建准备:VM虚拟机,Centos7镜像,redis-4.0.6.tar.tg,FileZilla
第一部分:搭建集群前的环境准备
第一步:现在本地VM虚拟机上搭建两个Centos7的虚拟机,选择最小化安装,通过ifconfig命令可以看到两个虚拟机ip分别为:
192.168.229.131
192.168.229.132
第二步:关闭虚拟机防火墙
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动
firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning,开启后显示running)
第三步:安装编译环境,在之后redis进行编译和安装时需要用到
sudo yum install gcc-c++
第四步:安装RVM,作用:通过RVM用来管理Ruby
gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
curl -L get.rvm.io | bash -s stable
find / -name rvm -print
在执行最后一行后会打印如下信息:
/usr/local/rvm
/usr/local/rvm/src/rvm
/usr/local/rvm/src/rvm/bin/rvm
/usr/local/rvm/src/rvm/lib/rvm
/usr/local/rvm/src/rvm/scripts/rvm
/usr/local/rvm/bin/rvm
/usr/local/rvm/lib/rvm
/usr/local/rvm/scripts/rvm
然后使安装的RVM生效
source /usr/local/rvm/scripts/rvm
第五步:查看rvm库中已知的ruby版本
rvm list known
可以看到:
# MRI Rubies [ruby-]1.8.6[-p420] [ruby-]1.8.7[-head] # security released on head [ruby-]1.9.1[-p431] [ruby-]1.9.2[-p330] [ruby-]1.9.3[-p551] [ruby-]2.0.0[-p648] [ruby-]2.1[.10] [ruby-]2.2[.7] [ruby-]2.3[.4] [ruby-]2.4[.1] ruby-head # for forks use: rvm install ruby-head-<name> --url https://github.com/github/ruby.git --branch 2.2 # JRuby jruby-1.6[.8] jruby-1.7[.27] jruby[-9.1.13.0] jruby-head # Rubinius rbx-1[.4.3] rbx-2.3[.0] rbx-2.4[.1] rbx-2[.5.8] rbx-3[.84] rbx-head # Opal opal # Minimalistic ruby implementation - ISO 30170:2012 mruby-1.0.0 mruby-1.1.0 mruby-1.2.0 mruby-1[.3.0] mruby[-head] # Ruby Enterprise Edition ree-1.8.6 ree[-1.8.7][-2012.02] # Topaz topaz # MagLev maglev[-head] maglev-1.0.0 # Mac OS X Snow Leopard Or Newer macruby-0.10 macruby-0.11 macruby[-0.12] macruby-nightly macruby-head # IronRuby ironruby[-1.1.3] ironruby-head
第六步:安装Ruby版本,这里我选择2.3.4
rvm install 2.3.4
如果版本低于2.2.0,在进行安装redis接口时会报错误,告诉你版本太低
gem install redis
ERROR: Error installing redis:
redis requires Ruby version >= 2.2.2.
第七步:使用一个版本的Ruby,并将这个版本设置为默认
rvm use 2.3.4
rvm use 2.3.4 --default
第八步:卸载旧版本,查看现在版本号,确认安装有效
rvm remove 2.0.0 #(CentOS7 yum库中ruby的版本支持到 2.0.0)
ruby --version #查看版本
第二部分:redis配置
第一步:上传redis-4.0.6.tar.tg到/usr/local目录下
第二步:解压
[root@localhost local]# tar -zxvf redis-4.0.6.tar.tg
[root@localhost local]# ll
drwxrwxr-x. 6 root root 4096 12月 5 01:01 redis-4.0.6
-rw-r--r--. 1 root root 1723533 1月 23 14:57 redis-4.0.6.tar.gz
第三步:对redis进行编译和安装
[root@localhost local]# cd redis-4.0.6
[root@localhost redis-4.0.6]# make #系统进行编译,稍等片刻
[root@localhost redis-4.0.6]# make install #系统进行安装redis
第四步:创建redis节点
我们有两台服务器,192.168.229.131和192.168.229.132
首先在131这台服务器上做如下配置
cd /usr/local/
mkdir redis_cluster //创建集群目录
mkdir 7000 7001 7002 //分别代表三个节点 其对应端口 7000 7001 7002
//创建7000节点为例,拷贝到7000目录
cp /usr/local/redis-4.0.6/redis.conf ./redis_cluster/7000/
//拷贝到7001目录
cp /usr/local/redis-4.0.6/redis.conf ./redis_cluster/7001/
//拷贝到7002目录
cp /usr/local/redis-4.0.6/redis.conf ./redis_cluster/7002/
然后在132这台服务器上做相似配置
cd /usr/local/
mkdir redis_cluster //创建集群目录
mkdir 7003 7004 7005 //分别代表三个节点 其对应端口 7003 7004 7005
//创建7003节点为例,拷贝到7003目录
cp /usr/local/redis-4.0.6/redis.conf ./redis_cluster/7003/
//拷贝到7004目录
cp /usr/local/redis-4.0.6/redis.conf ./redis_cluster/7004/
//拷贝到7005目录
cp /usr/local/redis-4.0.6/redis.conf ./redis_cluster/7005/
第五步:修改redis.conf配置
bind //绑定ip,不然只能本地访问,ip为每台虚拟机的ip
daemonize yes //redis后台运行
pidfile /var/run/redis_7000.pid //pidfile文件对应7000,7002,7003...
port 7000 //端口7000,7002,7003...
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_7000.conf //集群的配置 配置文件首次启动自动生成 7000,7001,7002
cluster-node-timeout 5000 //请求超时 设置5秒够了
appendonly yes //aof日志开启 有需要就开启,它会每次写操作都记录一条日志
我们有六个redis服务,那么这份文件就要修改六次
第六步:分别在每台服务器上启动各个节点
cd /usr/local
redis-server redis_cluster/7000/redis.conf
redis-server redis_cluster/7001/redis.conf
redis-server redis_cluster/7002/redis.conf
redis-server redis_cluster/7003/redis.conf
redis-server redis_cluster/7004/redis.conf
redis-server redis_cluster/7005/redis.conf
第七步:查看确认服务已经启动
ps -ef | grep redis #查看是否启动成功
netstat -tnlp | grep redis #可以看到redis监听端口
第三部分:redis集群创建
第一步:在每天服务器上串联起redis接口
gem install redis
第二步:试运行redis-trib.rb
/usr/local/redis-4.0.6/src/redis-trib.rb Usage: redis-trib <command> <options> <arguments ...>
create host1:port1 ... hostN:portN --replicas <arg> reshard host:port --to <arg> --yes --slots <arg> --from <arg> check host:port call host:port command arg arg .. arg set-timeout host:port milliseconds add-node new_host:new_port existing_host:existing_port --master-id <arg> --slave del-node host:port node_id fix host:port import host:port --from <arg> 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@localhost local]# /usr/local/redis-4.0.6/src/redis-trib.rb create --replicas 1 192.168.229.131:7000 192.168.229.131:7001 192.168.229.131:7002 192.168.229.132:7003 192.168.229.132:7004 192.168.229.132:7005
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.229.131:7000
192.168.229.132:7003
192.168.229.131:7001
Adding replica 192.168.229.132:7004 to 192.168.229.131:7000
Adding replica 192.168.229.131:7002 to 192.168.229.132:7003
Adding replica 192.168.229.132:7005 to 192.168.229.131:7001
M: ed3237a2f6772ce0fb895c538530ee837494357e 192.168.229.131:7000
slots:0-5460 (5461 slots) master
M: 10cb97caafb6be827cdf853e5fde813e2d94c09f 192.168.229.131:7001
slots:10923-16383 (5461 slots) master
S: 9f945c8fff6ce2ccaeaa127fecddecd73b938b81 192.168.229.131:7002
replicates 86f887139e8daea09df648cd0e414e46466b714e
M: 86f887139e8daea09df648cd0e414e46466b714e 192.168.229.132:7003
slots:5461-10922 (5462 slots) master
S: 4092761353182ab6a6ecbd1d5810c7e02fa0fdd9 192.168.229.132:7004
replicates ed3237a2f6772ce0fb895c538530ee837494357e
S: a90f168977b4255b4b47b2bfac75012e6fd0b454 192.168.229.132:7005
replicates 10cb97caafb6be827cdf853e5fde813e2d94c09f
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.229.131:7000)
M: ed3237a2f6772ce0fb895c538530ee837494357e 192.168.229.131:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 10cb97caafb6be827cdf853e5fde813e2d94c09f 192.168.229.131:7001
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 4092761353182ab6a6ecbd1d5810c7e02fa0fdd9 192.168.229.132:7004
slots: (0 slots) slave
replicates ed3237a2f6772ce0fb895c538530ee837494357e
M: 86f887139e8daea09df648cd0e414e46466b714e 192.168.229.132:7003
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: 9f945c8fff6ce2ccaeaa127fecddecd73b938b81 192.168.229.131:7002
slots: (0 slots) slave
replicates 86f887139e8daea09df648cd0e414e46466b714e
S: a90f168977b4255b4b47b2bfac75012e6fd0b454 192.168.229.132:7005
slots: (0 slots) slave
replicates 10cb97caafb6be827cdf853e5fde813e2d94c09f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
中间会有一个选项,问你是否要使用这些配置信息,选择yes即可
如果执行成功,最后可以看到7000/7001/7002这三个节点成为了master,而另外几个成为了slave,并且7000和7003,7001和7004,7002和7005对应
总共有16384个hash槽
第四部分:redis集群测试
[root@localhost redis-4.0.6]# redis-cli -c -h 192.168.229.131 -p 7000
192.168.229.131:7000> set hello helloworld
OK
192.168.229.131:7000> set name magic
-> Redirected to slot [5798] located at 192.168.229.132:7003
OK
192.168.229.132:7003>
测试成功,可以看到当要存储的键所对应的hash槽超过7000所在的hash槽容量后,会自动放到相应范围的节点下存储,实现数据的自动扩容和同步
注意:
在redis官网有一句话是这样说的:Redis Cluster is not able to guarantee strong consistency.
Redis集群不能保证数据的高度一致性。所以想通过redis集群来实现持久化数据库的想法可以省省了。
第五部分:Java程序连接redis集群
public static void main(String[] args) throws IOException { JedisPoolConfig poolConfig = new JedisPoolConfig(); // 最大连接数 poolConfig.setMaxTotal(1); // 最大空闲数 poolConfig.setMaxIdle(1); // 最大允许等待时间,如果超过这个时间还未获取到连接,则会报JedisException异常: // Could not get a resource from the pool poolConfig.setMaxWaitMillis(1000); Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>(); nodes.add(new HostAndPort("192.168.229.131", 7000)); nodes.add(new HostAndPort("192.168.229.131", 7001)); nodes.add(new HostAndPort("192.168.229.131", 7002)); nodes.add(new HostAndPort("192.168.229.132", 7003)); nodes.add(new HostAndPort("192.168.229.132", 7004)); nodes.add(new HostAndPort("192.168.229.132", 7005)); JedisCluster cluster = new JedisCluster(nodes, poolConfig); String name = cluster.get("name"); System.out.println(name); try { cluster.close(); } catch (Exception e) { e.printStackTrace(); } }
需要注意的是,如果连接不上,此时可能为pom.xml文件中jedis的版本不对,需要更新jedis的version
第六部分:spring整合redis集群
第一步:创建spring-redis.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="1000"/> <property name="maxIdle" value="10"/> <property name="minIdle" value="1"/> <property name="maxWaitMillis" value="30000"/> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="true"/> <property name="testWhileIdle" value="true"/> <!-- <property name="testWhileIdle" value="true"/> --> </bean> <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster"> <constructor-arg> <set> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="192.168.229.131"/> <constructor-arg name="port" value="7000"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="192.168.229.131"/> <constructor-arg name="port" value="7001"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="192.168.229.131"/> <constructor-arg name="port" value="7002"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="192.168.229.132"/> <constructor-arg name="port" value="7003"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="192.168.229.132"/> <constructor-arg name="port" value="7004"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="192.168.229.132"/> <constructor-arg name="port" value="7005"/> </bean> </set> </constructor-arg> <constructor-arg name="poolConfig" ref="jedisPoolConfig"/> </bean> </beans>
第二步:封装工具类
@Component public class RedisClusterUtils { @Autowired private JedisCluster jedisCluster; /** * 得到指定key值的value * @param key */ public Object get(String key){ return jedisCluster.get(key); } /** * 保存指定key值的value * @param key * @param value */ public void set(String key, String value){ jedisCluster.set(key, value); } /** * 保存指定key值的value * @param key * @param list */ public void set(String key, List<String> list){ jedisCluster.rpush(key, (String[]) list.toArray()); } /** * 删除指定key的value * @param key */ public void del(String key){ jedisCluster.del(key); } }
第三步:封装接口进行测试
@Autowired private RedisClusterUtils redis; @RequestMapping("/redis") public void reidsTest(){ redis.set("redis", "redis cluster"); System.err.println(redis.get("name")); }
打印出结果“magic”,正是我们之前在集群中输入的。

浙公网安备 33010602011771号