php 分页查询怎么redis缓存

 我来答
四川源码时代科技有限公司
2017-09-01 · 让每一名学员高薪就业
四川源码时代科技有限公司
源码时代IT培训,即成都源代码教育咨询有限公司,专注Java、PHP、UI设计、H5前端培训,源码时代致力于打造中国高端IT培训品牌,旨在为每一名前来培训的学子提供良好的服务。
向TA提问
展开全部
对于有分页条件的缓存,我们也可以按照不同的分页条件来缓存多个key,比如分页查询产品列表,page=1&limit=10和page=1&limit=5这两次请求可以这样缓存查询结果

productList:page:1:limit:10

productList:page:1:limit:5
这个是一种常见方案,但是存在着一些问题:

缓存的value存在冗余,productList:page:1:limit:10缓存的内容其实是包括了productList:page:1:limit:5中的内容(缓存两个key的时候,数据未发生变化的情况下)

仅仅是改变了查询条件的分页条件,就会导致缓存未命中,降低了缓存的命中率

为了保证数据一致性,需要清理缓存的时候,很难处理,redis的keys命令对性能影响很大,会导致redis很大的延迟,生产环境一般来说禁止该命令。自己手动拼缓存key,你可能根本不知道拼到哪一个page为止。

放弃数据一致性,通过设置失效时间来自动失效,可能会出现查询第一页命中了缓存,查询第二页的时候未命中缓存,但此时数据已经发生了改变,导致第二页查询返回的和第一页相同的结果。
以上,在分页条件下这样使用常规方案总感觉有诸多困扰,诸多麻烦,那是不是就应该放弃使用缓存?
基于SortedSet的分页查询缓存方案
首先想到的解决方法是使用@see ListOperations<K, V>不再根据分页条件使用多个key,而是使用一个key,也不分页将全部的数据缓存到redis中,然后按照分页条件使用range(key,start,limit)获取分页的结果,这个会导致一个问题,当缓存失效时,并发的写缓存会导致出现重复数据
所以想到通过使用set来处理并发时的重复数据,@see ZSetOperations<K, V>
代码逻辑如下:

range(key,start,limit)按照分页条件获取缓存,命中则直接返回

缓存未命中,查询(没有分页条件)数据库或是调用(没有分页)底层接口

add(key,valueScoreMap<value,score>)写入缓存,expire设置缓存时间

当需要清理缓存时,直接删除key,如果是因为数据新增和删除,可以add(key,value,score)或remove(key,value)

redis中会按照score分值升序排列map中的数据,一般的,score分值是sql语句的order by filedA的filedA的值,这样能保证数据一致性
但是这种方式也存在一定问题:

这个key缓存的value确实是热数据,但可能只有少数数据被频繁使用其余的可能根本就未被使用,比如数据有100页,实际可能只会用到前10页,这也会导致缓存空间的浪费,如果使用了redis虚拟内存,也会有一定影响

sql查询由原来的分页查询变成了不分页查询,缓存失效后,系统的处理能力较之前会有下降,尤其是对于大表.
____安分守己_
2017-08-18 · 超过10用户采纳过TA的回答
知道答主
回答量:51
采纳率:0%
帮助的人:15.8万
展开全部
redis的LRANGE命令,可以取列表指定范围内的元素
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
update152
2017-08-24 · 超过19用户采纳过TA的回答
知道答主
回答量:75
采纳率:0%
帮助的人:15.7万
展开全部
用redis zRevRange 和链表
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
杰克挂掉了
2017-08-21 · TA获得超过3785个赞
知道小有建树答主
回答量:641
采纳率:78%
帮助的人:68.6万
展开全部
马一个,我也要开始着手这个玩意儿了
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式