Redis集群架构环境搭建及jedis开发

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lanjian056/article/details/83507064

1、下载redis

     https://redis.io/download

2、安装redis

  • 上传安装文件到服务器的/usr/local目录下
  • 解压tar –zxvf redis-4.0.9.tar.gz
  • 进入redis目录,cd redis-4.0.9安装:make && make install

3、redis集群配置

1)在/usr/local创建redis_cluster文件夹 

2)进入到redis_cluster创建 9000、9001、9002、9003、9004、9005六个文件夹

3)在redis-4.0.9目录下找到redis.conf,复制redis.conf文件到9000、9001、9002、9003、9004、9005

4)修改9000、9001、9002、9003、9004、9005目录下的redis.conf配置(每个节点下的文件都需要修改,可以使用vi命令去修改,也可以在本地改好,在上传到服务器)

port  9000                                     //端口9000、9001、9002、9003、9004、9005      

bind  192.168.145.177                      //默认ip为192.168.145.177需要改为其他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群

daemonize    yes                       //redis后台运行

pidfile /var/run/redis_9000.pid       //pidfile文件对应9000、9001、9002、9003、9004、9005

cluster-enabled  yes               //开启集群  把注释#去掉

cluster-config-file  nodes_7000.conf  //集群的配置 9000、9001、9002、9003、9004、9005

cluster-node-timeout  15000        //请求超时  默认15秒,可自行设置

appendonly  yes                  //aof日志开启  有需要就开启,它会每次写操作都记录一条日志 

4、启动redis

在/usr/local目录下运行下面程序(redis-server这个命令在/usr/local/bin下面)

./bin/redis-server redis_cluster/9000/redis.conf

./bin/redis-server redis_cluster/9001/redis.conf

./bin/redis-server redis_cluster/9002/redis.conf

./bin/redis-server redis_cluster/9003/redis.conf

./bin/redis-server redis_cluster/9004/redis.conf

./bin/redis-server redis_cluster/9005/redis.conf

批量停止redis命令:pkill -9 redis

5、redis集群

redis运行环境需要ruby,因此需先按照ruby运行环境。

5.1、安装运行环境ruby

1)安装ruby

命令:yum -y install ruby ruby-devel rubygems rpm-build

2)安装rvm

命令:curl -L get.rvm.io | bash -s stable

第一次会失败,弹出需要公钥,然后

运行一下 gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

后面的这个串,每台机器都不一样,具体操作,看报错的信息。

再运行一次curl -L get.rvm.io | bash -s stable,即可安装rvm成功。

3)source环境,让rvm可用

source /usr/local/rvm/scripts/rvm

4)rvm list known查看可用的ruby

[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]

5)rvm install 2.4.1  选最新的安装

6)编译环境

gem install redis

7)安装rubygems

yum install -y rubygems
注意:如果yum用不了,需要先安装yum
https://jingyan.baidu.com/article/ed2a5d1f5a9fbe09f6be17ea.html

5.2、创建集群

命令:

/usr/local/redis-4.0.9/src/redis-trib.rb create --replicas  1  192.168.145.177:9000 192.168.145.177:9001 192.168.145.177:9002 192.168.145.177:9003 192.168.145.177:9004 192.168.145.177:9005

--replicas 1表示为集群的master节点创建1个副本。那么6个实例里,有三个master,有三个是slave。
提示Can I set the above configuration? (type 'yes' to accept): 
输入yes

即可

5.2验证集群

在目录/usr/local下,输入

命令:./bin/redis-cli -h 192.168.145.177 -p 9000 -c

输入:cluster info查看集群信息

输入:cluster nodes查看集群节点

测试:set test neusoft

get test

5.3验证集群容灾情况

1)查看redis进程:ps –ef|grep redis

2)关闭一台主redis,杀掉9001进程:kill -9 12783

3)再次进入9000的redis实例,查看现有的redis集群节点情况。

./bin/redis-cli -h 192.168.145.177 -p 9000 –c

cluster nodes

可以看到9001已经fail了,现在少了一台主redis。

4)启动9001,检测9001

/usr/local/redis-4.0.9/src/redis-trib.rb check 192.168.145.177:9001

查看集群节点信息:

9001变成从redis,9004变为主redis

6、jedis开发

6.1、Maven依赖

<dependency>

    <groupId>redis.clients</groupId>

    <artifactId>jedis</artifactId>

    <version>2.8.2</version>

</dependency>

6.2、编码

  RedisCacheUtil(Redis缓存操作类)

import org.apache.log4j.Logger;
import org.codehaus.jackson.type.TypeReference;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Redis缓存操作类
 *
 * @author: alex
 * @time: 2018-06-04
 * @version: 1.0
 */
public class RedisCacheUtil {

    private static Logger log = Logger.getLogger(RedisCacheUtil.class);

    /**
     * 存放String类型的值
     *
     * @param key   key值
     * @param value value值
     * @throws Exception
     */
    public void setString(String key, String value) throws Exception {
        try {
            RedisConfigUtil.getJedisCluster().set(key, value);
        } catch (Exception e) {
            log.error(e);
            throw new Exception("存储String对象的值出错");
        }
    }

    /**
     * 获取String类型的值
     *
     * @param key key值
     * @return 取得对应值
     * @throws Exception
     */
    public String getString(String key) throws Exception {
        String value = null;
        try {
            value = RedisConfigUtil.getJedisCluster().get(key);
        } catch (Exception e) {
            log.error(e);
            throw new Exception("获取String对象的值出错");
        }
        return value;
    }

    /**
     * 设置对象
     *
     * @param key    key值
     * @param object 对象
     * @throws Exception
     */
    public void setObject(String key, Object object) throws Exception {
        try {
            String json = JsonConvertUtil.objectConvertJSON(object);
            RedisConfigUtil.getJedisCluster().set(key, json);
        } catch (Exception e) {
            log.error(e);
            throw new Exception("存储Object对象的值出错");
        }
    }

    /**
     * 获取对象
     *
     * @param key  key值
     * @param type 获取对象的类型
     * @return 对象类型
     * @throws Exception
     */
    public Object getObject(String key, TypeReference<?> type) throws Exception {
        Object obj = null;
        try {
            if (RedisConfigUtil.getJedisCluster().exists(key)) {
                String json = RedisConfigUtil.getJedisCluster().get(key);
                obj = JsonConvertUtil.jsonConvertObject(json, type);
            }
        } catch (Exception e) {
            log.error(e);
            throw new Exception("获取Object对象的值出错");
        }
        return obj;
    }

    /**
     * 根据key、field取hash值,转换为对象
     *
     * @param key
     * @param field
     * @return
     * @throws Exception
     */
    public Object hGet(String key, String field, TypeReference<?> type) throws Exception {
        try {
            if (RedisConfigUtil.getJedisCluster().exists(key)) {
                String json = RedisConfigUtil.getJedisCluster().hget(key, field);
                return JsonConvertUtil.jsonConvertObject(json, type);
            }
            return null;
        } catch (Exception e) {
            log.error(e);
            throw new Exception("获取Hash时出错");
        }
    }

    /**
     * 取key对应的所有hash,返回hashmap
     *
     * @param key
     * @return
     * @throws Exception
     */
    public Map hGetAll(String key) throws Exception {
        try {
            if (RedisConfigUtil.getJedisCluster().exists(key)) {
                return RedisConfigUtil.getJedisCluster().hgetAll(key);
            }
            return null;
        } catch (Exception e) {
            log.error(e);
            throw new Exception("获取HashAll时出错");
        }
    }

    /**
     * 存放到缓存中,并设置失效时间
     *
     * @param key    key值
     * @param object 实体
     * @param min    失效时间
     * @throws Exception
     */
    public void setObjectByExpire(String key, Object object, int min) throws Exception {
        int seconds = min * 60;
        try {
            String json = JsonConvertUtil.objectConvertJSON(object);
            RedisConfigUtil.getJedisCluster().set(key, json);
            RedisConfigUtil.getJedisCluster().expire(key, seconds);
        } catch (Exception e) {
            log.error(e);
            throw new Exception("存储Object对象的值并设置失效时间操作出错");
        }
    }

    /**
     * 获取缓存信息
     *
     * @param key  key值
     * @param type 实体类型
     * @return 获取的对象
     * @throws Exception
     */
    public Object getExistObject(String key, TypeReference<?> type) throws Exception {
        try {
            if (RedisConfigUtil.getJedisCluster().exists(key)) {
                String json = RedisConfigUtil.getJedisCluster().get(key);
                return JsonConvertUtil.jsonConvertObject(json, type);
            }
            return null;
        } catch (Exception e) {
            log.error(e);
            throw new Exception("获取Object对象的值并设置失效时间操作出错");
        }
    }


    /**
     * 判断缓存中是否存在此key
     *
     * @param key key值
     * @return true存在,false不存在
     * @throws Exception
     */
    public boolean isExists(String key) throws Exception {
        boolean flag = false;
        try {
            flag = RedisConfigUtil.getJedisCluster().exists(key);
        } catch (Exception e) {
            log.error(e);
            throw new Exception("判断缓存中是否存在此key时出错");
        }
        return flag;
    }

    /**
     * 根据key值删除缓存内容
     *
     * @param key key值
     * @throws Exception
     */
    public void deleteByKey(String key) throws Exception {
        try {
            if (RedisConfigUtil.getJedisCluster().exists(key)) {
                RedisConfigUtil.getJedisCluster().del(key);
            }
        } catch (Exception e) {
            log.error(e);
            throw new Exception("删除此key时出错");
        }
    }

    /**
     * 将相同key值放入到链表中
     *
     * @param key    key值
     * @param object 对象
     * @throws Exception
     */
    public void setList(String key, Object object) throws Exception {
        try {
            String json = JsonConvertUtil.objectConvertJSON(object);
            RedisConfigUtil.getJedisCluster().rpush(key, json);
        } catch (Exception e) {
            log.error(e);
            throw new Exception("存储列表对象的值出错");
        }
    }

    /**
     * 获取列表对象
     *
     * @param key  key值
     * @param type 获取对象的类型
     * @return 对象类型
     * @throws Exception
     */
    public List<Object> getList(String key, TypeReference<?> type) throws Exception {
        try {
            List<Object> list = new ArrayList<Object>();
            Long size = RedisConfigUtil.getJedisCluster().llen(key);
            List<String> bis = RedisConfigUtil.getJedisCluster().lrange(key, 0, size.intValue() - 1);
            for (String bi : bis) {
                Object obj = JsonConvertUtil.jsonConvertObject(bi, type);
                list.add(obj);
            }
            return list;
        } catch (Exception e) {
            log.error(e);
            throw new Exception("获取列表对象出错");
        }
    }

    /**
     * 保存对象到set集合中,去掉重复数据
     *
     * @param key    key值
     * @param object 对象
     * @throws Exception
     */
    public void setSadd(String key, Object object) throws Exception {
        try {
            String json = JsonConvertUtil.objectConvertJSON(object);
            RedisConfigUtil.getJedisCluster().sadd(key, json);
        } catch (Exception e) {
            log.error(e);
            throw new Exception("保存对象到set集合中出错");
        }
    }

    /**
     * 获取所有set集合中的对象
     *
     * @param key  key值
     * @param type 获取对象的类型
     * @return 对象类型
     * @throws Exception
     */
    public List<Object> getSmembers(String key, TypeReference<?> type) throws Exception {
        try {
            List<Object> list = new ArrayList<Object>();
            java.util.Set<String> bis = RedisConfigUtil.getJedisCluster().smembers(key);
            for (String bi : bis) {
                Object obj = JsonConvertUtil.jsonConvertObject(bi, type);
                list.add(obj);
            }
            return list;
        } catch (Exception e) {
            log.error(e);
            throw new Exception("获取所有set集合中的对象出错");
        }
    }
}

RedisConfigUtil(Redis配置类)

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import java.util.LinkedHashSet;
import java.util.Set;

public class RedisConfigUtil {

    private static JedisCluster jedisCluster = null;

    private static Set<HostAndPort> nodes = null;

    private static JedisPoolConfig poolConfig = new JedisPoolConfig();

    static {
        nodes = new LinkedHashSet<HostAndPort>();
        nodes.add(new HostAndPort("192.168.145.177", 9000));
        nodes.add(new HostAndPort("192.168.145.177", 9001));
        nodes.add(new HostAndPort("192.168.145.177", 9002));
        nodes.add(new HostAndPort("192.168.145.177", 9003));
        nodes.add(new HostAndPort("192.168.145.177", 9004));
        nodes.add(new HostAndPort("192.168.145.177", 9005));
        // 最大连接数
        poolConfig.setMaxTotal(1);
        // 最大空闲数
        poolConfig.setMaxIdle(1);
        // 最大允许等待时间,如果超过这个时间还未获取到连接,则会报JedisException异常:
        poolConfig.setMaxWaitMillis(60000);
    }

    public static JedisCluster getJedisCluster() {
        if(jedisCluster == null) {
            jedisCluster = new JedisCluster(nodes, poolConfig);
        }
        return jedisCluster;
    }
}

 

json转换类JsonConvertUtil

import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import java.io.IOException;

/**
 * JSON转换
 * @author: alex
 * @time: 2018-06-04
 * @version: 1.0
 */
public class JsonConvertUtil {

    private static Logger log = Logger.getLogger(JsonConvertUtil.class);

    /**
     * 对象转换为JSON
     * @param obj
     * @return
     */
    public static String objectConvertJSON(Object obj) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(obj);
        } catch (IOException e) {
            log.error("对象转换为JSON出错", e);
        }

        return null;
    }
    /**
     * 对象转换为JSON
     * @param obj
     * @return
     */
    public static String toJSON(Object obj) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(obj);
        } catch (IOException e) {
            log.error("对象转换为JSON出错", e);
        }

        return null;
    }
    /**
     * json转换为对象
     * @param json
     * @param
     * @return
     */
    public static Object jsonConvertObject(String json,TypeReference<?> type){
        Object obj = null;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(json, type);
        } catch (IOException e) {
            log.error("JSON转换为对象出错", e);
        }

        return obj;
    }
    /**
     * json转换为对象
     * @param json
     * @param
     * @return
     */
    public static Object jsonConvertObject(String json,Class<?> clazz){
        Object obj = null;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(json, clazz);
        } catch (IOException e) {
            log.error("JSON转换为对象出错", e);
        }
        return obj;
    }
}

 

测试类:

import com.google.gson.reflect.TypeToken;
import org.codehaus.jackson.type.TypeReference;


public class RedisTest {

    public static void main(String[] args) {
        RedisCacheUtil redisUtil = new RedisCacheUtil();
        try {
//            redisUtil.setObject("test","alex");
//            redisUtil.getObject("test",  new TypeReference<String>() {});
            redisUtil.setString("test", "hello world!");
            System.out.println(redisUtil.getString("test"));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

 

6.3、运行报错

No reachable node in cluster

原因:访问不了redis集群信息。

解决办法:

1)关闭防火墙:

systemctl stop firewalld

2)安装iptables:

yum install -y iptables

yum install iptables-services

3)编辑可访问端口:

vi /etc/sysconfig/iptables

增加的位置很重要,不能改变顺序

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -i lo -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 9000 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 9001 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 9002 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 9003 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 9004 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 9005 -j ACCEPT

-A INPUT -j REJECT --reject-with icmp-host-prohibited

-A FORWARD -j REJECT --reject-with icmp-host-prohibited

4)重启

systemctl restart iptables.service

or

service iptables restart

7、参考文档

https://www.cnblogs.com/yingchen/p/6763524.html

https://www.cnblogs.com/kangoroo/p/7657616.html

https://blog.csdn.net/appleyk/article/details/78325499

https://blog.csdn.net/wojiushifeng1992/article/details/729040

猜你喜欢

转载自blog.csdn.net/lanjian056/article/details/83507064