背景:给大批量用户分配账号,用户和账号关系为一对一,支持tps150左右。
解决方案:redis队列存储账号,redis锁(生成账号)+多线程(处理分配逻辑)
代码逻辑
//多线程生成账号
threadPoolTaskExecutor.submit(() -> getInfo(redisCacheBatchNum));
//生成账号逻辑
private void getInfoToRedisCache(Integer addNum) {
Long value = redisTemplate.opsForValue().increment(LOCK_KEY, 1);
redisTemplate.expire(LOCK_KEY, 10, TimeUnit.SECONDS);
if (value == 1) {
try {
Integer cacheSize = redisTemplate.opsForSet().size(REDIS_CACHE_KEY).intValue();
if (cacheSize < redisCacheNum) {
log.info("{}目前获取锁成功,当前缓存数量为{},开始入队",Thread.currentThread().getName(),cacheSize);
。。。。(生成账号逻辑)
//将生成账号放入到redis队列中,注意set可以保证唯一性
resultList.stream().forEach(e -> redisTemplate.opsForSet().add(REDIS_CACHE_KEY, e));
}
} finally {
log.info("{}入队结束释放锁",Thread.currentThread().getName());
redisTemplate.delete(LOCK_KEY);
}
}
}
//获取redis队列中账号,然后可以和用户进行绑定
redisTemplate.opsForSet().pop(REDIS_CACHE_KEY);
如果并发量小,数据压力不大,可以给数据库加行所,具体实现可以在表中增加一个version字段,每次更新或新增数据拿出上一次的version作为判断条件,如果version不变version递增,否则更新或新增失败。
网友评论