Springboot2.x 集成 jedis和spring-boot-starter-data-redis的性能测试比较(Jedis完胜:附带源码)
文章系转载,方便整理和归纳
版权声明:本文为CSDN博主「斌哥谈编程」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/houpeibin2012/article/details/105839651
1.pom文件引入jedis和spring-boot-starter-data-redis的依赖
2.其他依赖的引入(Swagger)
3.Jedis配置类
4.Jedis及spring-boot-starter-data-redis的配置信息
5.Swagger配置类
6.编写测试相关类
7.测试
7.1插入数据测试
7.2读取数据测试
7.3多线程读取数据测试
8. 结论
温馨提示:
本文配套代码:https://gitee.com/guduwuhen/springboot2-lesson/tree/master/redispro
1.pom文件引入jedis和spring-boot-starter-data-redis的依赖
<properties><java.version>1.8</java.version><jedis.version>2.9.0</jedis.version><fastjson.version>1.2.68</fastjson.version><guava.version>28.2-jre</guava.version>
</properties>
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>${jedis.version}</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Springboot 使用的是2.2.4.RELEASE版本。
2.其他依赖的引入(Swagger)
如下是完整的pom文件代码:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.ieslab.powergrid</groupId><artifactId>redispro</artifactId><version>0.0.1-SNAPSHOT</version><name>demosvr</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><jedis.version>2.9.0</jedis.version><fastjson.version>1.2.68</fastjson.version><guava.version>28.2-jre</guava.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>${jedis.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${guava.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><!-- 热部署时使用 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!-- set/get方法免写,需要安装idea的插件 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-launcher</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
3.Jedis配置类
RedisConfiguration.java
package com.test.redis.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;/** <p>Title: RedisConfiguration </p>* <p>Description: 用户rest接口类,测试demo使用</p>** @author binge* @date 2020-2-20 下午7:15:30* @version V1.0*/
@Configuration
public class RedisConfiguration {@Bean(name= "jedis.pool")@Autowiredpublic JedisPool jedisPool(@Qualifier("jedis.pool.config") JedisPoolConfig config,@Value("${jedis.pool.host}")String host,@Value("${jedis.pool.port}")int port) {return new JedisPool(config, host, port);}@Bean(name= "jedis.pool.config")public JedisPoolConfig jedisPoolConfig (@Value("${jedis.pool.config.maxTotal}")int maxTotal,@Value("${jedis.pool.config.maxIdle}")int maxIdle,@Value("${jedis.pool.config.maxWaitMillis}")int maxWaitMillis) {JedisPoolConfig config = new JedisPoolConfig();config.setMaxTotal(maxTotal);config.setMaxIdle(maxIdle);config.setMaxWaitMillis(maxWaitMillis);return config;}
}
4. Jedis及spring-boot-starter-data-redis的配置信息
spring:redis:#数据库索引database: 0host: 192.168.22.150port: 6379lettuce:pool:#最大连接数max-active: 100#最大阻塞等待时间(负数表示没限制)max-wait: 5000#最大空闲max-idle: 500#最小空闲min-idle: 8#连接超时时间timeout: 10000jedis :pool :host : 192.168.22.150port : 6379config :maxTotal: 1000maxIdle: 1000maxWaitMillis : 100000
5. Swagger配置类
package com.test.redis.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/** <p>Title: SwaggerConfig </p>* <p>Description: Swagger配置类</p>** @author binge* @date 2020-2-20 下午7:15:30* @version V1.0*/@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket creatApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) // 指定构建api文档的详细信息的方法,下面会有实现:apiInfo().select()// 指定要生成api接口的包路径,这里把controller作为包路径,生成controller中的所有接口.apis(RequestHandlerSelectors.basePackage("com.test.redis.controller")).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("Spring Boot集成Swagger2接口测试").description("生成的接口如下").version("1.0").contact(new Contact("斌哥","https://blog.csdn.net/houpeibin2012","houpeibin@126.com")).build();}
}
6. 编写测试相关类
TestController.java
package com.test.redis.controller;import com.test.redis.entity.Result;
import com.test.redis.entity.TestDataEntity;
import com.test.redis.service.TestAsyncService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import java.util.*;
import java.util.Map.Entry;/** <p>Title: TestController </p>* <p>Description: 测试redis</p>** @author binge* @date 2020-2-20 下午7:15:30* @version V1.0*/
@RestController
@Slf4j
@Api(tags="redis性能测试")
public class TestController {@Autowiredprivate JedisPool jedisPool;@AutowiredStringRedisTemplate redisTemplate;@AutowiredTestAsyncService testAsyncService;@RequestMapping("del")@ApiOperation(value="删除所有库",notes="删除所有库")public Result del(){long startTime = System.currentTimeMillis();Jedis jedis = null;try {jedis = jedisPool.getResource();jedis.flushAll();} catch (Exception e) {e.printStackTrace();} finally {//返还到连接池jedis.close();}return Result.ok(System.currentTimeMillis() - startTime);}@RequestMapping("insertStringData")@ApiOperation(value="单个String数据插入",notes="单个String数据插入")@ApiImplicitParams({@ApiImplicitParam(name = "num", value = "插入条数", required = true, dataType = "Int", paramType="query"),@ApiImplicitParam(name = "type", value = "数据类型", required = true, dataType = "String", paramType="query")})public Result insertStringData(int num, String type){long startTime = System.currentTimeMillis();Jedis jedis = null;try {jedis = jedisPool.getResource();for(int i=0; i<num; i++){jedis.set(TestDataEntity.getKey(i, type), TestDataEntity.getTestStringData(type));}} catch (Exception e) {e.printStackTrace();} finally {//返还到连接池jedis.close();}return Result.ok(System.currentTimeMillis() - startTime);}@RequestMapping("insertStringDataPipelined")@ApiOperation(value="jedis方式批量插入String数据",notes="jedis方式批量插入String数据")public Result insertStringDataPipelined(@ApiParam(name="num",value="插入条数",required = true)@RequestParam int num,@ApiParam(name="type",value="数据类型",required = true)@RequestParam String type){long startTime = System.currentTimeMillis();Jedis jedis = null;try {//使用管道方式,性能比单次获取性能高jedis = jedisPool.getResource();Pipeline pipeline = jedis.pipelined();Map<String, Response<String>> map = new HashMap<>();for(int i=0; i<num; i++){Response<String> sResponse= pipeline.set(TestDataEntity.getKey(i, type),TestDataEntity.getTestStringData(type));map.put(String.valueOf(i), sResponse);}pipeline.sync();} catch (Exception e) {e.printStackTrace();} finally {//返还到连接池jedis.close();}return Result.ok(System.currentTimeMillis() - startTime);}@RequestMapping("insertStringDataPipelinedByRedisTemplate")@ApiOperation(value="redisTemplate方式批量插入String数据",notes="redisTemplate方式批量插入String数据")public Result insertStringDataPipelinedByRedisTemplate(@ApiParam(name="num",value="插入条数",required = true)@RequestParam int num,@ApiParam(name="type",value="数据类型",required = true)@RequestParam String type) {long startTime = System.currentTimeMillis();/* 插入多条数据 */redisTemplate.executePipelined(new SessionCallback<Object>() {@Overridepublic <K, V> Object execute(RedisOperations<K, V> redisOperations) throws DataAccessException {for(int i=0;i<num;i++){redisTemplate.opsForValue().set(TestDataEntity.getKey(i, type),TestDataEntity.getTestStringData(type));}return null;}});return Result.ok(System.currentTimeMillis() - startTime);}@RequestMapping("getDataByKey")@ApiOperation(value="根据key关键字获取所有key",notes="根据key关键字获取所有key")public Result getDataByKey(@ApiParam(name="key",value="key关键字",required = true)@RequestParam String key){long startTime = System.currentTimeMillis();Jedis jedis = null;Set<String> keys;try {jedis = jedisPool.getResource();keys = jedis.keys(key);log.info(".......keys:" + keys.size());} finally {//返还到连接池jedis.close();}return Result.ok((System.currentTimeMillis() - startTime) + ":数据个数:" + keys.size());}@RequestMapping("getValueBykey")@ApiOperation(value="根据key过滤获取数据",notes="根据key过滤获取数据")public Result getValueBykey(@ApiParam(name="key",value="过滤条件",required = true)@RequestParam String key){long startTime = System.currentTimeMillis();Jedis jedis = null;try {jedis = jedisPool.getResource();//使用管道方式,性能比单次获取性能高Map<String, String> map = new HashMap<>();Set<String> keys = jedis.keys(key);for(String ketTmp :keys){try {String sResponse= jedis.get(ketTmp);map.put(ketTmp,sResponse);} catch (Exception e) {e.printStackTrace();}}long haoshi = System.currentTimeMillis() - startTime;System.out.println("个数:" + map.size() + ";耗时:" + haoshi+ ";大小:" + map.toString().getBytes().length/1024);} finally {//返还到连接池jedis.close();}return Result.ok(System.currentTimeMillis() - startTime);}@RequestMapping("getDataByPipelined")@ApiOperation(value="根据num,type过滤获取数据",notes="根据num,type过滤获取数据")public Result getDataByPipelined(@ApiParam(name="num",value="查询条数",required = true)@RequestParam int num,@ApiParam(name="type",value="数据类型",required = true)@RequestParam String type){long startTime = System.currentTimeMillis();Jedis jedis = null;Map<String, Response<String>> map = null;try {jedis = jedisPool.getResource();//使用管道方式,性能比单次获取性能高Pipeline pipeline = jedis.pipelined();map = new HashMap<>();for(int i=0;i<num;i++){try {Response<String> sResponse= pipeline.get(TestDataEntity.getKey(i, type));map.put(String.valueOf(i), sResponse);} catch (Exception e) {e.printStackTrace();}}pipeline.sync();int i = num-10;for (Entry<String, Response<String>> entry : map.entrySet()) {Response<String> sResponse=(Response<String>)entry.getValue();if(i<num){System.out.println(entry.getKey()+"-----" + sResponse.get());}++i;}System.out.println(map.size() + ":" + map.toString().getBytes().length/1024);} finally {//返还到连接池jedis.close();}return Result.ok((System.currentTimeMillis() - startTime) + ":数据个数:" + map.size() + ":" + map.toString().getBytes().length/1024);}@RequestMapping("getDataByPipelinedAndPipelineKey")@ApiOperation(value="根据key过滤获取数据",notes="根据key过滤获取数据")public Result getDataByPipelinedAndPipelineKey(@ApiParam(name="key",value="过滤条件",required = true)@RequestParam String key){long startTime = System.currentTimeMillis();Jedis jedis = null;try {jedis = jedisPool.getResource();//使用管道方式,性能比单次获取性能高Pipeline pipeline = jedis.pipelined();Map<String, Response<String>> map = new HashMap<>();Response<Set<String>> keys = pipeline.keys(key);pipeline.sync();Set<String> sets = keys.get();for(String ketTmp :sets){try {Response<String> sResponse= pipeline.get(ketTmp);map.put(ketTmp,sResponse);} catch (Exception e) {e.printStackTrace();}}pipeline.sync();long haoshi = System.currentTimeMillis() - startTime;System.out.println("个数:" + map.size() + ";耗时:" + haoshi+ ";大小:" + map.toString().getBytes().length/1024);} finally {//返还到连接池jedis.close();}return Result.ok(System.currentTimeMillis() - startTime);}@RequestMapping("getDataByPipelinedAndJedisKey")@ApiOperation(value="根据key过滤获取数据",notes="根据key过滤获取数据")public Result getDataByPipelinedAndJedisKey(@ApiParam(name="key",value="过滤条件",required = true)@RequestParam String key){long startTime = System.currentTimeMillis();Jedis jedis = null;try {jedis = jedisPool.getResource();//使用管道方式,性能比单次获取性能高Pipeline pipeline = jedis.pipelined();Map<String, Response<String>> map = new HashMap<>();Set<String> sets = jedisPool.getResource().keys(key);for(String ketTmp :sets){try {Response<String> sResponse= pipeline.get(ketTmp);map.put(ketTmp,sResponse);} catch (Exception e) {e.printStackTrace();}}pipeline.sync();int i = sets.size()-10;for (Entry<String, Response<String>> entry : map.entrySet()) {Response<String> sResponse=(Response<String>)entry.getValue();if(i<sets.size()){System.out.println(entry.getKey()+"-----" + sResponse.get());}++i;}System.out.println(map.size() + ":" + map.toString().getBytes().length/1024);} finally {//返还到连接池jedis.close();}return Result.ok(System.currentTimeMillis() - startTime);}@RequestMapping("getDataByPipelinedByRedisTemplate")@ApiOperation(value="RedisTemplate根据key过滤获取数据",notes="RedisTemplate根据key过滤获取数据")public Result getDataByPipelinedByRedisTemplate(@ApiParam(name="key",value="过滤条件",required = true)@RequestParam String key){long startTime = System.currentTimeMillis();try {Set<String> sets = jedisPool.getResource().keys(key);List<String> keyList = new ArrayList<>();for(String ketTmp :sets){keyList.add(ketTmp);}List<Object> obj = redisTemplate.executePipelined((RedisCallback<String>) redisConnection -> {StringRedisConnection stringRedisConnection = (StringRedisConnection) redisConnection;for (String keyTmp : keyList) {stringRedisConnection.get(keyTmp);}return null;});System.out.println(obj.size() + ":" + obj.toString().getBytes().length/1024);} finally {//返还到连接池}return Result.ok(System.currentTimeMillis() - startTime);}@RequestMapping("startAsyn")@ApiOperation(value="启动异步线程并发获取数据",notes="启动异步线程并发获取数据")public Result startAsyn(@ApiParam(name="num",value="线程个数",required = true)@RequestParam int num,@ApiParam(name="key",value="过滤条件",required = true)@RequestParam String key){long startTime = System.currentTimeMillis();for (int i=0; i<num; ++i){testAsyncService.startAsyn(key);}return Result.ok(System.currentTimeMillis() - startTime);}}
Result.java 返回结构
package com.test.redis.entity;/** <p>Title: PersonService </p>* <p>Description: 通用Rest请求返回结构 </p>** @author bingge* @date 2020-2-20 下午7:15:30* @version V1.0*/
public class Result {//服务器返回的状态码(主要给程序员看)。例如 : 200 : 请求成功, 500 : 服务器内部错误,400 : 未知错误private Integer code;//返回码 1:成功 10000:系统错误 10001:参数错误 ...private Integer status;// 服务器的错误信息 ,主要返回给用户看private String msg;// 服务器返回的数据private Object data;public Result() {}//返回操作成功public static Result ok() {return ok(null);}//返回操作成功public static Result ok(Object data) {Result result = new Result();result.setCode(200);result.setStatus(1);result.setMsg("请求成功");result.setData(data);return result;}//返回操作成功public static Result error() {return error("请求失败");}//返回操作成功public static Result error(Integer code, Integer status, String msg) {Result result = new Result();result.setCode(code);result.setStatus(status);result.setMsg(msg);return result;}//返回操作成功public static Result error(String msg) {return error(500,0, msg);}//返回操作成功public static Result error(ErrorStatus errorStatus) {return error(500,errorStatus.value(), errorStatus.getMessage());}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}
}
全局异常捕捉处理GlobleExceptionHandler.java
package com.test.redis.utils;import com.test.redis.entity.MyException;
import com.test.redis.entity.Result;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;/** <p>Title: GlobleExceptionHandler </p>* <p>Description: 全局异常捕捉处理</p>** @author binge* @date 2020-2-20 下午7:15:30* @version V1.0*/
@ControllerAdvice
public class GlobleExceptionHandler {@ResponseBody@ExceptionHandler(value = Exception.class)public Result errorHandler(Exception ex) {//判断异常的类型,返回不一样的返回值if(ex instanceof MissingServletRequestParameterException){return Result.error(400, 0, "全局异常捕捉:缺少必需参数:"+((MissingServletRequestParameterException) ex).getParameterName());}else if(ex instanceof MyException){return Result.error(400, 0, "全局异常捕捉:这是自定义异常");}return Result.error(400, 0, "全局异常捕捉:未知异常");}
}
线程池配置AsyncConfiguration.java
package com.test.redis.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;/** <p>Title: PersonService </p>* <p>Description: 线程池配置</p>** @author houpeibin* @date 2020-2-20 下午7:15:30* @version V1.0*/
@Configuration
@EnableAsync // 启用异步任务
public class AsyncConfiguration {// 声明一个线程池(并指定线程池的名字)@Bean("taskExecutor")public Executor asyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();//核心线程数5:线程池创建时候初始化的线程数executor.setCorePoolSize(50);//最大线程数5:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程executor.setMaxPoolSize(500);//缓冲队列500:用来缓冲执行任务的队列executor.setQueueCapacity(500);//允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁executor.setKeepAliveSeconds(60);//线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池executor.setThreadNamePrefix("DailyAsync-");executor.initialize();return executor;}
}
TestDataEntity.java
package com.test.redis.entity;import com.alibaba.fastjson.JSONObject;import java.util.UUID;/*** 测试数据类*/
public class TestDataEntity {static String testStringData;static{StringBuffer sb = new StringBuffer();for(int i=0;i<100;++i){sb.append("测试");}testStringData = sb.toString();}public static String getTestStringData(String type){JSONObject obj = new JSONObject();obj.put("type",type);obj.put("uuid",UUID.randomUUID());obj.put("data",testStringData);return obj.toString();}public static String getKey(int index, String type){return "rtd:" + index + ":" + type;}
}
7. 测试
打开http://localhost:8080/swagger-ui.html#/
7.1 插入数据测试
首先从http://localhost:8080/swagger-ui.html#/ 测试界面中,找到“单个String数据插入”接口:/insertStringData
![](https://wejack639.oss-cn-beijing.aliyuncs.com/blogimages/img/20211108192145.png)
点击“Try it out”,
![](https://wejack639.oss-cn-beijing.aliyuncs.com/blogimages/img/20211108192222.png)
执行结果在图形的下面,如下图
![](https://wejack639.oss-cn-beijing.aliyuncs.com/blogimages/img/20211108192237.png)
依照此方法依次测试insertStringDataPipelined和insertStringDataPipelinedByRedisTemplate接口
单位:ms
个数 | jedis单次写入 | jedis批量写入 | RedisTemplate批量写入 |
---|---|---|---|
3000个 | 192 | 28 | 54 |
30000个 | 2432 | 242 | 539 |
100000个 | 6061 | 762 | 1988 |
300000个 | 19203 | 2262 | 7015 |
一个数据的长度为:
{"data":"测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试","type":"1","uuid":"aa5b34ba-dd43-4d93-a795-485a0683be7a"}
7.2 读取数据测试
依照此方法依次测试getValueBykey 和getDataByPipelinedAndPipelineKey 、getDataByPipelinedByRedisTemplate接口
单位:ms
个数 | jedis单次读取 | jedis批量读取 | RedisTemplate批量读取 |
---|---|---|---|
3000个 | 489 | 224 | 308 |
30000个 | 2030 | 331 | 891 |
100000个 | 6530 | 689 | 2247 |
300000个 | 18089 | 1622 | 9253 |
7.3 多线程读取数据测试
先插入3000条数据类型为4的数据,便于并发测试:
![](https://wejack639.oss-cn-beijing.aliyuncs.com/blogimages/img/20211108192437.png)
然后启动5个线程:
![](https://wejack639.oss-cn-beijing.aliyuncs.com/blogimages/img/20211108192454.png)
查看后台日志:
![](https://wejack639.oss-cn-beijing.aliyuncs.com/blogimages/img/20211108192505.png)
依次按照如下表格的次数进行测试,记录如下:
个数 | 平均耗时 |
---|---|
5个 | 162 |
10个 | 336 |
20个 | 668 |
50个 | 1679 |
100个 | 1399 |
200个 | 1604 |
500个 | 1506 |
并发测试时,因此同时启动100线程占用时间,一旦线程运行之后,访问redis的时间基本都在1000-2000ms之间。
8.结论
通过读取对比:
- 单次读写,性能最差
- jedis性能比RedisTemplate的性能好3倍,并且随着数据量的增大,倍数也成指数增加
因此优先选择jedis,因为他在性能方面完胜RedisTemplate
并发测试:
- 并发访问时,对于多线程的开销较大,而对于并发访问redis的性能影响较小。
Springboot2.x 集成 jedis和spring-boot-starter-data-redis的性能测试比较(Jedis完胜:附带源码)相关推荐
- 【java毕业设计】基于Spring Boot+mysql的酒店管理系统设计与实现(程序源码+毕业论文)-酒店管理系统
基于Spring Boot+mysql的酒店管理系统设计与实现(程序源码+毕业论文) 大家好,今天给大家介绍基于Spring Boot+mysql的酒店管理系统设计与实现,本论文只截取部分文章重点,文 ...
- springboot2 使用hikaridatasource 并测试_基于Spring Boot 2.x的后端管理网站脚手,源码免费分享...
基于Spring Boot 2.x 的 Material Design 的后端管理网站脚手架 :提供权限认证 用户管理 菜单管理 操作日志 等常用功能 去繁就简 重新出发 基于Spring Boot ...
- spring boot文达云课堂的设计与实现毕业设计-附源码210908
摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题.针对云课堂教学等问题,对其 ...
- spring boot +Mysql双端融合的教学过程管理系统小程序源码66431
摘 要 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,双端融合的教学过程管理系统小程序被用户普遍使 ...
- spring boot实战(第六篇)加载application资源文件源码分析
前言 在上一篇中了解了spring配置资源的加载过程,本篇在此基础上学习spring boot如何默认加载application.xml等文件信息的. ConfigFileApplicationLis ...
- (附源码)Spring Boot 框架整合 OAuth2 实现单点登录 SSO 详细完整源码教程!
1. 前言 技术这东西吧,看别人写的好像很简单似的,到自己去写的时候就各种问题,"一看就会,一做就错".网上关于实现SSO的文章一大堆,但是当你真的照着写的时候就会发现根本不是那 ...
- JavaEE + Oracle + Spring Boot + Mybatis + Maven 开发简易版银行管理系统(附源码)
文章目录 JavaEE + Oracle + Spring Boot + Mybatis + Maven 开发简易版银行管理系统 一.系统介绍 二.开发步骤 三.系统展示 四.开发总结 五.数据库相关 ...
- Spring mvc Data Redis—Pub/Sub(附Web项目源码)
一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...
- Spring Data Redis—Pub/Sub(附Web项目源码)
一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...
- 基于Spring boot+freemarker+Mysql实现的玩具企业官网项目源码
最新文章
- 多个文件中的数据处理,输出自己想要是数据
- 如何写好注释,让同事赞不绝口?
- matlab仿真散射信道,无线信道建模原理及SUI-3信道的MATlab仿真.doc
- SmartRF Flash Programmer1.6.2打不开程序界面问题
- DCMTK:将显示曲线导出到文本文件
- python字典输入学生信息_如何用Python将XML中的所有信息输入字典
- IDEA快捷键生成serialVersionUID
- 不洗袜子的高文博_那个孩子在夏天中旬用高袜子大笑?
- Adreno GPU上的DirectX应用开发简介 (1)
- ZEMAX知识点:坐标间断面(coordinate break)
- 醋醋SEO基础入门教程_seo入门基础知识
- 交换机接口的双工模式
- 游戏中的Decal(贴花)
- Vue响应式原理详细讲解
- 扑克牌游戏——老牛拉破车
- 【课程设计】僵尸大战植物 Zombies vs.Plants
- linux 计价软件,思谷电话计费系统Linux版免费版_思谷电话计费系统Linux版官方下载_思谷电话计费系统Linux版5.1-华军软件园...
- No servers available for service: xxxx
- 复旦计算机学院 王曦,复旦大学计算机科学与工程系薛向阳老师介绍
- Android Toast无效的问题
热门文章
- 研究生小菜简谈“如何做研究”
- JavaScript从入门到放弃之补充篇
- bzoj 1093 [ ZJOI 2007 ] 最大半连通子图 —— 拓扑+DP
- (转)栈与堆栈的区别
- 爬虫笔记(四)------关于BeautifulSoup4解析器与编码
- 2015.5.29日总结
- (转)C++类所占内存大小计算
- Asp.net使用HttpResponse.Filter 实现简繁/繁简转换
- SQL Server 2008安装和配置图解图(转)
- 网络工程师Day7--本地AAA配置