集群搭建系列教程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
View Code

第六步:安装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.
View Code

中间会有一个选项,问你是否要使用这些配置信息,选择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>                         
View Code

第二步:封装工具类

@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);  
    }  
}  
View Code

第三步:封装接口进行测试

@Autowired
      private RedisClusterUtils redis;
      @RequestMapping("/redis")
      public void reidsTest(){
        redis.set("redis", "redis cluster");
        System.err.println(redis.get("name"));
      }
View Code

打印出结果“magic”,正是我们之前在集群中输入的。

posted @ 2018-01-24 11:27  一介書生  阅读(353)  评论(0)    收藏  举报