redis集群安裝到使用

redis
1、cd /root/software

2、wget http://download.redis.io/releases/redis-4.0.9.tar.gz

3、tar -zxvf redis-4.0.9.tar.gz 

4、
(1) make
cd src && make all
make[1]: 进入目录“/usr/local/redis-3.2.0/src”
CC adlist.o
/bin/sh: cc: 未找到命令
make[1]: *** [adlist.o] 错误 127
make[1]: 离开目录“/usr/local/redis-3.2.0/src”
make: *** [all] 错误 2


解決:yum install gcc-c++

(2)make
cd src && make all
make[1]: 进入目录“/usr/local/redis-3.2.0/src”
CC adlist.o
In file included from adlist.c:34:0:
zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录
#include <jemalloc/jemalloc.h>
解决“jemalloc/jemalloc.h:没有那个文件或目录“问题,在进行编译(因为上次编译失败,有残留的文件)

# make distclean

# make && make install


1.本地启动:./redis-cli
./redis-server ../redis.conf 命令启动server
远程启动:redis-cli -h host -p port -a password

2.AUTH password 验证密码是否正确

3.ECHO message 打印字符串

4.PING 查看服务是否运行

QUIT 关闭当前连接

SELECT index 切换到指定的数据库


5. 启动各个节点

复制代码
第一台机器上执行
./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
复制代码
6. 检查 redis 启动情况

复制代码
##一台机器<br>ps -ef | grep redis
root 61020 1 0 02:14 ? 00:00:01 redis-server 127.0.0.1:7000 [cluster]
root 61024 1 0 02:14 ? 00:00:01 redis-server 127.0.0.1:7001 [cluster]
root 61029 1 0 02:14 ? 00:00:01 redis-server 127.0.0.1:7002 [cluster]

netstat -tnlp | grep redis
tcp 0 0 127.0.0.1:17000 0.0.0.0:* LISTEN 61020/redis-server
tcp 0 0 127.0.0.1:17001 0.0.0.0:* LISTEN 61024/redis-server
tcp 0 0 127.0.0.1:17002 0.0.0.0:* LISTEN 61029/redis-server
tcp 0 0 127.0.0.1:7000 0.0.0.0:* LISTEN 61020/redis-server
tcp 0 0 127.0.0.1:7001 0.0.0.0:* LISTEN 61024/redis-server
tcp 0 0 127.0.0.1:7002 0.0.0.0:* LISTEN 61029/redis-server
1
2
3
4
5
6
7
8
9
10
11
12
13

##另外一台机器
ps -ef | grep redis
root 9957 1 0 02:32 ? 00:00:01 redis-server 127.0.0.1:7003 [cluster]
root 9964 1 0 02:32 ? 00:00:01 redis-server 127.0.0.1:7004 [cluster]
root 9971 1 0 02:32 ? 00:00:01 redis-server 127.0.0.1:7005 [cluster]
root 10065 4744 0 02:38 pts/0 00:00:00 grep --color=auto redis
netstat -tlnp | grep redis
tcp 0 0 127.0.0.1:17003 0.0.0.0:* LISTEN 9957/redis-server 1
tcp 0 0 127.0.0.1:17004 0.0.0.0:* LISTEN 9964/redis-server 1
tcp 0 0 127.0.0.1:17005 0.0.0.0:* LISTEN 9971/redis-server 1
tcp 0 0 127.0.0.1:7003 0.0.0.0:* LISTEN 9957/redis-server 1
tcp 0 0 127.0.0.1:7004 0.0.0.0:* LISTEN 9964/redis-server 1
tcp 0 0 127.0.0.1:7005 0.0.0.0:* LISTEN 9971/redis-server 1
复制代码

7.创建集群

Redis 官方提供了 redis-trib.rb 这个工具,就在解压目录的 src 目录中,第三步中已将它复制到 /usr/local/bin 目录中,可以直接在命令行中使用了。使用下面这个命令即可完成安装。

./redis-trib.rb create --replicas 1 192.168.146.130:7000 192.168.146.130:7001 192.168.146.130:7002
192.168.146.131:7003 192.168.146.131:7004 192.168.146.131:7005


其中,前三个 ip:port 为第一台机器的节点,剩下三个为第二台机器。

等等,出错了。这个工具是用 ruby 实现的,所以需要安装 ruby。安装命令如下:

7.1、yum -y install ruby ruby-devel rubygems rpm-build

7.2、gem install redis

redis需要Ruby版本> = 2.2.2

1.安装RVM:
gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
curl -L get.rvm.io | bash -s stable
find / -name rvm -print

2.查看RVM库中已知的红宝石版本
rvm list known

3.安装一个红宝石版本
rvm install 2.4.1

4.使用一个ruby版本
rvm use 2.4.1

5.设置默认版本
rvm use 2.4.1 --default

6.卸载一个已知版本
rvm remove 2.0.0

7.查看红宝石版本:
ruby --version
红宝石2.4.1p222([x86_64-linux]

8.安装Redis的:
gem install redis

之后再运行 redis-trib.rb 命令,会出现如下提示:

输入 yes 即可,然后出现如下内容,说明安装成功。

9. 集群验证

在第一台机器上连接集群的7002端口的节点,在另外一台连接7005节点,连接方式为 ./redis-cli -h 192.168.146.130 -c -p 7002 -a 123456 ,
加参数 -C 可连接到集群,因为上面 redis.conf 将 bind 改为了ip地址,所以 -h 参数不可以省略。

在7005节点执行命令 set hello world ,执行结果如下:

然后在另外一台7002端口,查看 key 为 hello 的内容, get hello ,执行结果如下:

说明集群运作正常.

一、netstat
netstat -ntlp //查看当前所有tcp端口·

netstat -ntulp |grep 80 //查看所有80端口使用情况·

netstat -an | grep 3306 //查看所有3306端口使用情况·

Linux关闭防火墙命令
在外部访问CentOS中部署应用时,需要关闭防火墙。

关闭防火墙命令:systemctl stop firewalld.service

开启防火墙:systemctl start firewalld.service

关闭开机自启动:systemctl disable firewalld.service

开启开机启动:systemctl enable firewalld.service

1.先倒入jar包pom.xml

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>

2.application.properties

#redis
redis.host=192.168.146.130
redis.port=6379
redis.timeout=3
redis.password=123456
redis.poolMaxTotal=10
redis.poolMaxIdle=10
redis.poolMaxWait=3
redis.clusterNodes=192.168.146.130:7000, 192.168.146.130:7001, 192.168.146.130:7002 , 192.168.146.131:7003, 192.168.146.131:7004, 192.168.146.131:7005

 3.RedisConfig 

package com.imooc.miaosha.redis;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix="redis")
public class RedisConfig {
private String host;
private int port;
private String clusterNodes;
private int timeout;//秒
private String password;
private int poolMaxTotal;
private int poolMaxIdle;
private int poolMaxWait;//秒

public String getClusterNodes() {
return clusterNodes;
}
public void setClusterNodes(String clusterNodes) {
this.clusterNodes = clusterNodes;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPoolMaxTotal() {
return poolMaxTotal;
}
public void setPoolMaxTotal(int poolMaxTotal) {
this.poolMaxTotal = poolMaxTotal;
}
public int getPoolMaxIdle() {
return poolMaxIdle;
}
public void setPoolMaxIdle(int poolMaxIdle) {
this.poolMaxIdle = poolMaxIdle;
}
public int getPoolMaxWait() {
return poolMaxWait;
}
public void setPoolMaxWait(int poolMaxWait) {
this.poolMaxWait = poolMaxWait;
}
}

4.JedisCluster

package com.imooc.miaosha.redis;

import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

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

@Service
public class RedisPoolFactory {

@Autowired
RedisConfig redisConfig;

/*@Bean
public JedisPool JedisPoolFactory() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle());
poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000);

JedisPool jp = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(),
redisConfig.getTimeout() * 1000, redisConfig.getPassword(), 0);
return jp;
}*/

@Bean
public JedisCluster getJedisCluster() {

String[] serverArr = redisConfig.getClusterNodes().split(",");

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

for (String ipPort : serverArr) {
String[] ips = ipPort.split(":");
nodes.add(new HostAndPort(ips[0].trim(), Integer.valueOf(ips[1].trim())));
}

JedisPoolConfig poolConfig = new JedisPoolConfig();

poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle());

poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());

poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000);

return new JedisCluster(nodes,redisConfig.getTimeout() * 1000,redisConfig.getTimeout() * 1000,5,redisConfig.getPassword(),poolConfig);
}

}

5.創建RedisService 

package com.imooc.miaosha.redis;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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

import com.alibaba.fastjson.JSON;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

@Service
public class RedisService {

//@Autowired
//JedisPool jedisPool;

@Autowired
JedisCluster jediscluster;

/**
* jediscluster设置对象
* */
public <T> boolean set(KeyPrefix prefix, String key, T value) {

try {

String str = beanToString(value);
if(str == null || str.length() <= 0) {
return false;
}
//生成真正的key
String realKey = prefix.getPrefix() + key;
int seconds = prefix.expireSeconds();
if(seconds <= 0) {
jediscluster.set(realKey, str);
}else {
jediscluster.setex(realKey, seconds, str);
}
return true;
}finally {
//returnToPoolCluster(jediscluster);
}
}

/**
* jediscluster获取当个对象
* */
public <T> T get(KeyPrefix prefix, String key, Class<T> clazz) {

try {
//生成真正的key
String realKey = prefix.getPrefix() + key;
String str = jediscluster.get(realKey);
T t = stringToBean(str, clazz);
return t;
}finally {
// returnToPoolCluster(jediscluster);
}
}
/**
* jediscluster判断key是否存在
* */
public <T> boolean exists(KeyPrefix prefix, String key) {
try {
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jediscluster.exists(realKey);
}finally {
// returnToPoolCluster(jediscluster);
}
}

/**
* 删除
* */
public boolean delete(KeyPrefix prefix, String key) {
try {
//生成真正的key
String realKey = prefix.getPrefix() + key;
long ret = jediscluster.del(realKey);
return ret > 0;
}finally {
// returnToPoolCluster(jediscluster);
}
}

/**
* jediscluster增加值
* */
public <T> Long incr(KeyPrefix prefix, String key) {
try {
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jediscluster.incr(realKey);
}finally {
// returnToPoolCluster(jediscluster);
}
}

/**
* jediscluster减少值
* */
public <T> Long decr(KeyPrefix prefix, String key) {
try {
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jediscluster.decr(realKey);
}finally {
// returnToPoolCluster(jediscluster);
}
}
/**
* jediscluster
* @param prefix
* @return
*/
public boolean delete(KeyPrefix prefix) {
if(prefix == null) {
return false;
}
List<String> keys = scanKeys(prefix.getPrefix());
if(keys==null || keys.size() <= 0) {
return true;
}
try {
jediscluster.del(keys.toArray(new String[0]));
return true;
} catch (final Exception e) {
e.printStackTrace();
return false;
} finally {
// returnToPoolCluster(jediscluster);

}
}public List<String> scanKeys(String key) {
try {
List<String> keys = new ArrayList<String>();
String cursor = "0";
ScanParams sp = new ScanParams();
sp.match("*"+key+"*");
sp.count(100);
do{
ScanResult<String> ret = jediscluster.scan(cursor, sp);
List<String> result = ret.getResult();
if(result!=null && result.size() > 0){
keys.addAll(result);
}
//再处理cursor
cursor = ret.getStringCursor();
}while(!cursor.equals("0"));
return keys;
} finally {
//returnToPoolCluster(jediscluster);
}
}
@SuppressWarnings("unused")
private void returnToPoolCluster(JedisCluster jedisCluster) {
if(jedisCluster != null) {
try {
jedisCluster.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static <T> String beanToString(T value) {
if(value == null) {
return null;
}
Class<?> clazz = value.getClass();
if(clazz == int.class || clazz == Integer.class) {
return ""+value;
}else if(clazz == String.class) {
return (String)value;
}else if(clazz == long.class || clazz == Long.class) {
return ""+value;
}else {
return JSON.toJSONString(value);
}
}

@SuppressWarnings("unchecked")
public static <T> T stringToBean(String str, Class<T> clazz) {
if(str == null || str.length() <= 0 || clazz == null) {
return null;
}
if(clazz == int.class || clazz == Integer.class) {
return (T)Integer.valueOf(str);
}else if(clazz == String.class) {
return (T)str;
}else if(clazz == long.class || clazz == Long.class) {
return (T)Long.valueOf(str);
}else {
return JSON.toJavaObject(JSON.parseObject(str), clazz);
}
}

/******************************************************************************************************************
* 设置对象
* */
/*public <T> boolean setjediscluster(KeyPrefix prefix, String key, T value) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String str = beanToString(value);
if(str == null || str.length() <= 0) {
return false;
}
//生成真正的key
String realKey = prefix.getPrefix() + key;
int seconds = prefix.expireSeconds();
if(seconds <= 0) {
jedis.set(realKey, str);
}else {
jedis.setex(realKey, seconds, str);
}
return true;
}finally {
returnToPool(jedis);
}
}

*//**
* 判断key是否存在
* *//*
public <T> boolean existsjediscluster(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jedis.exists(realKey);
}finally {
returnToPool(jedis);
}
}

*//**
* 删除
* *//*
public boolean deletejediscluster(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
String realKey = prefix.getPrefix() + key;
long ret = jedis.del(realKey);
return ret > 0;
}finally {
returnToPool(jedis);
}
}

*//**
* 增加值
* *//*
public <T> Long incrjediscluster(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jedis.incr(realKey);
}finally {
returnToPool(jedis);
}
}

*//**
* 减少值
* *//*
public <T> Long decrjediscluster(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jedis.decr(realKey);
}finally {
returnToPool(jedis);
}
}

public boolean deletejediscluster(KeyPrefix prefix) {
if(prefix == null) {
return false;
}
List<String> keys = scanKeys(prefix.getPrefix());
if(keys==null || keys.size() <= 0) {
return true;
}
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.del(keys.toArray(new String[0]));
return true;
} catch (final Exception e) {
e.printStackTrace();
return false;
} finally {
if(jedis != null) {
jedis.close();
}
}
}

public List<String> scanKeys(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
List<String> keys = new ArrayList<String>();
String cursor = "0";
ScanParams sp = new ScanParams();
sp.match("*"+key+"*");
sp.count(100);
do{
ScanResult<String> ret = jedis.scan(cursor, sp);
List<String> result = ret.getResult();
if(result!=null && result.size() > 0){
keys.addAll(result);
}
//再处理cursor
cursor = ret.getStringCursor();
}while(!cursor.equals("0"));
return keys;
} finally {
if (jedis != null) {
jedis.close();
}
}
}

public static <T> String beanToString(T value) {
if(value == null) {
return null;
}
Class<?> clazz = value.getClass();
if(clazz == int.class || clazz == Integer.class) {
return ""+value;
}else if(clazz == String.class) {
return (String)value;
}else if(clazz == long.class || clazz == Long.class) {
return ""+value;
}else {
return JSON.toJSONString(value);
}
}

@SuppressWarnings("unchecked")
public static <T> T stringToBean(String str, Class<T> clazz) {
if(str == null || str.length() <= 0 || clazz == null) {
return null;
}
if(clazz == int.class || clazz == Integer.class) {
return (T)Integer.valueOf(str);
}else if(clazz == String.class) {
return (T)str;
}else if(clazz == long.class || clazz == Long.class) {
return (T)Long.valueOf(str);
}else {
return JSON.toJavaObject(JSON.parseObject(str), clazz);
}
}

private void returnToPool(Jedis jedis) {
if(jedis != null) {
jedis.close();
}
}*/
}

遇到問題:

上午午好好的,突然抛了如下异常:

Exception in thread "main" redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException: No reachable node in cluster
    at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnection(JedisSlotBasedConnectionHandler.java:57)
    at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot(JedisSlotBasedConnectionHandler.java:74)
    at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:116)
    at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:31)
    at redis.clients.jedis.JedisCluster.set(JedisCluster.java:103)
    at com.java.example.redis.JedisClusterDemo.setTest(JedisClusterDemo.java:33)
    at com.java.example.redis.JedisClusterDemo.main(JedisClusterDemo.java:28)

先说真正原因:

经过查找代码终于发现,最终是调用JedisCluster.close()方法造成的。

原因:我们使用的是redis3.0的集群,用jedis的JedisCluster.close()方法造成的集群连接关闭的情况。 jedisCluster内部使用了池化技术,每次使用完毕都会自动释放Jedis因此不需要关闭。如果调用close方法后再调用jedisCluster的api进行操作时就会出现如上错误。

 

原文地址:https://www.cnblogs.com/523823-wu/p/9096758.html