redis的hscan和hgetall区别?

这两个都是取所有数据,hscan是迭代式的一次取几个,一次取几个,直到取完为止;
hgetall是一次性取所有;
我简单的测试了1万条hash,10万条hash,发现hgetall是比hscan更快的;

那么问题来了,hscan的应用场景在哪里?

六月的风
Junwind
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 7
sane

阻塞和非阻塞的区别

3年前 评论

hscan 是迭代式的一次取几个,一次取几个,直到取完为止; hgetall 是一次性取所有;

占用内存不一样吧,可以对照 Eloquent 的 User::cursor()User::get() 理解

3年前 评论

就在下班前处理的一个 BUG,一个简单的业务逻辑:

记录帖子的浏览量,当一个帖子被浏览后,先放入 Redis List,然后再用定时任务每一个小时把 List 中的数据取出来lrange <key> 0 -1 这个方法就跟 hgetall 有点儿类似了,就是把所有的值都拿出来,然后再在代码层面把数据聚合后落存数据库中去,然后再 del 这个 key

结果,有一个时间段,访问量暴增,Redis 中记录了很多数据,导致这个 key 的成员增多,在使用 lrange <key> 0 -1 查的时候,导致了 OOM (超出 PHP 的执行内存限制),进而导致后面的业务没有继续下去,自然后面的 del <key> 也就没有执行到,在经过一天的失败后,通过服务器报警得知,上去一看,这个 List 已经有 3 亿个 Item。


试想一下,如果在业务中,不是使用的 lrange <key> 0 -1 而是类似于分页的方式 lrange <key> ($page - 1) * 1000 $limit 的方式去拿数据(类似于 hscan),那么就不可能会出现 OOM ,导致一天的数据都阻塞在 Redis 中,形成这么一个有 3 亿个 Item 的 List,若不是及时发现了(其实也不及时了),就有可能最终导致 Redis 挂掉了。

3年前 评论
Junwind (楼主) 3年前
Rache1 (作者) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!