redis 学习笔记(7)-cluster 客户端(jedis)代码示例

上节学习了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

时间: 2024-08-20 02:24:37

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

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

上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞sharding,现在方便多了,直接上cluster功能就行了,而且还支持节点动态添加.HA.节点增减后缓存重新分布(resharding). 下面是参考官方教程cluster-tutorial 在mac机上搭建cluster的过程: 一.下载最新版redis 编译 目前最新版是3.0.7,下载地址:http:

Android学习笔记--通过Application传递数据代码示例_Android

在整个Android程序中,有时需要保存某些全局的数据(如:用户信息),方便在程序的任何地方调用.在Activity之间数据传递中有一种比较使用的方式,就是全局对象,使用过J2EE的都应该知道JavaWeb的四个作用域,其中Application域在应用程序的任何地方都可以使用和访问,除非是Web服务器停止,Android中的全局对象非常类似于JavaWeb中的Application域,除非是Android应用程序清除内存,否则全局对象将一直可以访问. 在启动Application时,系统会创建

Android学习笔记--通过Application传递数据代码示例

在整个Android程序中,有时需要保存某些全局的数据(如:用户信息),方便在程序的任何地方调用.在Activity之间数据传递中有一种比较使用的方式,就是全局对象,使用过J2EE的都应该知道JavaWeb的四个作用域,其中Application域在应用程序的任何地方都可以使用和访问,除非是Web服务器停止,Android中的全局对象非常类似于JavaWeb中的Application域,除非是Android应用程序清除内存,否则全局对象将一直可以访问. 在启动Application时,系统会创建

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

首先不得不服Spring这个宇宙无敌的开源框架,几乎整合了所有流行的其它框架,http://projects.spring.io/spring-data/从这上面看,当下流行的redis.solr.hadoop.mongoDB.couchBase... 全都收入囊中.对于redis整合而言,主要用到的是spring-data-redis 使用步骤: 一.pom添加依赖项 <dependency> <groupId>org.springframework.data</group

JavaScript学习笔记之检测客户端类型是(引擎、浏览器、平台、操作系统、移动设备)_javascript技巧

//取得用户代理字符串 并全部小写. var ua = navigator.userAgent.toLowerCase(); document.write(ua); 在上篇文章给大家介绍了基于javascript代码检测访问网页的浏览器呈现引擎.平台.Windows操作系统.移动设备和游戏系统 ,感兴趣的朋友可以点击全文了解详情. 1.识别呈现引擎 引擎主要包含四种:IE.Gecko.WebKit.Opera 2.识别浏览器 主流浏览器包含四种:IE.Chrome.Firefox.Opera 3

Redis学习笔记~StackExchange.Redis实现分布式Session

对于多WEB的环境现在已经是必须的了,很难想像一台WEB服务器面对百万并发的响应,所以,我们需要多台WEB服务器集群合作,来缓解这种高并发,高吞吐的场景,而对于多WEB的场景又会有个问题出现,即session存储的问题,如一个用户登陆后,把一个状态信息存储到当前WEB服务器的session里,而你请求其它页面时,很可能就被路由到另一台服务器了,这时,session也就丢了,而对于这种情况,有人把redis这个存储中间件想了起来,对它进行了封装,就有了今天基于redis的session共享机制.

Redis学习笔记

1 安装 $ wget http://download.redis.io/releases/redis-3.0.7.tar.gz $ tar xzf redis-3.0.7.tar.gz $ cd redis-3.0.7 $ make 网页下载地址:http://www.redis.cn/download.html 2 启动服务端 $ src/redis-server 3 启动客户端 You can interact with Redis using the built-in client: $

redis 学习笔记(2)-client端示例代码

redis提供了几乎所有主流语言的client,java中主要使用二种:Jedis与Redisson 一.Jedis的使用 1 <dependency> 2 <groupId>redis.clients</groupId> 3 <artifactId>jedis</artifactId> 4 <version>2.6.0</version> 5 <type>jar</type> 6 <scop

redis 学习笔记(3)-master/slave(主/从模式)

类似mysql的master-slave模式一样,redis的master-slave可以提升系统的可用性,master节点写入cache后,会自动同步到slave上. 环境: master node: 10.6.144.155:7030 slave node: 10.6.144.156:7031   一.配置 仅需要在slave node上修改配置: 找到slaveof这行,参考下面的修改(填上master node的Ip和端口就完事了) slaveof 10.6.144.155 7030 另