一、重点
代码讲解:6-点赞功能-定时持久化到数据库-pipeline+lua-优化pipeline_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1yP411C7dr
代码:
blogLike_schedule/like06 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com)
https://gitee.com/flowers-bloom-is-the-sea/XinQiUtilsOrDemo/tree/master/blogLike_schedule/like06
数据库表的设计:
blogLike_schedule · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com)
https://gitee.com/flowers-bloom-is-the-sea/XinQiUtilsOrDemo/tree/master/blogLike_schedule
架构图:
最开始的代码版本:
(108条消息) springboot+redis+mysql+quartz-通过Java操作redis的KEYS*命令获取缓存数据定时更新数据库_xin麒的博客-CSDN博客
二、核心代码:
定时板块就看这篇吧:
@Override
public void updateAllLikeListToDatabaseByPipeline1() {
String prefix = "BLOG_LIKED_KEY";
// Set<String> keys = getAllRedisKeyByKeys(prefix);//这个不行!
Set<String> keys = getAllRedisKeyByScanThroughMatch(prefix);//通过scan拿到以BLOG_LIKED_KEY开头的所有key
if (keys == null || keys.size() == 0) return;
Map<Long,Map<String,String>> maps = getIdWithTimeListsByPipelineByJedis(keys);
if (maps == null || maps.size() == 0) return;
for (Map.Entry<Long, Map<String, String>> entry : maps.entrySet()) {
Long blogId = entry.getKey();
Map<String, String> likeList = entry.getValue();
updateLikeListByBlogId(blogId,likeList);
}
}
这里还是算半Pipeline方法,因为zset的键是通过scan扫描获取到的,这里的scan扫描的方法应该是可以放到管道里面的。但是呢因为Pipeline不适合做太强逻辑相关的命令,所以这个应该也算可以的了。为什么?这里可以去看看这篇文章:
(108条消息) redis事务-pipeline-lua三者区别简单概括_xin麒的博客-CSDN博客
先通过scan方法扫出
public Set<String> getAllRedisKeyByScanThroughMatch(String prefix) {//找不到stringRedisTemplate对Zset里键值对扫描的资料
Jedis jedis = null;
Set<String> blogLikeList = new HashSet<>();
ScanParams scanParams = new ScanParams();
try {
jedis = jedisPool.getResource();
String cursor = "0";
do {
// 扫描并获取一部分key
ScanResult<String> result = jedis.scan(cursor, scanParams.match(prefix.concat("*")));
// 记录cursor
cursor = result.getCursor();
List<String> list = result.getResult();
if (list == null || list.isEmpty()) {
break;
}
// 遍历
for (String key : list) {
log.debug("key is {}", key);//这里可以看到有哪些key
blogLikeList.add(key);
}
} while (!cursor.equals("0"));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) jedis.close();
}
return blogLikeList;
}
然后再通过这个方法来使用pipeline技术:
public Map<Long,Map<String,String>> getIdWithTimeListsByPipelineByJedis(Collection<String> collection) {
String prefix = "BLOG_LIKED_KEY";
Jedis jedis = null;
Map<Long,Map<String,String>> maps = null;
try {
jedis = jedisPool.getResource();
Pipeline pipe = jedis.pipelined();
ArrayList<Long> blogKeyIds = new ArrayList<>(collection.size());
for (String key : collection) {
pipe.zrangeWithScores(key, 0, -1);
blogKeyIds.add(Long.parseLong(key.substring(prefix.length(),key.length())));
}
List<Object> response = pipe.syncAndReturnAll();
maps = pipeLineResponseTransformedToMap(response,blogKeyIds);
} catch (NumberFormatException e) {
e.printStackTrace();
} finally {
jedis.close();
}
log.debug("maps is {}",maps);
return maps;
}
三、其他
现在是2023-07-01,不得不吐槽stringRedisTemplate
和RedisTemplate
,如果要来实现使用pipeline技术将缓存里面的zset数据获取得到,好像只能用jedis
了,其他的都很难找得到参考资料,全网搜不到,官网也很少资料(可能没细看),笑死,所以后面就用jedis
来实现了。
其他类似的文章:
(108条消息) springboot+redis+mysql+quartz-通过Java操作redis的KEYS*命令获取缓存数据定时更新数据库_xin麒的博客-CSDN博客
(108条消息) springboot+redis+mysql+quartz-通过Java操作jedis定时使用lua脚本获取缓存数据并更新数据库_xin麒的博客-CSDN博客
(108条消息) lua脚本获取table类型-Java使用lua脚本操作redis获取zset元素的集合_xin麒的博客-CSDN博客
(108条消息) springboot+redis+mysql+quartz-通过Java操作jedis使用pipeline获取缓存数据定时更新数据库_xin麒的博客-CSDN博客
(108条消息) springboot+redis+mysql+quartz-通过Java操作jedis的scan命令获取缓存数据定时更新数据库_xin麒的博客-CSDN博客