使用RedisAtomicLong优化性能问题
作者:饭团小哥哥iop
这篇文章主要介绍了使用RedisAtomicLong优化性能问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
RedisAtomicLong优化性能
在项目中许多过这样的需求,记录留做备忘。
需要创建一个递增序列,这个序列会提供给多个应用来使用,这样就需要保持序列的原子递增。
RedisAtomicLong
spring-data-redis包中提供的,可以对数据中的Long类型进行原子性操作的类,下面是这个类的头:
/** * Atomic long backed by Redis. Uses Redis atomic increment/decrement and watch/multi/exec operations for CAS * operations. * * @see java.util.concurrent.atomic.AtomicLong * @author Costin Leau * @author Thomas Darimont * @author Christoph Strobl * @author Mark Paluch */ public class RedisAtomicLong extends Number implements Serializable, BoundKeyOperations<String> {
我们可以看到java.util.concurrent.atomic.AtomicLong,和java自带的atomic包一样进行原子性操作,两者不同的是:
AtomicLong
只能在一个应用中使用RedisAtomicLong
可以在所有与Redis有连接的应用中使用
开始优化
应用初始化时创建RedisAtomicLong实例。
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.jiu.common.redis; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.support.atomic.RedisAtomicLong; public class RedisSequenceFactory { private static final Logger log = LoggerFactory.getLogger(RedisSequenceFactory.class); @Autowired private ObjectRedisTemplate<Integer> redisTemplate; public RedisSequenceFactory() { } public void set(String key, long value) { RedisAtomicLong counter = new RedisAtomicLong(key, this.redisTemplate.getConnectionFactory()); counter.set(value); } public long generate(String key, int increment) { RedisAtomicLong counter = new RedisAtomicLong(key, this.redisTemplate.getConnectionFactory()); return counter.addAndGet((long)increment); } public List<Long> generateBatch(String key, int increment, int size) { RedisAtomicLong counter = new RedisAtomicLong(key, this.redisTemplate.getConnectionFactory()); long max = counter.addAndGet((long)(increment * size)); long min = max - (long)(increment * (size - 1)); List<Long> list = new ArrayList(); list.add(min); for(int i = 1; i < size; ++i) { list.add(min + (long)(increment * i)); } return list; } public long queryValue(String key) { Integer val = (Integer)this.redisTemplate.get(key); return val == null ? 0L : (long)val.intValue(); } }
测试代码
public static String tradeIdIncRedisKey = "order:orderid_inc"; @Test public long generateId(){ return redisSequenceFactory.generate(tradeIdIncRedisKey,1); }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。