(七)使用jedis连接单机和集群(一步一个坑踩出来的辛酸泪)
环境准备:
redis-4.0.9,最新版了
ruby:redis-x.x.x.gem 这个gem什么版本都行,我redis4用3.0.0的gem正常跑
jedis-2.9.0.jar,最新版
伪集群搭建:这里省略了,需要的看我前面的文档,这里只贴出来一些关键点
1、下载、解压
# make
# make install PREFIX=/usr/local/bin/
2、创建集群工作目录,把redis/bin复制进去,需要几台集群自己看着办
3、修改每个节点的配置文件
port //端口7001,7002,7003...
bind 本机ip //默认ip为127.0.0.1 需要改为其他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群,直接注释掉
daemonize yes //redis后台运行
cluster-enabled yes //开启集群 把注释#去掉
protect_mode no //如果bind注释掉了,那么就把保护模式关掉
#可选项 cluster-config-file nodes.conf //集群的配置 配置文件首次启动自动生成,默认就行
cluster-node-timeout //请求超时 默认15秒,可自行设置
appendonly yes //aof日志开启 有需要就开启,它会每次写操作都记录一条日志
4、安装ruby、rubygems、redis.x.x.x.gem
# yum install ruby
# yum install rubygems
# 去官网下redis-x.x.x.gem,.0以上都行
# gem install redis-4.0..gem
5、构建以下目录

解释:
redis-cli:客户端,方便调试用
reids-trib.rb:集群的ruby脚本,去源码包复制过来
start-all-nodes.h:shell脚本,启动所有节点(参考下图)
stop-all-nodes.h:shell脚本,关闭集群(参考下图)
redis-cluster-configure.sh:开始集群部署,需要node节点全部启动(参考下图)



6、依次执行shell即可(start-all-nodes.sh ---> redis-cluster-configure.sh ---> input "yes")
集群测试:
@Test
public void testCluster() throws IOException, InterruptedException {
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("47.100.101.31", 7001));
nodes.add(new HostAndPort("47.100.101.31", 7002));
nodes.add(new HostAndPort("47.100.101.31", 7003));
nodes.add(new HostAndPort("47.100.101.31", 7004));
nodes.add(new HostAndPort("47.100.101.31", 7005));
nodes.add(new HostAndPort("47.100.101.31", 7006));
JedisCluster cluster = new JedisCluster(nodes);
try {
String res = cluster.get("name");
System.out.println(res);
cluster.close();
} catch (Exception e) {
e.printStackTrace();
cluster.close();
}
}
遇到的坑:
1)连接报错:Connection refused。
错误原因:远程拒绝链接,单机版和集群都报错。
解决方案:当时bind 127.0.0.1。于是乎注释掉,不行,提示没有bind于是启动了保护模式,所以配置:protect_mode no,单机版ok,redis客户端连集群ok。
2)通过jedis连接redis单机成功,使用JedisCluster连接redis集群一直报Could not get a resource from the pool,但是使用redis客户端可以连接集群(我使用的redis desktop manager)在java中通过jedis连接redis单机也成功,但使用JedisCluster连接redis集群一直报Could not get a resource from the pool,
错误原因:未知,以为jar包版本问题,换最新版2.9.0.jar,无效。纠结了好几天,最后看一个博客说把127.0.0.1换成公网ip
解决:127.0.0.1换成公网IP,于是直接跑通。
疑问:127.0.0.1表示的就是本地,启动后对外网来说127就是公网ip了,不知道为啥会错,因为用其他客户端都没问题,怀疑是jedis内部机制导致的。
附录:Spring集成redis
<!-- Jedis连接池配置, 可以写在资源文件中 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大连接数 -->
<property name="maxTotal" value="30" />
<!-- 最大空闲连接数 -->
<property name="maxIdle" value="10" />
<!-- 每次释放连接的最大数目 -->
<property name="numTestsPerEvictionRun" value="1024" />
<!-- 释放连接的扫描间隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<!-- 连接最小空闲时间 -->
<property name="minEvictableIdleTimeMillis" value="1800000" />
<!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
<property name="maxWaitMillis" value="1500" />
<!-- 在获取连接的时候检查有效性, 默认false -->
<property name="testOnBorrow" value="true" />
<!-- 在空闲时检查有效性, 默认false -->
<property name="testWhileIdle" value="true" />
<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="false" />
</bean>
<!-- jedis客户端单机版 -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="47.100.101.31" />
<constructor-arg name="port" value="6379" />
<constructor-arg name="poolConfig" ref="jedisPoolConfig" />
</bean>
<!-- Jedis集群版 -->
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="47.100.101.31"/>
<constructor-arg name="port" value="7001"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="47.100.101.31"/>
<constructor-arg name="port" value="7002"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="47.100.101.31"/>
<constructor-arg name="port" value="7003"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="47.100.101.31"/>
<constructor-arg name="port" value="7004"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="47.100.101.31"/>
<constructor-arg name="port" value="7005"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="47.100.101.31"/>
<constructor-arg name="port" value="7006"/>
</bean>
</set>
</constructor-arg>
<constructor-arg name="poolConfig" ref="jedisPoolConfig"/>
</bean>
使用集群请注释掉单机版的
最后还有点小bug,7001节点不能出现在jediscluster的构造函数中,不然访问7001节点内容会超时,原因未知。我用3.2.9重装一遍没发现任何问题,待大佬们解决吧
public interface JedisClient {
String get(String key);
String set(String key, String value);
long ttl(String key);
long expire(String key, int second);
long incr(String key);
long hset(String hkey, String key, String value);
String hget(String hkey, String key);
long del(String key);
long hdel(String hkey, String key);
}
public class JedisClientCluster implements JedisClient {
@Resource
private JedisCluster jedisCluster;
@Override
public String get(String key) {
return jedisCluster.get(key);
}
@Override
public String set(String key, String value) {
return jedisCluster.set(key, value);
}
@Override
public long ttl(String key) {
return jedisCluster.ttl(key);
}
@Override
public long expire(String key, int second) {
return jedisCluster.expire(key, second);
}
@Override
public long incr(String key) {
return jedisCluster.incr(key);
}
@Override
public long hset(String hkey, String key, String value) {
return jedisCluster.hset(hkey, key, value);
}
@Override
public String hget(String hkey, String key) {
return jedisCluster.hget(hkey, key);
}
@Override
public long del(String key) {
return jedisCluster.del(key);
}
@Override
public long hdel(String hkey, String key) {
return jedisCluster.del(hkey, key);
}
}
public class JedisClientSingle implements JedisClient {
@Resource
private JedisPool jedisPool;
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String string = jedis.get(key);
jedis.close();
return string;
}
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String string = jedis.set(key, value);
jedis.close();
return string;
}
@Override
public String hget(String hkey, String key) {
Jedis jedis = jedisPool.getResource();
String string = jedis.hget(hkey, key);
jedis.close();
return string;
}
@Override
public long hset(String hkey, String key, String value) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hset(hkey, key, value);
jedis.close();
return result;
}
@Override
public long incr(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.incr(key);
jedis.close();
return result;
}
@Override
public long expire(String key, int second) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.expire(key, second);
jedis.close();
return result;
}
@Override
public long ttl(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.ttl(key);
jedis.close();
return result;
}
@Override
public long del(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.del(key);
jedis.close();
return result;
}
@Override
public long hdel(String hkey, String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hdel(hkey, key);
jedis.close();
return result;
}
}
如果集群版和主从复制版想要共存,那么就在spring配置文件中手动注入
(七)使用jedis连接单机和集群(一步一个坑踩出来的辛酸泪)的更多相关文章
- redis在Windows下以后台服务一键搭建集群(单机--伪集群)
redis在Windows下以后台服务一键搭建集群(单机--伪集群) 一.概述 此教程介绍如何在windows系统中同一台机器上布置redis伪集群,同时要以后台服务的模式运行.布置以脚本的形式,一键 ...
- Greenplum源码编译安装(单机及集群模式)完全攻略
公司有个项目需要安装greenplum数据库,让我这个gp小白很是受伤,在网上各种搜,结果找到的都是TMD坑货帖子,但是经过4日苦战,总算是把greenplum的安装弄了个明白,单机及集群模式都部署成 ...
- jedis处理redis cluster集群的密码问题
环境介绍:jedis:2.8.0 redis版本:3.2 首先说一下redis集群的方式,一种是cluster的 一种是sentinel的,cluster的是redis 3.0之后出来新的集群方式 本 ...
- 【运维技术】Zookeeper单机以及集群搭建教程
Zookeeper单机以及集群搭建教程 单机搭建 单机安装以及启动 安装zookeeper的前提是必须有java环境 # 选择目录进行下载安装 cd /app # 下载zk,可以去官方网站下载,自己上 ...
- Redis 5.0.7 讲解,单机、集群模式搭建
Redis 5.0.7 讲解,单机.集群模式搭建 一.Redis 介绍 不管你是从事 Python.Java.Go.PHP.Ruby等等... Redis都应该是一个比较熟悉的中间件.而大部分经常写业 ...
- Zookeeper集群搭建(多节点,单机伪集群,Docker集群)
Zookeeper介绍 原理简介 ZooKeeper是一个分布式的.开源的分布式应用程序协调服务.它公开了一组简单的原语,分布式应用程序可以在此基础上实现更高级别的同步.配置维护.组和命名服务.它的设 ...
- eclipse连接远程hadoop集群开发时权限不足问题解决方案
转自:http://blog.csdn.net/shan9liang/article/details/9734693 eclipse连接远程hadoop集群开发时报错 Exception in t ...
- eclipse连接远程hadoop集群开发时0700问题解决方案
eclipse连接远程hadoop集群开发时报错 错误信息: Exception in thread "main" java.io.IOException:Failed to se ...
- 玩转nodeJS系列:使用cluster创建nodejs单机多核集群(多进程)
前言: nodejs提供了cluster集群(支持端口共享的多进程),cluster基于child_process,process二次封装,方便我们使用该功能实现单机nodejs的web集群. 1.c ...
随机推荐
- adb 无法调试的问题,ADB server didn't ACK,* failed to start daemon *
The connection to adb is down, and a severe error has occured. You must restart adb and Eclipse. Ple ...
- IDEA使用maven创建SSM及其依赖的导入
$.说明: 1.IDEA创建maven SSM web项目 2.导入依赖 一.IDEA创建maven SSM项目 对于初入IDEA的人来说此篇博客适用于不会创建maven 项目的人 首先下载IDEA ...
- 解决RegexKitLite导入报错问题
1.RegexKitLite是什么? RegexKitLite是一个非常方便的处理正则表达式的第三方类库. 本身只有一个RegexKitLite.h和RegexKitLite.m 2.导入RegexK ...
- unity googleplay随手记
googleplay设置 进入play console后可以发布应用 点击所有应用->创建应用(这部经常报错误码,多试几次就ok可能和vpn有关) 创建一个应用成功后,这个应用就会包含上面所有选 ...
- 咕咕(数位dp+AC自动机)
咕咕(数位dp+AC自动机) 若一个字符串的字符集合是0~m-1,那么称它为m进制字符串.给出n个m进制字符串\(s_i\),每个字符串的权值为\(v_i\).对于另一个m进制字符串\(S\),设\( ...
- [A/C 2007] 数据备份(网络流,堆)
[A/C 2007] 数据备份(网络流,堆) 给你N各点的位置和K条链,需要用这些链把2K个点连起来,使得链的总长最短.可以随意选择要链的点.n=100000. 这道题居然可以用堆-- 首先,不能把区 ...
- vue2.0 vs vue1.0
1.每个组件模板不支持代码片段组件中模板之前<template> <h3>as</h3></template>现在 必须要有根元素 包裹住所有代码< ...
- P4213 【模板】杜教筛(Sum)
\(\color{#0066ff}{题 目 描 述}\) 给定一个正整数\(N(N\le2^{31}-1)\) 求 \(\begin{aligned} ans_1=\sum_{i=1}^n\varph ...
- Linq中DeferredLoadingEnabled,DataLoadOption的用法
1. 基本的数据关系图 Student和Class之间是多对一关系,Student和Course之间是多对多关系. DataContext的DeferredLoadingEnabled属性指定是否需 ...
- Qt 学习之路 2(14):对话框数据传递
Home / Qt 学习之路 2 / Qt 学习之路 2(14):对话框数据传递 Qt 学习之路 2(14):对话框数据传递 豆子 2012年9月15日 Qt 学习之路 2 53条评论 对话框 ...