All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lingdonge.redis.service.RedisClusterUtil Maven / Gradle / Ivy

package com.lingdonge.redis.service;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.*;
import redis.clients.jedis.util.JedisClusterCRC16;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class RedisClusterUtil {

    private static JedisCluster jedisCluster;

    public RedisClusterUtil() {
    }

    public RedisClusterUtil(JedisCluster jedisCluster) {
        RedisClusterUtil.jedisCluster = jedisCluster;

        this.afterPropertySet();//注入和生成实例
        log.info("正在加载Redis配置文件:" + jedisCluster);
    }

    private static volatile RedisPoolUtil instance;

    /**
     * 单例模式,线程安全
     *
     * @return
     * @throws Exception
     */
    public static RedisPoolUtil getInstance() {
        // 对象实例化时与否判断(不使用同步代码块,instance不等于null时,直接返回对象,提高运行效率)
        if (instance == null) {
            //同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建)
            synchronized (RedisPoolUtil.class) {
                //未初始化,则初始instance变量
                if (instance == null) {
                    instance = new RedisPoolUtil();
                    instance.afterPropertySet();//初始化配置和Pool池
                }
            }
        }
        return instance;
    }

    /**
     * 实例化完成之后执行
     */
    public void afterPropertySet() {
    }

    public List getScan(Jedis redisService, String key) {
        List list = new ArrayList<>();
        ScanParams params = new ScanParams();
        params.match(key);
        params.count(100);
        String cursor = "0";
        while (true) {
            ScanResult scanResult = redisService.scan(cursor, params);
            List elements = scanResult.getResult();
            if (elements != null && elements.size() > 0) {
                list.addAll(elements);
            }
            cursor = scanResult.getCursor();
            if ("0".equals(cursor)) {
                break;
            }
        }
        return list;
    }

    public List getRedisKeys(JedisCluster jedisCluster, String matchKey) {
        List list = new ArrayList<>();
        try {
            Map clusterNodes = jedisCluster.getClusterNodes();
            for (Map.Entry entry : clusterNodes.entrySet()) {
                Jedis jedis = entry.getValue().getResource();
                // 判断非从节点(因为若主从复制,从节点会跟随主节点的变化而变化)
                if (!jedis.info("replication").contains("role:slave")) {
                    List keys = getScan(jedis, matchKey);
                    if (keys.size() > 0) {
                        Map> map = new HashMap<>();
                        for (String key : keys) {
                            // cluster模式执行多key操作的时候,这些key必须在同一个slot上,不然会报:JedisDataException:
                            // CROSSSLOT Keys in request don't hash to the same slot
                            int slot = JedisClusterCRC16.getSlot(key);
                            // 按slot将key分组,相同slot的key一起提交
                            if (map.containsKey(slot)) {
                                map.get(slot).add(key);
                            } else {
                                map.put(slot, Lists.newArrayList(key));
                            }
                        }
                        for (Map.Entry> integerListEntry : map.entrySet()) {
                            // System.out.println("integerListEntry="+integerListEntry);
                            list.addAll(integerListEntry.getValue());
                        }
                    }
                }
            }
        } finally {
            return list;
        }
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy