当前位置: 代码迷 >> Java相关 >> redis 学习笔记(七)-cluster 客户端(jedis)代码示例
  详细解决方案

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

热度:821   发布时间:2016-04-22 19:12:18.0
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