Redis-3.x集群配置(RedisCluster+SpringBoot+Jedis)

古城微笑少年丶 2022-05-26 07:48 400阅读 0赞
Redis-3.x集群配置(RedisCluster+SpringBoot+Jedis)

部署计划

部署6个redis节点,为3主3从。
































端口 IP地址
6379 192.168.101.121
6379
192.168.101.199
6379
192.168.101.123
6379
192.168.101.127
6379
192.168.101.125
6379
192.168.101.126

编译安装

(所有关于权限问题全部sudo,启动服务 sudo ./redis-server /data/redis/conf/redis.conf,真实环境下,若是以一个较低的权限启动redis,那么就可能产生无法创建日志以及rdb的问题)

创建目录

mkdir redis

cd redis

下载解压安装包

wget http://download.redis.io/releases/redis-3.2.4.tar.gz

tar zxvf redis-3.2.4.tar.gz

cd redis-3.2.4

make

make install PREFIX=/data/redis-3.2.4 //默认安装到/usr/local/bin目录下。这里指定安装目录data/redis-3.2.4

ln -s /data/redis-3.2.4 /data/redis //软连接

mkdir /data/redis/conf //创建目录结构

mkdir /data/redis/log

mkdir /data/redis/data

cp /home/redis/redis/redis-3.2.4/redis.conf /data/redis/conf/ //copy配置文件

vim /data/redis/conf/redis.conf

redis的配置

protected-mode no //关闭保护模式

port 6379 //端口

daemonize yes //守护进程开启,默认服务从后台启动

loglevel verbose //日志级别

logfile /data/redis/log/redis-6379.log //日志文件位置

==redis持久化rdb,AOF相关==

dbfilename dump.rdb //redis持久化文件名称

dir /data/redis/data/6379 //redis持久化文件路径,默认为当前路径

appendonly yes //开启AOF

appendfilename “appendonly.aof” //AOF文件名称

no-appendfsync-on-rewrite yes //子进程在做rewrite时,主进程不调用fsync(由内核默认调度)

==REPLICATION==

slave-serve-stale-data yes //当slave与master断开连接,slave继续提供服务

slave-read-only yes

repl-ping-slave-period 1 //slave ping master的时间间隔,单位为秒

repl-timeout 10 //复制超时,单位为秒,须大于repl-ping-slave-period的值

==REDIS CLUSTER==

cluster-enabled yes //开启集群配置

cluster-config-file nodes-6379.conf //节点配置文件,这个文件是服务启动时自己配置创建的

cluster-node-timeout 5000 //集群中各节点相互通讯时,允许”失联”的最大毫秒数,如果超过没向其它节点汇报成功,就认为该节点已挂。

cluster-slave-validity-factor 0 //将该项设置为0,不管slave节点和master节点间失联多久都会一直尝试failover

repl-ping-slave-period 1

其他5台机器配置

相同操作目录可直接远程拷贝

scp -r redis@192.168.101.126:/data/redis/data /data/redis/

scp -r redis@192.168.101.126:/data/redis/conf /data/redis/

scp -r redis@192.168.101.126:/data/redis/log /data/redis/

创建和启动redis cluster前的准备工作

yum -y install ruby //安装ruby

yum -y install rubygems //安装rubygems

wget https://rubygems.org/downloads/redis-3.3.1.gem //安装redis-3.3.1.gem

gem install -l redis-3.3.1.gem

cp redis-3.2.4/src/redis-trib.rb /data/redis/bin/ //redis-trib.rb是redis官方提供的redis cluster管理工具,使用ruby实现。

./redis-server /data/redis/conf/redis.conf //启动6台服务

创建redis cluster

redis-trib.rb create —replicas 1 192.168.101.121:6379 192.168.101.199:6379 192.168.101.123:6379 192.168.101.127:6379 192.168.101.125:6379 192.168.101.126:6379

#redis-trib.rb的create子命令构建

#—replicas 则指定了为Redis Cluster中的每个Master节点配备几个Slave节点

进入redis客户端

redis-cli -c -p 6379 //-c进入集群模式

info//查看信息

cluster nodes//查看节点信息

CLUSTER SLOTS//查看插槽信息

节点操作

./redis-trib.rb del-node 192.168.101.121:6379 ‘2ff326bc9084236ee6540d58d307893662ceff0b’//删除节点

./redis-trib.rb add-node —slave —master-id 0ecc54ed34cc7e2e1ebca168ab4564b803992094 192.168.101.121:6379 192.168.101.125:6379//添加从节点,添加前需要删除已存在的node.conf,rdb,aof文件

./redis-trib.rb reshard 192.168.101.121:6379//为新节点分配slot

./redis-trib.rb check 192.168.101.121:6379 //检查集群运行状态,只要输入任意集群中节点即可,会自动检查所有相关节点。

./redis-trib.rb fix 192.168.101.121:6379 //修复集群(若node移除了,但是并没有移除node上面的slot,从而导致了slot总数没有达到16384,其实也就是slots分布不正确。所以在删除节点的时候一定要注意删除的是否是Master主节点)。

关于集群创建错误

集群创建的时候如果没有创建成功,那么需要删除集群节点配置文件,不然无法重新创建集群

sudo rm /data/redis-3.2.4/data/6379/nodes-6379.conf

如果遇到Waiting for the cluster to join ……………………………………………….

>>> Sending CLUSTER MEET messages to join the cluster

解决方式

sudo ./redis-cli -c -p 6379 //进入客户端

CLUSTER MEET 将 ip 和 port 所指定的节点添加到集群当中。

Jedis的配置

config文件需要添加

github上有这一句,Jedis Cluster 会自动去发现集群中的节点,所以JedisClusterNodes只需要 add一个实例

// JedisCluster

@Bean

public JedisCluster JedisClusterFactory() {

LOG.info("JedisCluster创建!!");

LOG.info("redis地址:" + host + ":" + port);

Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();

JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

jedisPoolConfig.setMaxIdle(maxIdle);

jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);

jedisClusterNodes.add(new HostAndPort(host, port));

JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, jedisPoolConfig);

return jedisCluster;

}

dao

package com.unioncast.db.rdbms.core.dao.commonDBDao.impl;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Repository;

import com.unioncast.common.util.JsonUtil;

import com.unioncast.db.rdbms.core.dao.commonDBDao.RedisDao;

import redis.clients.jedis.JedisCluster;

@Repository("redisDao")

public class RedisDaoImpl implements RedisDao {

@Autowired

JedisCluster jedisCluster;

@Override

public <T> String addByKey(String key, T object) throws IOException {

String object2JsonString = JsonUtil.object2JsonString(object);

String set = jedisCluster.set(key, object2JsonString);

return set;

}

@Override

public <T> String add(T object) throws IOException {

String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");

String object2JsonString = JsonUtil.object2JsonString(object);

jedisCluster.set(uuid, object2JsonString);

return uuid;

}

@Override

public Object getObject(String key) throws IOException {

String string = jedisCluster.get(key);

Object json2Object = JsonUtil.json2Object(string, Object.class);

return json2Object;

}

@Override

public <T> List<String> addList(List<T> list) throws IOException {

List<String> sum = new ArrayList<>(70);

String uuid = null;

String str = null;

for (int i = 0; i < list.size(); i++) {

uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");

str = JsonUtil.object2JsonString(list.get(i));

jedisCluster.set(uuid, str);

sum.set(i, uuid);

}

return sum;

}

@Override

public <T> String addListKey(List<String> strList, List<T> list) throws IOException {

return null;

}

@Override

public <T> Long addListKey(Map<String, T> map) throws IOException {

Long sum = (long) 0;

String str = null;

Iterator<Entry<String, T>> iterator = map.entrySet().iterator();

while (iterator.hasNext()) {

Entry<String, T> entry = (Entry<String, T>) iterator.next();

String key = entry.getKey();

T object = entry.getValue();

str = JsonUtil.object2JsonString(object);

jedisCluster.set(key, str);

sum = sum + 1;

}

return sum;

}

@Override

public Long deleteByKey(String key) throws IOException {

Long del = jedisCluster.del(key);

return del;

}

@Override

public Long batchDelete(List<String> strList) throws IOException {

Long sum = (long) 0;

Long del = (long) 0;

for (int i = 0; i < strList.size(); i++) {

del = jedisCluster.del(strList.get(i));

sum = sum + del;

}

return sum;

}

}

config

package com.unioncast.db.config;

import java.lang.reflect.Method;

import java.util.HashSet;

import java.util.Set;

import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.cache.CacheManager;

import org.springframework.cache.annotation.CachingConfigurerSupport;

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.cache.interceptor.KeyGenerator;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.PropertySource;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;

import com.fasterxml.jackson.annotation.PropertyAccessor;

import com.fasterxml.jackson.databind.ObjectMapper;

import redis.clients.jedis.HostAndPort;

import redis.clients.jedis.JedisCluster;

import redis.clients.jedis.JedisPool;

import redis.clients.jedis.JedisPoolConfig;

@Configuration

@PropertySource(value = "classpath:/redis.properties")

@EnableCaching

public class RedisConfig extends CachingConfigurerSupport {

// @Value("${spring.redis.host}")

// private String host;

// @Value("${spring.redis.port}")

// private int port;

// @Value("${spring.redis.timeout}")

// private int timeout;

private static final Logger LOG = LogManager.getLogger(RedisConfig.class);

@Value("${spring.redis.host}")

private String host;

@Value("${spring.redis.port}")

private int port;

@Value("${spring.redis.timeout}")

private int timeout;

@Value("${spring.redis.pool.max-idle}")

private int maxIdle;

@Value("${spring.redis.pool.max-wait}")

private long maxWaitMillis;

/*

* @Value("${spring.redis.password}") private String password;

*/

// Jedis连接池

@Bean

public JedisPool redisPoolFactory() {

LOG.info("JedisPool注入成功!!");

LOG.info("redis地址:" + host + ":" + port);

JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

jedisPoolConfig.setMaxIdle(maxIdle);

jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);

// JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port,

// timeout, password);

JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);

``

return jedisPool;

}

``

// JedisCluster

@Bean

public JedisCluster JedisClusterFactory() {

LOG.info("JedisCluster创建!!");

LOG.info("redis地址:" + host + ":" + port);

Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();

JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

jedisPoolConfig.setMaxIdle(maxIdle);

jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);

jedisClusterNodes.add(new HostAndPort(host, port));

JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, jedisPoolConfig);

return jedisCluster;

}

@Bean

public KeyGenerator wiselyKeyGenerator() {

return new KeyGenerator() {

@Override

public Object generate(Object target, Method method, Object... params) {

StringBuilder sb = new StringBuilder();

sb.append(target.getClass().getName());

sb.append(method.getName());

for (Object obj : params) {

sb.append(obj.toString());

}

return sb.toString();

}

};

}

@Bean

public JedisConnectionFactory redisConnectionFactory() {

JedisConnectionFactory factory = new JedisConnectionFactory();

factory.setHostName(host);

factory.setPort(port);

factory.setTimeout(timeout); // 设置连接超时时间

return factory;

}

@Bean

public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {

RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);

// Number of seconds before expiration. Defaults to unlimited (0)

cacheManager.setDefaultExpiration(10); // 设置key-value超时时间

return cacheManager;

}

@Bean

public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {

StringRedisTemplate template = new StringRedisTemplate(factory);

setSerializer(template); // 设置序列化工具,这样ReportBean不需要实现Serializable接口

template.afterPropertiesSet();

return template;

}

private void setSerializer(StringRedisTemplate template) {

Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(

Object.class);

ObjectMapper om = new ObjectMapper();

om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

jackson2JsonRedisSerializer.setObjectMapper(om);

template.setValueSerializer(jackson2JsonRedisSerializer);

}

}

发表评论

表情:
评论列表 (有 0 条评论,400人围观)

还没有评论,来说两句吧...

相关阅读