redis數據結構和使用場景
- strings
- lists
- sets
- sort sets
- hashes
strings
- token
- session
- validateCode
- 分布鎖
lists
sets
sort sets
hashes
bitmaps
hyperloglog
geo
主要使用場景對應的java源碼
/**
* 代金卷例子.
* set結構保證了value的唯一性.
*/
@Test
public void setCoupon() {
final String COUPON_KEY = "coupon";
for (int i = 0; i < 100; i++) {
redisTemplate.opsForSet().add(COUPON_KEY, String.format("abc%s", i));
redisTemplate.opsForSet().add(COUPON_KEY, String.format("abc%s", i));
}
Assert.assertEquals(Long.valueOf(100), redisTemplate.opsForSet().size(COUPON_KEY));
redisTemplate.opsForSet().pop(COUPON_KEY);
Assert.assertEquals(Long.valueOf(99), redisTemplate.opsForSet().size(COUPON_KEY));
}
/**
* 用戶消費top10.
* sortList結構做實時排名.
*/
@Test
public void sortListTop() {
final String CONSUMPTION_KEY = "consumption";
redisTemplate.opsForZSet().add(CONSUMPTION_KEY, "person1", 1);
redisTemplate.opsForZSet().add(CONSUMPTION_KEY, "person2", 2);
redisTemplate.opsForZSet().add(CONSUMPTION_KEY, "person3", 1);
for (Object o : redisTemplate.opsForZSet().rangeByScore(CONSUMPTION_KEY, 1, 1)) {
System.out.println(o);
}
}
@Test
public void distributeLock2() {
new Thread(() -> {
for (int i = 0; i < 5; i++) {
queue2();
}
}).start();
}
/**
* 地理位置測試.
*/
@Test
public void geoTest() {
BoundGeoOperations boundGeoOperations = redisTemplate.boundGeoOps("CHINA:CITY");
Point nanjing = new Point(118.803805, 32.060168);
boundGeoOperations.add(nanjing, "南京市");
Point beijing = new Point(116.397039, 39.9077);
boundGeoOperations.add(beijing, "北京市");
Point shanghai = new Point(120.52, 30.40);
boundGeoOperations.add(shanghai, "上海市");
//geodist:獲取兩個地理位置的距離
Distance distance = boundGeoOperations.distance("南京市", "北京市", Metrics.KILOMETERS);
System.out.println("南京市到北京市之間的距離是:" + distance.getValue() + "km");
Distance distance2 = boundGeoOperations.distance("南京市", "上海市", Metrics.KILOMETERS);
System.out.println("南京市到上海市之間的距離是:" + distance2.getValue() + "km");
//geohash:獲取某個地理位置的geohash值
List<String> list = boundGeoOperations.hash("南京市");
System.out.println("南京市的geoHash = " + list.get(0));
//geopos:獲取某個地理位置的坐標
List<Point> pointList = boundGeoOperations.position("南京市");
System.out.println("南京市的經緯度為 = " + pointList.get(0));
//georadius:根據給定地理位置坐標獲取指定范圍內的地理位置集合
//查詢南京市1000KM范圍內的城市
Circle within = new Circle(nanjing, 1000000);
//設置geo查詢參數
RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
//查詢返回結果包括距離和坐標
geoRadiusArgs = geoRadiusArgs.includeCoordinates().includeDistance();
//按查詢出的坐標距離中心坐標的距離進行排序
geoRadiusArgs.sortAscending();
//限制查詢返回的數量
geoRadiusArgs.limit(2);
GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = boundGeoOperations.radius(within, geoRadiusArgs);
List<GeoResult<RedisGeoCommands.GeoLocation<String>>> geoResultList = geoResults.getContent();
for (GeoResult geoResult : geoResultList) {
System.out.println("geoRadius " + geoResult.getContent());
}
//georadiusbymember:根據給定地理位置獲取指定范圍內的地理位置集合
geoRadiusArgs.limit(1);
geoResults = boundGeoOperations.radius("南京市", new Distance(1000000), geoRadiusArgs);
geoResultList = geoResults.getContent();
for (GeoResult geoResult : geoResultList) {
System.out.println("geoRadiusByMember " + geoResult.getContent());
}
//刪除位置信息,此命令不是geo提供的,是使用zrem命令刪除的
boundGeoOperations.remove("南京市");
}
/**
* 查看用戶在線狀態情況 1在線,0離線.
*/
@Test
public void bitmapTest() {
final String onlineKey = "online:";
for (int i = 0; i < 100; i++) {
redisTemplate.opsForValue().setBit(onlineKey, i, i % 2 == 0);
}
for (int i = 0; i < 10; i++) {
System.out.println(i + "=" + redisTemplate.opsForValue().getBit(onlineKey, i));
}
System.out.println("online:" + redisConfig.bitCount(onlineKey));
}
/**
* 統一數組里數據唯一性.
* IP地址去重復.
*/
@Test
public void hyperLogLogTest() {
final String loglogKey = "loglog:";
String[] arr = new String[100];
for (int i = 0; i < 100; i++) {
arr[i] = "A" + new Random().nextInt(10) + 1;
}
redisTemplate.opsForHyperLogLog().add(loglogKey, arr);
System.out.println("loglog:" + redisTemplate.opsForHyperLogLog().size(loglogKey));
}