Java实现对Redis集群的性能测试

2023-05-16

package com.wlzx;

import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

import redis.clients.jedis.BinaryJedisCluster;
import redis.clients.jedis.Client;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisClusterConnectionHandler;
import redis.clients.jedis.JedisClusterInfoCache;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSlotBasedConnectionHandler;
import redis.clients.jedis.PipelineBase;
import redis.clients.jedis.exceptions.JedisMovedDataException;
import redis.clients.jedis.exceptions.JedisRedirectionException;
import redis.clients.util.JedisClusterCRC16;
import redis.clients.util.SafeEncoder;

public class RedisClusterUtil extends PipelineBase implements Closeable {
    private JedisSlotBasedConnectionHandler connectionHandler;
    private JedisClusterInfoCache clusterInfoCache;
    private Queue<Client> clients = new LinkedList();
    private Map<JedisPool, Jedis> jedisMap = new HashMap<>();
    private boolean hasDataInBuf = false;


    private void initJedisCluster(JedisCluster jedisCluster) {
        try {
            Field conn = BinaryJedisCluster.class.getDeclaredField("connectionHandler");
            conn.setAccessible(true);
            connectionHandler = (JedisSlotBasedConnectionHandler) conn.get(jedisCluster);
            Field clusterInfo = JedisClusterConnectionHandler.class.getDeclaredField("cache");
            clusterInfo.setAccessible(true);
            clusterInfoCache = (JedisClusterInfoCache) clusterInfo.get(connectionHandler);
        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
            e.printStackTrace();
        }

    }


    public static RedisClusterUtil pipelined(JedisCluster jedisCluster) {
        RedisClusterUtil rcu = new RedisClusterUtil();
        rcu.initJedisCluster(jedisCluster);
        return rcu;
    }

    public RedisClusterUtil() {
    }

    private void refreshCluster() {
        connectionHandler.renewSlotCache();
    }

    private void flushCachedData(Jedis jedis) {
        try {
            jedis.getClient().getAll();
        } catch (RuntimeException ex) {
        }
    }

    public void sync() {
        try {
            for (Client client : clients) {
                generateResponse(client.getOne()).get();
            }
        } catch (JedisRedirectionException jre) {
            if (jre instanceof JedisMovedDataException) {
                refreshCluster();
            }
            throw jre;
        } finally {
            for (Jedis jedis : jedisMap.values()) {
                flushCachedData(jedis);
            }
            hasDataInBuf = false;
            try {
                close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void close() throws IOException {
        clean();
        clients.clear();
        for (Jedis jedis : jedisMap.values()) {
            if (hasDataInBuf) {
                flushCachedData(jedis);
            }
            jedis.close();
        }

        jedisMap.clear();

        hasDataInBuf = false;

    }

    @Override
    protected Client getClient(String key) {
        byte[] bKey = SafeEncoder.encode(key);
        return getClient(bKey);
    }

    @Override
    protected Client getClient(byte[] key) {
        Jedis jedis = getJedis(JedisClusterCRC16.getSlot(key));
        Client client = jedis.getClient();
        clients.add(client);

        return client;
    }

    private Jedis getJedis(int slot) {
        JedisPool pool = clusterInfoCache.getSlotPool(slot);
        Jedis jedis = jedisMap.get(pool);
        if (null == jedis) {
            jedis = pool.getResource();
            jedisMap.put(pool, jedis);
        }
        hasDataInBuf = true;
        return jedis;
    }

    // 集群所有节点
    public static Set<HostAndPort> getRedisClusterNodes() {
        Set<HostAndPort> jedisClusterNodes = new HashSet<>();
        // 集群节点自己写啦~

        return jedisClusterNodes;
    }

    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        int i = scanner.nextInt();
        long start = System.currentTimeMillis();
        JedisCluster cluster = new JedisCluster(getRedisClusterNodes(), 5000, 3000, 3, "1qazXSW@", new JedisPoolConfig());
        RedisClusterUtil rc = RedisClusterUtil.pipelined(cluster);
        rc.initJedisCluster(cluster);
        rc.refreshCluster();
        rc.close();
        Path path = Paths.get("data-1000.txt");
        List<String> list = Files.readAllLines(path, Charset.forName("utf-8"));
        int count = 1;
        try {
            for (String str : list) {
                rc.setex("chenne_" + count, 300, str);
                if (count % i == 0) {
                    rc.sync();
                }
                count++;
            }
            rc.sync();
        } finally {
            rc.close();
        }

        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

目前测试结果是读取1000w行数据然后按照上面写入只需要30s

 

当然,这也跟集群服务器的性能有关。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现对Redis集群的性能测试 的相关文章

  • .net 6 基于AspNetCoreRateLimit的限流

    1 安装包 AspNetCoreRateLimit 2 在appsetting cs中加入IpRateLimiting配置节点 span class token comment 限流配置 span span class token stri
  • 关于汉字转拼音并排序解决方案

    使用方法 xff1a 写一个静态帮助类 span class token keyword public span span class token keyword static span span class token keyword c
  • .NET Core6 中使用AutoMapper

    1 引入AutoMapper包 2 新建一个类 xff1a MappingProfile xff0c 类名自定义 xff0c 但是必须要继承 Profile类 用于创建映射规则 如图 xff1a Student为源数据 xff08 我这里是
  • 使用Python调用百度OCR

    使用Python调用百度OCR 注册 登录百度智能云创建应用安装python SDK接口说明代码实现 xff08 本地图片 xff09 代码实现 xff08 使用url上的图片并使用可选参数 xff09 注册 登录百度智能云 注册请点击 登
  • 001 超全C语言程序设计概念

    前言 此笔记主要参考自赵海英老师的C语言课程 xff0c 此笔记是在考研重新学习C语言的情况下进行的整理 xff0c 主要用于后续的C语言概念温故知新 第一章 基础知识 1 数制及转换 四种数制 xff1a 二进制 十进制 八进制 十六进制
  • 使用@Autowired注解警告Field injection is not recommended

    问题 xff1a 在使用变量方式依赖注入时 xff0c 提示Field injection is not recommended 64 Autowired LogService logService 虽然变量方式注入非常简洁 xff0c 但
  • mybatis动态数据源,分页插件失效

    mybatis动态数据源 xff0c 分页插件失效 发表于 xff1a 2020 08 18 20 42 47 阅读量 xff1a 9 作者 xff1a 黄叶 原因 xff1a 使用动态数据源 xff1a 数据正常但是total为0 解决
  • mybatis动态数据源配置使用事务不生效

    原因 xff1a 因为我使用的是配置的方式来加载数据源 xff0c 因此我们还需要对事务管理器进行一个配置 解决 xff1a 在代码中添加 配置事物 64 param dataSource 64 return 64 Bean public
  • Caffeine cache实现本地缓存(简单又清楚)

    Caffeine cache实现本地缓存题 缓存填充策略 手动加载 介绍 xff1a 使用方式 xff1a 同步加载 介绍 xff1a 使用方式 xff1a 异步加载 介绍 xff1a 注意 xff1a 异步和同步使用方式相似 这里的话主要
  • 商城后台系统 — 新手练习 —毕业设计

    商城后台系统 新手练习 毕业设计 业务功能介绍项目地址 xff1a 一 商品管理1 商品列表 描述 效果 2 添加商品 描述 效果 3 商品分类 描述 效果 4 商品类型 描述 效果 二 订单管理1 订单列表 描述 效果 2 订单设置 描述
  • CASE WHEN函数@sql学习

    mysql中可以使用CASE WHEN函数完成数据分组 CASE WHEN函数用来对数据进行判断和分组 来自MySQL触发器里的流程控制语句 知识 CASE WHEN是SQL编程中常用的条件控制语句 CASE WHEN的功能 xff1a 新
  • @Autowired注入为null — 4种常见情况

    64 Autowired注入为null 情况一 使用过滤器 原因解决 情况二 没有添加注解 原因解决 情况三 xff08 没有被扫描到 xff09 原因解决 情况四 xff08 手动new xff09 原因解决 情况一 使用过滤器 原因 因
  • TDD项目实战-命令行参数解析

    认识1 基本规则2 三步骤3 任务分解法总结 项目1命令行参数解析01 任务分解法与整体工作流程1 API 构思与组件划分2 功能分解与任务列表3 红绿灯循环 02 识别坏味道与代码重构1 引入多态接口2 使用 抽象工厂 模式的变体来替换分
  • mapper扫描问题(Invalid bound statement (not found))

    分析 xff1a 通常来说这种情况是mybatis没有配置好 但是还有一种可能是你的mapperscan扫描问题 解决 xff1a 使用这个的时候应该扫描的是mapper层 如果我们用成全局的扫描 xff08 根目录 xff09 xff0c
  • 找不到org.springframework.cloud.client.loadbalancer.reactive.OnNoRibbonDefaultCondition

    原因 xff1a 该类存在于spring cloud commons jar 引用的jar包存在冲突 新版本的spring cloud commons中取消了OnNoRibbonDefaultCondition类 解决 xff1a 引入依赖
  • Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springfra..问题

    原因 xff1a 依赖冲突 解决 xff1a 例如我的是spring cloud starter gateway和spring boot starter web和spring boot starter webflux依赖冲突排除 sprin
  • 重构 - 消除重复的new创建

    如下 xff1a 有时会遇到这种重复的new创建 span class token keyword public span span class token keyword class span span class token class
  • IDEA快捷键-重构

    文章目录 重构项目案例参考重构技巧1 消除重复new创建重构技巧2 提炼函数 xff0c 消除重复计算 提炼函数提炼变量搬移函数inlIne使用 xff08 内联 xff09 inLine重构局部变量inLine重构方法 重构重构菜单栏ID
  • 重构 - 提炼函数,消除重复代码

    一 参考资料二 重构步骤 以提炼重复计算函数为例子演示代码具体步骤1 提取重复new创建2 提取会变化的信息3 使用抽取的共有信息 xff0c 并删除原有信息4 提取计算函数5 使用卫语句 xff0c 简化代码逻辑 一 参考资料 重构 2
  • 模板方法 + 工厂变体消除重复if else

    模板方法 43 工厂消除重复if else 1 将重复代码 xff0c 抽取到抽象类中2 子类实现抽象类3 使用工厂获取对象 思维导图 xff1a 示例代码 xff1a 1 将重复代码 xff0c 抽取到抽象类中 span class to

随机推荐