redis减库存 同步到mysql_redis并发减库存

本文通过一个Java应用模拟并发更新库存,对比了Redis和MySQL在减库存操作上的性能。实验结果显示,执行10次并发更新,Redis平均耗时170.6ms,而MySQL耗时1148.5ms,Redis的性能约为MySQL的7倍。
摘要由CSDN通过智能技术生成

商品有库存, 如10000 每买一个商品 库存就减一减库存可以通过mysql来实现 如update product_stock set stock = stock - 1 where product_id = 1 and stock > 0;也可以使用redis来实现 如decr 1_stock(integer) 99面对这种场景都说要使用redis 因为redis并发性能更好 想实际验证一下是否这样思路设置较大的并发数去更新库存 执行10次 比较redis和mysql花费的时间代码:

@SpringBootApplication

public class CocurrentUpdateStockApplication implements CommandLineRunner {

@Autowired

private JdbcTemplate jdbcTemplate;

@Bean

JedisConnectionFactory jedisConnectionFactory() {

return new JedisConnectionFactory();

}

@Bean

RedisTemplate redisTemplate() {

final RedisTemplate template = new RedisTemplate();

template.setConnectionFactory(jedisConnectionFactory());

template.setKeySerializer(new StringRedisSerializer());

template.setHashValueSerializer(new GenericToStringSerializer(Long.class));

template.setValueSerializer(new GenericToStringSerializer(Long.class));

return template;

}

public static void main(String[] args) {

SpringApplication.run(CocurrentUpdateStockApplication.class, args);

}

//mysql减库存任务

private Callable updateStockInMysqlTask = () -> {

final String sql = "update product_stock set stock = stock-1 where product_id=1 and stock>0";

jdbcTemplate.update(sql);

return null;

};

//redis减库存任务

private Callable updateStockInRedisTask = () -> {

redisTemplate().execute(new RedisCallback() {

public Long doInRedis(RedisConnection connection) throws DataAccessException {

Long decr = connection.decr("1_stock".getBytes());

return decr;

}

});

return null;

};

@Override

public void run(String... args) throws Exception {

final String name = "mysql"; // or "redis"

System.out.printf("start concurrent update stock in %s...%n", name);

List timeList = new ArrayList<>();

for (int i = 0; i < 10; i++) {//分别统计10次

long start = System.currentTimeMillis();

concurrentUpdateStock(name); //

long end = System.currentTimeMillis();

System.out.printf("Done. Take time: %d ms%n", end - start);

timeList.add(end - start);

Thread.sleep(1000); //休眠1秒

}

System.out.println(timeList.stream().collect(Collectors.summarizingLong(t -> t))); //输出统计结果

}

private void concurrentUpdateStock(String name) throws InterruptedException {

// 模拟并发更新库存

int nThreads = 500; //设置一个较大线程数

ExecutorService pool = Executors.newFixedThreadPool(nThreads);

List> tasks = new ArrayList<>();

for (int i = 0; i < nThreads * 2; i++) { //2倍于线程数的减库存任务

if ("mysql".equalsIgnoreCase(name))

tasks.add(updateStockInMysqlTask);

else if ("redis".equalsIgnoreCase(name))

tasks.add(updateStockInRedisTask);

}

List> futureList = pool.invokeAll(tasks); //并发去执行这些任务

while (futureList.stream().anyMatch(f -> !f.isDone())); //等待任务执行完

pool.shutdown();

}

}

输出结果: mysql:

LongSummaryStatistics{count=10, sum=11485, min=897, average=1148.500000, max=1458}

redis:

LongSummaryStatistics{count=10, sum=1706, min=95, average=170.600000, max=493}

结论:并发执行1000次减库存操作 mysql要比redis慢差不多7倍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值