(七)使用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 ...
随机推荐
- Ubuntu - 安装hadoop(简约版)
相关版本: VMware ubuntuKylin16.04 JDK :openjdk Hadoop-2.9.1 步骤: 1.SSH 配置 [ 远程登陆 ] [ 配置SSH免码登陆 ] *测试:ssh ...
- Linux 编写安全巡检脚本
Linux 编写安全巡检脚本 检测/etc/passwd,/etc/shadow文件是否锁定 检测/etc/login.defs配置文件中密码有效期设置是否得当 检查所有用户账户(非系统账户)中是否存 ...
- POJ - 3468A Simple Problem with Integers (线段树区间更新,区间查询和)
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of op ...
- 【转】32位plsql连接64位oracle
源地址:http://www.cnblogs.com/ymj126/p/3712727.html
- P1505 [国家集训队]旅游
\(\color{#0066ff}{题 目 描 述}\) Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了 ...
- 10.6-10.7 牛客网NOIP模拟赛题解
留个坑... upd:估计这个坑补不了了 如果还补不了就删了吧
- Qt 学习之路 2(25):画刷和画笔
Home / Qt 学习之路 2 / Qt 学习之路 2(25):画刷和画笔 Qt 学习之路 2(25):画刷和画笔 豆子 2012年11月5日 Qt 学习之路 2 17条评论 前面一章我们提 ...
- vue.js 基础
vuejs 遍历 数组, vue js 文章 http://www.cnblogs.com/libin-1/p/6851775.html https://zhuanlan.zhihu.com/p/ ...
- P4824 [USACO15FEB]Censoring (Silver) 审查(银)
传送门 一个串的匹配肯定考虑KMP 那就暴力KMP 记录一下到每个字符时匹配的位置 找到一个符合的串就标记然后暴力回跳 感觉好像太暴力了... #include<iostream> #in ...
- poj3713 Transferring Sylla 枚举+tarjan判割点
其实就是判断是否为三连通图 三连通图指的是去掉3个点就不连通的图,但是并没有直接求三连通的算法.著名的Tarjan算法可以求解连通和割点,再枚举删除一个点就能达到三连通的目的. 先看用例2,是由用例1 ...