Redis使用总结

Redis使用总结

在项目开发过程中,笔主使用Redis也有一段时间了。在一些特性的场景,Redis能帮助我们解决一些问题。因此,总结一下分享给大家。

1.使用Redis实现分布式锁

  • 使用Boolean setIfAbsent(K key, Vvalue)
/**
 * Redis访问工具类
 */
@Component
public class RedisDao {
	private static Logger logger = LoggerFactory.getLogger(RedisDao.class);
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@Resource(name="stringRedisTemplate")
	private ValueOperations<String, String> valOpsStr;
	
	/**
	 * 如果key不存在,就存储一个key-value,相当于SETNX命令
	 * @param key      键
	 * @param value    值,可以为空
	 * @return
	 */
	public boolean setIfObsent (String key, String value) {
		return valOpsObj.setIfAbsent(key, value);
	}
}
  • 使用Boolean setNX(byte[] key, byte[] value)
@Component
public class RedisDao {
	private static Logger logger = LoggerFactory.getLogger(RedisDao.class);
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	/**
	 * 设置一个锁
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean setNX(String key, String value) {
		RedisConnection connection = null;
		boolean flag = false;
		try {
			//获取一个连接
			connection = stringRedisTemplate.getConnectionFactory().getConnection();
			connection.setNX(key.getBytes(), value.getBytes());
			connection.expire(key.getBytes(), 120);
			logger.info("设置redis锁成功");
			flag = true;
		} catch (Exception e) {
			connection.del(key.getBytes());
			logger.error("设置redis锁失败,原因:{}", e);
		}
		return flag;
	}
}

2.分布式场景下使用Redis生成有序递增序列
笔主在开发过程中有个需求,要求主键的格式为“xxx+有序递增的数字”,xxx是一个特定的字符串常量。这时,借助Mysql的主键自增功能显然不能满足需求。这时,可以借助Long increment(K key, long delta)生成有序递增的数字,然后拼接出主键。

@Component
public class RedisDao {
	private static Logger logger = LoggerFactory.getLogger(RedisDao.class);
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@Resource(name="stringRedisTemplate")
	private ValueOperations<String, String> valOpsStr;
	
	/**
	 * 为指定的key对应的value增加delta
	 * @param key   键
	 * @param delta 增量
	 * @return
	 */
	public Long increment(String key, long delta){
		return valOpsStr.increment(key, delta);
	}
}

3.使用 bitmap 实现用户上线次数统计

http://doc.redisfans.com/string/bitcount.html

4.使用Redis的List结构实现分布式队列
5.使用Redis的Set结构实现集合间的并集、交集、差集
例如:两个不同的用户共同关注了哪些主播
6.使用Redis的ZSet结构实现排行榜统计
例如:某个主播的粉丝贡献排行榜,假设主播id为001,这里定义该主播的粉丝贡献排行榜的key为fans_contribution_rank_001。

/**
 * Redis访问工具类
 */
 @Component
public class RedisDao {
	private static Logger logger = LoggerFactory.getLogger(RedisDao.class);
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	/**
	 * 添加zset记录
	 * @param key     键
	 * @param value   值
	 * @param score   分数
	 * @return
	 */
	public boolean zAdd (String key, String value, double score) {
		return zSetOpsStr.add(key, value, score);
	}
	
	/**
	 * 返回按照分数从高到低排序的zset集合
	 * @param key  键
	 * @return
	 */
	public Set<TypedTuple<String>> reverseRangeByScoreWithScores (String key) {
		return zSetOpsStr.reverseRangeWithScores(key, 0, -1);
	}
}

添加打赏记录和查询的测试代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo1ApplicationTests2 {

	private static Logger logger = LoggerFactory.getLogger(Demo1ApplicationTests2.class);
	
	@Autowired
	private TestService testService;
	
	@Autowired
	private RedisDao redisDao;
	
	@Test
	public void contextLoads() {
		//主播的粉丝贡献排行榜key
		String key = "fans_contribution_rank_001";
		//添加用户给主播的打赏记录,参数分别为key、用户id、打赏的道具数
		redisDao.zAdd(key, "100001", 100);
		redisDao.zAdd(key, "100002", 20);
		redisDao.zAdd(key, "100003", 50);
		redisDao.zAdd(key, "100004", 210);
		redisDao.zAdd(key, "100005", 360);
		redisDao.zAdd(key, "100006", 180);
		redisDao.zAdd(key, "100007", 270);
		//查询主播的粉丝贡献排行榜key
		Set<TypedTuple<String>> tuples = redisDao.reverseRangeByScoreWithScores(key);
		System.out.println();
		for (TypedTuple<String> arg :tuples) {
			logger.info("values:{} , score:{}", arg.getValue(), arg.getScore());
		}
	}
}

测试结果如下:

2018-12-03 17:29:31.841 - values:100005 , score:360.0
2018-12-03 17:29:31.842 - values:100007 , score:270.0
2018-12-03 17:29:31.842 - values:100004 , score:210.0
2018-12-03 17:29:31.842 - values:100006 , score:180.0
2018-12-03 17:29:31.842 - values:100001 , score:100.0
2018-12-03 17:29:31.842 - values:100003 , score:50.0
2018-12-03 17:29:31.842 - values:100002 , score:20.0

版权声明:本文为zhaoheng314原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。