redis-distributed-id-generator-start之id生成器压测的一些思考

2024-08-21 10:12

本文主要是介绍redis-distributed-id-generator-start之id生成器压测的一些思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1.测试工程集成id生成器
    • 2.新建表
    • 3.测试代码
    • 4.jemeter压测结果预期
    • 5.总结

1.测试工程集成id生成器

    省略–参考之前的文章

https://mp.weixin.qq.com/s/B1vcrPVnFI1pKH7RAnPQ5g
https://blog.csdn.net/qq_34905631/article/details/138121262?spm=1001.2014.3001.5501

2.新建表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for id_create
-- ----------------------------
DROP TABLE IF EXISTS `id_create`;
CREATE TABLE `id_create`  (`id` bigint NOT NULL COMMENT '主键',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

3.测试代码

    IdCreate实体类

@Data
@TableName("id_create")
public class IdCreate implements Serializable {private static final long serialVersionUID = 8808172704142222291L;private Long id;}

    IdCreateMapper类

package xxxx.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.corporate.member.entity.IdCreate;import java.util.Collection;public interface IdCreateMapper extends BaseMapper<IdCreate> {/*** 批量插入 仅适用于mysql** @param entityList 实体列表* @return 影响行数*/Integer insertBatchSomeColumn(Collection<IdCreate> entityList);}

    TestController类

@RestController
@RequestMapping("/testId")
public class TestController {@Autowiredprivate ZlfRedisIdByScripts1Service zlfRedisIdByScripts1Service;private volatile Boolean flag = Boolean.TRUE;private AtomicInteger num = new AtomicInteger(0);@GetMapping("/idCreate")public RestResponse idCreate() {log.info("=========idCreate开始==============");try {if (flag) {IdCreate idCreate = new IdCreate();GeneratorIdDto dto = new GeneratorIdDto();dto.setApplicationName("t_id1");dto.setTabName("id_create");dto.setLength(16);   idCreate.setId(zlfRedisIdByScripts1Service.generatorIdByLength(dto));synchronized (idCreates) {idCreates.add(idCreate);log.info("=========idCreate加入队列完成==============num:{}", num.incrementAndGet());if (CollectionUtil.isNotEmpty(idCreates) && num.get() == 100000) {Integer i = idCreateMapper.insertBatchSomeColumn(idCreates);log.info("=========idCreate数据插入完成==============idCreates.size:{}", idCreates.size());flag = Boolean.FALSE;Thread.sleep(10 * 1000);if (i > 0) {//清空idCreatesidCreates.clear();log.info("=========idCreate====idCreates清空完毕==========");}return RestResponse.success("已插入100000成功");}}return RestResponse.success("id生成中");}} catch (Exception e) {e.printStackTrace();log.error("异常:{}", e.getMessage());return RestResponse.fail(e.getMessage());}log.info("=========idCreate====id生成完成==========");return RestResponse.success("id生成完成");}}

4.jemeter压测结果预期

    使用jemeter新建一个线程组,线程数设置1000,循环次数100次,然后多执行几次,直达请求100000(10w)次之后,使用mybatisPlus的sql注入器批量插入100000(10w)条数据到id_create表中,没有出现id重复,导致主键冲突而插入失败的情况,10w数据全部入库。

5.总结

    如果jemeter的线程设置过多的话,会出现超时连接被拒绝的问题,所以线程数需要设置少一点,之前我压测的时候也遇到这个问题,之前的文章有提到的,可以去看之前的文章,本文主要是想验证使用 redis-distributed-id-generator-start并发下生成的id会不会有重复,插入数据库导致id主键冲突,验证结果是不会的,虽然 redis-distributed-id-generator-start的代码里面使用了如下代码:

 private volatile Integer index = 0;int idx = index++ % rps.size();

    i++是线程不安全的,但是在 redis-distributed-id-generator-start里面即使是线程不安全但是最终取模的值就0,1,2选择节点也是随机的,可以达到了随机的效果,及时是不同线程同同时选到了一个节点上执行,luna脚本只能给一个线程生成id,另外一个线程生成失败之后有重试机制,会重新去随机选择节点生成id,但是还是有可能重试次数都用完了也没有生成id,但是经过上面的压测,基本上是没有出现这种情况的,累计10w数据全部插入数据库,没有出现主键冲突的情况,所以该项目还是非常666的,只不过压测的时候redis的连接满了,导致连接redis超时了,可以配置优化redis的连接参数设置大一点,这样一个redis的节点可以有更多的连接可以用,那么单节点的吞吐量将会大大提高,可以使用master-v2版本来集成测试的,可以将index++优化成使用AtomicInteger,从并发的角度index++不是线程安全的,但是根据编程严谨性上讲,这个index++是个小问题的,但是不会导致id生成重复出现,这几天思考了下单列模式(单列安全的工具类)、spring单列,有的时候是不用考虑单列是否安全,只要单列调用的方法是封闭的,使用的是内部局部的变量是安全的,java的JMM内存模型来讲,堆、方法区这两个是线程公共且共享的,但是局部变量,方法调用是在栈上,栈、本地栈、程序计数器是线程私有,所以有的时候还是需要考虑单例的线程安全性,如果单例调用的方法使用了外部全局静态、非静态变量(不管是否加了volatile关键字)是线程不安全的,除该全局变量本身具备线程安全的能力的实现(比如AtomicInteger等),所以在写代码的时候还是要时刻考虑是否有线程安全性的问题并加于解决(并发编程),有的时候写的代码跟我们想象的预期不是一致的,代码姿势真的非常非常的重要,姿势不对,努力白费,姿势不对,当场翻车,本次分享到此结束,希望对你有所启发和帮助,请一键三连,么么么哒!

这篇关于redis-distributed-id-generator-start之id生成器压测的一些思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092868

相关文章

关于rpc长连接与短连接的思考记录

《关于rpc长连接与短连接的思考记录》文章总结了RPC项目中长连接和短连接的处理方式,包括RPC和HTTP的长连接与短连接的区别、TCP的保活机制、客户端与服务器的连接模式及其利弊分析,文章强调了在实... 目录rpc项目中的长连接与短连接的思考什么是rpc项目中的长连接和短连接与tcp和http的长连接短

基于Go语言实现一个压测工具

《基于Go语言实现一个压测工具》这篇文章主要为大家详细介绍了基于Go语言实现一个简单的压测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录整体架构通用数据处理模块Http请求响应数据处理Curl参数解析处理客户端模块Http客户端处理Grpc客户端处理Websocket客户端

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

Mybatis官方生成器的使用方式

《Mybatis官方生成器的使用方式》本文详细介绍了MyBatisGenerator(MBG)的使用方法,通过实际代码示例展示了如何配置Maven插件来自动化生成MyBatis项目所需的实体类、Map... 目录1. MyBATis Generator 简介2. MyBatis Generator 的功能3

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis延迟队列的实现示例

《Redis延迟队列的实现示例》Redis延迟队列是一种使用Redis实现的消息队列,本文主要介绍了Redis延迟队列的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录一、什么是 Redis 延迟队列二、实现原理三、Java 代码示例四、注意事项五、使用 Redi

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

redis-cli命令行工具的使用小结

《redis-cli命令行工具的使用小结》redis-cli是Redis的命令行客户端,支持多种参数用于连接、操作和管理Redis数据库,本文给大家介绍redis-cli命令行工具的使用小结,感兴趣的... 目录基本连接参数基本连接方式连接远程服务器带密码连接操作与格式参数-r参数重复执行命令-i参数指定命

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维