基于redis的数据结构做缓存分页利弊

①:基于redis的list数据结构,直接通过list的数据结构,用range方法可以进行分页,在数据量大的时候,性能也很可观,但是当存在接口高并发访问时,
这个list可能会无限延长,且里面的数据会存在很多重复,这就会影响到正常的业务(不是很推荐);

②:基于redis的ZSet数据结构,通过Zset这个有序集合我们也可以做分页,同样也是用range方法,但是这里比较麻烦的是在初始化数据的时候Zset必须存放TypedTuple类型的数据,
这个类型是一个value和score的键值对,具体可以查百度,
这个score的生成比较麻烦我这边测试时用的是当前数据在这个list的位置,然后Zset是根据这个score值来排序的,默认是从小到大;用这个的好处是,即使在高并发情况下Zset中也
不会存在重复数据从而影响正常的业务;而且分页效率也和list结构差不多;

③:用hash和Zset来一起实现;这个是问了一个朋友和得知的,Zset中存储有序的id字段,通过分页后拿到id,然后再用id去hash中取,感觉应该效率相差不大的,
只是中间多了层从hash结构取,还需要维护又一个hash;(为何这样做我也不清楚);


设置缓存后无法保证数据库的一致性!   如果强制保证使用锁的话这样性能会遭到损失。   所以性能和数据的一致性只能选择一个。
先更新数据库 + 再删除缓存」

异步重试。什么是异步重试?

缓存延迟双删策略。

问题1:延迟时间要大于「主从复制」的延迟时间
问题2:延迟时间要大于线程 B 读取数据库 + 写入缓存的时间

一旦我们决定使用缓存,那必然要面临一致性问题。性能和一致性就像天平的两端,无法做到都满足要求。  「更新数据库 + 更新缓存」、「更新数据库 + 删除缓存」

性能和一致性不能同时满足,为了性能考虑,通常会采用「最终一致性」的方案

2、掌握缓存和数据库一致性问题,核心问题有 3 点:缓存利用率、并发、缓存 + 数据库一起成功问题

3、失败场景下要保证一致性,常见手段就是「重试」,同步重试会影响吞吐量,所以通常会采用异步重试的方案

4、订阅变更日志的思想,本质是把权威数据源(例如 MySQL)当做 leader 副本,让其它异质系统(例如 Redis / Elasticsearch)成为它的 follower 副本,通过同步变更日志的方式,保证 leader 和 follower 之间保持一致


超卖问题:
第二种解决:在数据库中将用户id和商品id加上唯一索引解决

你可能感兴趣的:(redis,缓存,数据结构)