1. 程式人生 > >redis集群安裝到使用

redis集群安裝到使用

org serve ems -- uil *** oot getclass ice

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();
}
}*/
}

遇到問題:

1.redis集群出現JedisNoReachableClusterNodeException異常(No reachable node in cluster)

上午午好好的,突然拋了如下異常:

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進行操作時就會出現如上錯誤。

redis集群安裝到使用