程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> redis 學習筆記(7)-cluster 客戶端(jedis)代碼示例,redisjedis

redis 學習筆記(7)-cluster 客戶端(jedis)代碼示例,redisjedis

編輯:JAVA綜合教程

redis 學習筆記(7)-cluster 客戶端(jedis)代碼示例,redisjedis


上節學習了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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved