RedisCluster工具类

背景

在将redis切换到redis cluster中,也遇到一些问题,借此机会和大家分享一下。

1.spring-data-redis与ibatis冲突

    使用spring-data-redis操作redis cluster的话,必须将spring版本升级至4.x以上。

    如果老项目中使用了ibatis的话,只能用spring3.x ,无法兼容redis cluster。有两个方法解决:

        1)使用mybatis替换ibatis,升级spring至4.x版本

        2)使用JedisCluster

封装RedisCluster

2.基于JedisCluster进行简单封装

    因为看到JedisCluster的配置比较复杂,因此对其进行简单的封装,代码如下:

package com.utils;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Administrator on 2017/9/26.
 */
public class RedisClusterManager {
    private int threadSize=10;
    private int maxTotal=500;
    private int maxIdle=100;
    private int maxWaitMillis=3000;
    private int timeout=1000;
    private String redisNodes;
    ExecutorService executorService;
    JedisCluster jedisCluster;

    public void asyncSet(String key,String value){
        executorService.execute(new RunOnce(Type.SET,key,value,jedisCluster));
    }
    public void asyncSetExpire(String key,String value,int expire){
        executorService.execute(new RunOnce(Type.SET,key,value,expire,jedisCluster));
    }
    public void asyncDel(String key){
        executorService.execute(new RunOnce(Type.DEL,key,jedisCluster));
    }
    public void asyncHmset(String key,Map<String,String> hmset){
        executorService.execute(new RunOnce(Type.HMSET,key,hmset,jedisCluster));
    }
    public void asyncHmsetExpire(String key,Map<String,String> hmset,int expire){
        executorService.execute(new RunOnce(Type.HMSET,key,hmset,expire,jedisCluster));
    }
    public String get(String key){
        return jedisCluster.get(key);
    }
    public Map<String,String> hgetAll(String key){
        return jedisCluster.hgetAll(key);
    }
    public Boolean exists(String key){
        return jedisCluster.exists(key);
    }
    public void set(String key,String value){
        jedisCluster.set(key,value);
    }
    public void setExpire(String key,String value,int expire){
        jedisCluster.set(key,value);
        jedisCluster.expire(key,expire);
    }
    public Long del(String key){
        return jedisCluster.del(key);
    }
    public void hmset(String key,Map<String,String> hmset){
        jedisCluster.hmset(key,hmset);
    }
    public void hmsetExpire(String key,Map<String,String> hmset,int expire){
        jedisCluster.hmset(key,hmset);
        jedisCluster.expire(key,expire);
    }
    public List<String> hmget(String key,String[] propertys){
        return jedisCluster.hmget(key,propertys);
    }



    public void init(){
        if(null == redisNodes||"".equals(redisNodes.trim())) throw new RuntimeException("shardNodes is empty");
        String[] addresses = redisNodes.split(",");
        if(null == addresses||addresses.length==0) throw new RuntimeException("ip or port is empty");
        Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
        for(String address: addresses){
            String[] addr = address.split(":");
            jedisClusterNodes.add(new HostAndPort(addr[0],Integer.valueOf(addr[1])));
        }
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(maxTotal);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMaxWaitMillis(maxWaitMillis);
        jedisCluster = new JedisCluster(jedisClusterNodes,timeout,poolConfig);
        executorService = Executors.newFixedThreadPool(threadSize);
    }
    public void destory(){
        executorService.shutdownNow();
        try {
            jedisCluster.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    class RunOnce implements Runnable{
        Type type;
        String key;
        String value;
        Map<String,String> hmset;
        int expire=-1;
        JedisCluster jedisCluster;

        public RunOnce(Type type, String key, JedisCluster jedisCluster) {
            this.type = type;
            this.key = key;
            this.jedisCluster = jedisCluster;
        }

        public RunOnce(Type type, String key, String value, int expire, JedisCluster jedisCluster) {
            this.type = type;
            this.key = key;
            this.value = value;
            this.expire = expire;
            this.jedisCluster = jedisCluster;
        }

        public RunOnce(Type type, String key, Map<String, String> hmset, JedisCluster jedisCluster) {
            this.type = type;
            this.key = key;
            this.hmset = hmset;
            this.jedisCluster = jedisCluster;
        }

        public RunOnce(Type type, String key, String value, JedisCluster jedisCluster) {
            this.type = type;
            this.key = key;
            this.value = value;
            this.jedisCluster = jedisCluster;
        }

        public RunOnce(Type type, String key, Map<String, String> hmset, int expire, JedisCluster jedisCluster) {
            this.type = type;
            this.key = key;
            this.hmset = hmset;
            this.expire = expire;
            this.jedisCluster = jedisCluster;
        }

        @Override
        public void run() {
            if(Type.SET.equals(type)){
                jedisCluster.set(key,value);
                if(expire!=-1) jedisCluster.expire(key,expire);
            }else if(Type.DEL.equals(type)){
                jedisCluster.del(key);
            }else if(Type.HMSET.equals(type)){
                jedisCluster.hmset(key,hmset);
                if(expire!=-1) jedisCluster.expire(key,expire);
            }
        }
    }
    enum Type {
        SET,DEL,HMSET;
    }

    public void setThreadSize(int threadSize) {
        this.threadSize = threadSize;
    }

    public void setRedisNodes(String redisNodes) {
        this.redisNodes = redisNodes;
    }

    public void setMaxTotal(int maxTotal) {
        this.maxTotal = maxTotal;
    }

    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    public void setMaxWaitMillis(int maxWaitMillis) {
        this.maxWaitMillis = maxWaitMillis;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
}

    1)实现功能

        封装了set,expire,del,hmset,get,hgetAll,exists,hmget方法,并提供异步支持

    2)spring配置        

<bean id="redisClusterManager" class="com.utils.RedisClusterManager" init-method="init" destroy-method="destory">

    <property name="redisNodes" value="redis-cluster0.service.baihe:6379,redis-cluster1.service.baihe:6379,........" />
    <property name="threadSize" value="50" />         <!-- 可省略,默认是10 -->
    <property name="maxTotal" value="500"/> <!-- 可省略,默认是500 -->
    <property name="maxIdle" value="100"/> <!-- 可省略,默认是100 -->
    <property name="maxWaitMillis" value="3000"/> <!-- 可省略,默认是3000 -->
    <property name="timeout" value="1000" /> <!-- 可省略,默认是1000 -->
</bean>

    3)代码使用

        

import com.utils.RedisClusterManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;

/**
 * Created by Administrator on 2017/9/26.
 */
public class RedisClusterManagerJunit {
    RedisClusterManager manager;
    @Before
    public void init(){
        manager = new RedisClusterManager();
        manager.setRedisNodes("" +
                "redis-cluster0.service.baihe:6379," +
                "redis-cluster1.service.baihe:6379," +
                "redis-cluster2.service.baihe:6379," +
                "redis-cluster3.service.baihe:6379," +
                "redis-cluster4.service.baihe:6379," +
                "redis-cluster5.service.baihe:6379," +
                "redis-cluster6.service.baihe:6379," +
                "redis-cluster7.service.baihe:6379," +
                "redis-cluster8.service.baihe:6379," +
                "redis-cluster9.service.baihe:6379");
        manager.init();
    }
    @After
    public void destory(){
        manager.destory();
    }

    @Test
    public void set() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(100000);
        for(int i=0;i<100000;i++){
            manager.set("test"+i,"1");
            latch.countDown();
        }
        latch.await();
    }
    @Test
    public void get() throws InterruptedException {
        for(int i=0;i<100000;i++){
            System.out.println(manager.get("test"+i));
        }
    }
    @Test
    public void exists(){
        for(int i=0;i<100000;i++){
            System.out.println(manager.exists("test"+i));
        }
    }
    @Test
    public void del(){
        for(int i=0;i<100000;i++){
            manager.del("test"+i);
            System.out.println("test"+i);
        }
    }
}

 

转载于:https://my.oschina.net/cnarthurs/blog/1573199

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
redis-cluster-tool 是一个非常便利的 Redis 集群管理工具。help        Usage: redis-cluster-tool [-?hVds] [-v verbosity level] [-o output file]                  [-c conf file] [-a addr] [-i interval]                  [-p pid file] [-C command] [-r redis role]                  [-t thread number] [-b buffer size]    Options:      -h, --help             : this help      -V, --version          : show version and exit      -d, --daemonize        : run as a daemon      -s, --simple           : show the output not in detail      -v, --verbosity=N      : set logging level (default: 5, min: 0, max: 11)      -o, --output=S         : set logging file (default: stderr)      -c, --conf-file=S      : set configuration file (default: conf/rct.yml)      -a, --addr=S           : set redis cluster address (default: 127.0.0.1:6379)      -i, --interval=N       : set interval in msec (default: 1000 msec)      -p, --pid-file=S       : set pid file (default: off)      -C, --command=S        : set command to execute (default: cluster_state)      -r, --role=S           : set the role of the nodes that command to execute on (default: all, you can input: all, master or slave)      -t, --thread=N         : set how many threads to run the job(default: 8)      -b, --buffer=S         : set buffer size to run the job (default: 1048576 byte, unit:G/M/K)        Commands:        cluster_state                 :Show the cluster state.        cluster_used_memory           :Show the cluster used memory.        cluster_keys_num              :Show the cluster holds keys num.        slots_state                   :Show the slots state.        node_slot_num                 :Show the node hold slots number.        new_nodes_name                :Show the new nodes name that not covered slots.        cluster_rebalance             :Show the cluster how to rebalance.        flushall                      :Flush all the cluster.        cluster_config_get            :Get config from every node in the cluster and check consistency.        cluster_config_set            :Set config to every node in the cluster.        cluster_config_rewrite        :Rewrite every node config to echo node for the cluster.        node_list                     :List the nodes            del_keys                      :Delete keys in the cluster. The keys must match a given glob-style pattern.(This command not block the redis)ExampleGet the cluster state:        $redis-cluster-tool -a 127.0.0.1:34501 -C cluster_state -r master    master[127.0.0.1:34504] cluster_state is ok     master[127.0.0.1:34501] cluster_state is ok     master[127.0.0.1:34502] cluster_state is ok     master[127.0.0.1:34503] cluster_state is ok     all nodes cluster_state is ok    Get the cluster used memory:    $redis-cluster-tool -a 127.0.0.1:34501 -C cluster_used_memory -r master    master[127.0.0.1:34504] used 195 M 25%    master[127.0.0.1:34501] used 195 M 25%    master[127.0.0.1:34502] used 195 M 25%    master[127.0.0.1:34503] used 195 M 25%    cluster used 780 MRebalance the cluster slots:    $redis-cluster-tool -a 127.0.0.1:34501 -C cluster_rebalance    --from e1a4ba9922555bfc961f987213e3d4e6659c9316 --to 785862477453bc6b91765ffba0b5bc803052d70a --slots 2048    --from 437c719f50dc9d0745032f3b280ce7ecc40792ac --to cb8299390ce53cefb2352db34976dd768708bf64 --slots 2048    --from a497fc619d4f6c93bd4afb85f3f8a148a3f35adb --to a0cf6c1f12d295cd80f5811afab713cdc858ea30 --slots 2048    --from 0bdef694d08cb3daab9aac518d3ad6f8035ec896 --to 471eaf98ff43ba9a0aadd9579f5af1609239c5b7 --slots 2048Then you can use "redis-trib.rb reshard --yes --from e1a4ba9922555bfc961f987213e3d4e6659c9316 --to 785862477453bc6b91765ffba0b5bc803052d70a --slots 2048 127.0.0.1:34501" to rebalance the cluster slots     Flushall the cluster:    $redis-cluster-tool -a 127.0.0.1:34501 -C flushall -s    Do you really want to execute the "flushall"?    please input "yes" or "no" :        yes    OKGet a config from every node in cluster:    $redis-cluster-tool -a 127.0.0.1:34501 -C "cluster_config_get maxmemory" -r master    master[127.0.0.1:34501] config maxmemory is 1048576000 (1000MB)    master[127.0.0.1:34502] config maxmemory is 1048576000 (1000MB)    master[127.0.0.1:34503] config maxmemory is 1048576000 (1000MB)    master[127.0.0.1:34504] config maxmemory is 1048576000 (1000MB)    All nodes config are Consistent    cluster total maxmemory: 4194304000 (4000MB)Set a config from every node in cluster:    $redis-cluster-tool -a 127.0.0.1:34501 -C "cluster_config_set maxmemory 10000000" -s    Do you really want to execute the "cluster_config_set"?    please input "yes" or "no" :    yes        OKDelete keys in the cluster:    $redis-cluster-tool -a 127.0.0.1:34501 -C "del_keys abc*"    Do you really want to execute the "del_keys"?    please input "yes" or "no" :    yes    delete keys job is running...    delete keys job finished, deleted: 999999 keys, used: 4 s 标签:redis
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值