Redis——实现关注与取关等功能


实现关注与取关

实现

Controller层

@RestController
@RequestMapping("/follow")
public class FollowController {
    @Resource
    private IFollowService followService;
    @PutMapping("/{id}/{isFollow}")
    public Result follow(@PathVariable("id")Long followUserId,@PathVariable("isFollow") Boolean isFollow){
        return followService.follow(followUserId,isFollow);
    }

    @GetMapping("/or/not/{id}")
    public Result follow(@PathVariable("id")Long followUserId){
        return followService.isFollow(followUserId);
    }
}

Service层


实现共同关注功能

修改

实现

Controller层

@GetMapping("/common/{id}")
    public Result followCommons(@PathVariable("id")Long id){
        return followService.followCommons(id);
    }

Service层


关注推送

Feed流的模式

拉模式

优点:节省内存空间,收件箱读完以后,就不用了可以清理,所以消息只保存一份在发件人的发件箱中

缺点:每次去读消息时,都要去拉取再做排序,耗时时间长,读取时间较

推模式

弥补拉模式的缺点,每次都会把消息发给每一个粉丝,并排序,等粉丝读取

缺点:这种扩散方式,每次更新消息时,都会发给每个粉丝,所以内存占用率很高

推拉结合模式

普通人采取推模式

大V,活跃粉丝采用推模式,普通的粉丝采用拉模式

总结


Feed流的分页问题

思考应该用Redis中哪种数据结构进行时间戳的排序?是sortedset还是list?

list查询数据只能按照角标查询,或者首尾查询,不支持滚动分页 sortedset按照score值排序,得出排名,如果按照排名查询则跟角标查询无区别,但是sortedset支持按照score值范围进行查询(把时间戳按照从大到小进行排列,每次排序都记住最小的时间戳,然后下次查询时再找比这个时间戳更小的,这样就实现了滚动分页查询)

小结:如果数据会有变化,尽量使用sortedset实现分页查询

采用传统角标查询会出现下列问题

使用滚动分页,每次存入页的最后一次角标

实现

Controller层

@PostMapping
    public Result saveBlog(@RequestBody Blog blog) {
        return blogService.saveBlog(blog);
    }

Service层


角标查询 和 通过记录最后一个的范围查询的对比

一开始redis中z1集合存入的数据("m6" : 6,"m5" : 5,"m4" : 4,"m3" : 3,"m2" : 2,"m1" : 1)

实现滚动分页查询一定要传入四个参数:

分数的最大值(max),分数的最小值(min),偏移量(offset),数量(count)(其中分数最小值,数量固定不变)

最大值每次都要找上一次查询的最小分数(除了第一次)

偏移量(第一次采取0,以后采取1,小于等于与小于的区别)

注意:如果分数一样会出现以下问题,所以offset应是上一次查询的最小分数的总个数

接口说明

Controller层

@GetMapping("/of/follow")
    public Result queryBlogOfFollow(@RequestParam("lastId") Long max,@RequestParam(value = "offset",defaultValue = "0") Integer offset){
        return blogService.queryBlogOfFollow(max,offset);
    }

Service层

经验分享 程序员 微信小程序 职场和发展