上节学习了cluster的搭建及redis-cli终端下如何操作,但是更常用的场景是在程序代码里对cluster读写,这需要redis-client对cluster模式的支持,目前spring-data-redis(1.6.4)还不支持cluster,最新的1.7.0 RC1已经有cluster的相关实现了,不过目前尚未正式发布,所以现阶段要使用redis-cluster的话,client最好还是选用原生的jedis,示例代码如下:

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg index="0">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="7000"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="7001"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="7002"/>
</bean>
<!--<bean class="redis.clients.jedis.HostAndPort">-->
<!--<constructor-arg name="host" value="127.0.0.1"/>-->
<!--<constructor-arg name="port" value="7003"/>-->
<!--</bean>-->
<!--<bean class="redis.clients.jedis.HostAndPort">-->
<!--<constructor-arg name="host" value="127.0.0.1"/>-->
<!--<constructor-arg name="port" value="7004"/>-->
<!--</bean>-->
<!--<bean class="redis.clients.jedis.HostAndPort">-->
<!--<constructor-arg name="host" value="127.0.0.1"/>-->
<!--<constructor-arg name="port" value="7005"/>-->
<!--</bean>-->
</set>
</constructor-arg>
</bean>
</beans>

注:上面的这些节点,不需要配全,最少可以只保留一个cluster中的节点信息,运行时,jedis会自动发现其它节点,但是为了防止某个节点挂掉,所以建议配置时,还是多配置几个,保证这一堆节点中,至少有一个能连接上。

示例代码:

package com.cnblogs.yjmyzz.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool; import java.util.List;
import java.util.Map;
import java.util.Set; public class AppDemo { private static Logger logger = LoggerFactory.getLogger(AppDemo.class);
private static JedisCluster jc = null; private static final String KEYS_STRING = "STRING";
private static final String KEYS_SET = "SET";
private static final String KEYS_LIST = "LIST";
private static final String KEYS_HASH = "HASH";
private static final String KEYS_ZSET = "ZSET"; private static void addKey(final String conainter, final String key) {
if (!jc.exists(conainter)) {
jc.sadd(conainter, key);
} else {
if (!jc.smembers(conainter).contains(key)) {
jc.sadd(conainter, key);
}
}
} /**
* 写入字符串缓存
*
* @param key
* @param value
* @return
*/
private static String set(final String key, final String value) {
String result = jc.set(key, value);
addKey(KEYS_STRING, key);
return result;
} /**
* 写入Set缓存
*
* @param key
* @param member
* @return
*/
private static Long sadd(final String key, final String... member) {
Long result = jc.sadd(key, member);
addKey(KEYS_SET, key);
return result;
} /**
* 从左侧写入List
*
* @param key
* @param string
* @return
*/
private static Long lpush(final String key, final String... string) {
Long result = jc.lpush(key, string);
addKey(KEYS_LIST, key);
return result;
} /**
* 写入HashMap缓存
*
* @param key
* @param field
* @param value
* @return
*/
private static Long hset(final String key, final String field, final String value) {
Long result = jc.hset(key, field, value);
addKey(KEYS_HASH, key);
return result;
} /**
* 写入ZSet缓存
*
* @param key
* @param score
* @param member
* @return
*/
private static Long zadd(final String key, final double score, final String member) {
Long result = jc.zadd(key, score, member);
addKey(KEYS_ZSET, key);
return result;
} private static Long zadd(final String key, final String member) {
Long result = jc.zadd(key, 0d, member);
addKey(KEYS_ZSET, key);
return result;
} public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-redis.xml"); jc = ctx.getBean(JedisCluster.class); Map<String, JedisPool> nodes = jc.getClusterNodes();
for (Map.Entry<String, JedisPool> entry : nodes.entrySet()) {
logger.info(entry.getKey() + " => " + entry.getValue().toString());
//清空所有数据
try {
entry.getValue().getResource().flushDB();
} catch (Exception e) {
logger.info(e.getLocalizedMessage());//slave节点上执行flushDB会报错
}
//entry.getValue().getResource().keys("*");//慎用,缓存数量较大时,会引起性能问题.
} //检测key是否存在
logger.info(jc.exists("a").toString()); //字符串写入测试
logger.info(set("a", "hello world!"));
logger.info(set("b", "hello redis!")); //字符串读取测试
logger.info(jc.get("a")); //set写入操作
logger.info("set写入测试 ==>");
logger.info(sadd("set1", "a", "b", "c") + ""); //缓存类型测试
logger.info(jc.type("set1")); //set读取测试
logger.info("set读取测试 ==>");
Set<String> set1 = jc.smembers("set1");
for (String s : set1) {
logger.info(s);
} //list写入测试
logger.info("list写入测试 ==>");
logger.info(lpush("list1", "1", "2", "3") + ""); //list读取测试
logger.info("list读取测试 ==>");
List<String> list1 = jc.lrange("list1", 0, 999);
for (String s : list1) {
logger.info(s);
} //hash写入测试
logger.info("hash写入测试 ==>");
logger.info(hset("hash1", "jimmy", "杨俊明") + "");
logger.info(hset("hash1", "CN", "中国") + "");
logger.info(hset("hash1", "US", "美国") + ""); //hash读取测试
logger.info("hash读取测试 ==>");
Map<String, String> hash1 = jc.hgetAll("hash1");
for (Map.Entry<String, String> entry : hash1.entrySet()) {
logger.info(entry.getKey() + ":" + entry.getValue());
} //zset写入测试
logger.info("zset写入测试 ==>");
logger.info(zadd("zset1", "3") + "");
logger.info(zadd("zset1", "2") + "");
logger.info(zadd("zset1", "1") + "");
logger.info(zadd("zset1", "4") + "");
logger.info(zadd("zset1", "5") + "");
logger.info(zadd("zset1", "6") + ""); //zset读取测试
logger.info("zset读取测试 ==>");
Set<String> zset1 = jc.zrange("zset1", 0, 999);
for (String s : zset1) {
logger.info(s);
} //遍历所有缓存项的key
logger.info("遍历cluster中的所有key ==>");
logger.info(jc.smembers(KEYS_STRING).toString());
logger.info(jc.smembers(KEYS_HASH).toString());
logger.info(jc.smembers(KEYS_SET).toString());
logger.info(jc.smembers(KEYS_LIST).toString());
logger.info(jc.smembers(KEYS_ZSET).toString()); }
}

注:建议尽量避免用jedis对节点做keys的模糊搜索,该操作在缓存项较多时,可能会导致redis性能急剧下降,改进办法是自己弄一个集合,记录所有缓存的key,具体可参考上面的办法。此外,jedis提供的命令非常之多,但是没有详细的说明文档(估计,作者认为代码就是最好的文档),大体可以从方法前缀猜测出来,比如sXXX表示是对Set的操作,hXXX表示是对hash的操作,lXXX或rXXX是对list的操作,zXXX是对zset的操作,什么前缀都没有的,比如set/get是对字符串的操作。

有网友把jedis的操作整理了一份文档,请参见:http://blog.csdn.net/zhu_xun/article/details/16806285

最后,附加上文中示例的源码:https://github.com/yjmyzz/redis-cluster-demo

redis 学习笔记(7)-cluster 客户端(jedis)代码示例的更多相关文章

  1. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  2. redis学习笔记(二)——java中jedis的简单使用

    redis怎么在java中使用,那就是要用到jedis了,jedis是redis的java版本的客户端实现,原本原本想上来就直接学spring整合redis的,但是一口吃个胖子,还是脚踏实地,从基础开 ...

  3. redis 学习笔记(5)-Spring与Jedis的集成

    首先不得不服Spring这个宇宙无敌的开源框架,几乎整合了所有流行的其它框架,http://projects.spring.io/spring-data/从这上面看,当下流行的redis.solr.h ...

  4. Redis学习笔记(4)—— Jedis入门

    一.Jedis介绍 Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如Java.C.C#.C++.php.Node.js.Go等. 在官方网站里列的一些Java客户端,有jedi ...

  5. redis 学习笔记-cluster集群搭建

    一.下载最新版redis 编译 目前最新版是3.0.7,下载地址:http://www.redis.io/download 编译很简单,一个make命令即可,不清楚的同学,可参考我之前的笔记: red ...

  6. Redis学习笔记7--Redis管道(pipeline)

    redis是一个cs模式的tcp server,使用和http类似的请求响应协议.一个client可以通过一个socket连接发起多个请求命令.每个请求命令发出后client通常会阻塞并等待redis ...

  7. (转)redis 学习笔记(1)-编译、启动、停止

    redis 学习笔记(1)-编译.启动.停止   一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...

  8. Redis 学习笔记4: Redis 3.2.1 集群搭建

    在CenOS 6.7 linux环境下搭建Redis 集群环境 1.下载最新的Redis版本 本人下载的Redis版本是3.2.1版本,下载之后,解压,编译(make): 具体操作可以参考我的博文:R ...

  9. Redis学习笔记八:集群模式

    作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...

随机推荐

  1. 《HelloGitHub月刊》第06期

    前言 <HelloGitHub>月刊做到第06期了(已经做了6个月了),在GitHub上获得了100+的stars,虽然不多,但是我很知足了,说明有人觉得这个项目是有价值的.同时园子中的' ...

  2. 深入学习jQuery描述文本内容的3个方法

    × 目录 [1]html() [2]text() [3]val()[4]总结 前面的话 在javascript中,描述元素内容有5个属性,分别是innerHTML.outerHTML.innerTex ...

  3. 谈谈React那些小事

    前言 说起React,那也是近一年多时间火起来的前端框架,其在Facebook的影响力和大力推广下,已然成为目前前端界的中流砥柱.在如今的前端框架界,React.Vue.Angular三分天下的时代已 ...

  4. 利用KD树进行异常检测

    软件安全课程的一次实验,整理之后发出来共享. 什么是KD树 要说KD树,我们得先说一下什么是KNN算法. KNN是k-NearestNeighbor的简称,原理很简单:当你有一堆已经标注好的数据时,你 ...

  5. C#多态“说来也说”——逻辑层BLL中的多态使用

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/p/5861842.html 昨天晚上,有个朋友说学了好久,依然没搞 ...

  6. HTML5新增及移除的元素

    HTML经过10多年的发展,其元素经历了废弃与不断重新定义的过程.为了更好的处理现在的互联网应用,HTML5新增了图形绘制.多媒体播放.页面结构.应用程序存储.网络工作等新元素.http://hove ...

  7. Linux下history命令用法

    如果你经常使用 Linux 命令行,那么使用 history(历史)命令可以有效地提升你的效率.本文将通过实例的方式向你介绍 history 命令的 15 个用法. 使用 HISTTIMEFORMAT ...

  8. 每天一个设计模式-2 外观模式(Facade)

    每天一个设计模式-2  外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...

  9. struts2中从后台读取数据到<s:select>

    看到网上好多有struts2中从后台读取数据到<s:select>的,但都 不太详细,可能是我自己理解不了吧!所以我自己做了 一个,其中可能 有很多不好的地方,望广大网友指出 结果如图 p ...

  10. Shiro安全框架入门篇(登录验证实例详解与源码)

    转载自http://blog.csdn.net/u013142781 一.Shiro框架简单介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和J ...