Scala - Redis hgetAll 优化 by hscan
一.引言
Redis 实际使用过程中,由于 redis hgetAll 数据量过于大,导致线上 redis 进程堵塞,读取缓慢影响任务执行效率,改用 hscan 优化。
二.Case分析
1.hgetAll 为什么慢
hgetAll 获取指定 key 的全部 hash 结果,时间复杂度 O(n) ,hash 的 key 越多,当 kv 值不多时 hgetAll 非常好用,但是使用 hgetAll 获取的数据量越大,获取的性能越低。与之类似的是 hdel,随着 key 的增加,获取的时间并不是完全的线性增加,而是可能出现翻倍的情况。因此对于高并发的场景,要尽量避免在大数据上进行 hgetAll,hdel,emembers 等操作。
2.hscan 怎么代替
scan,hscan 是增量式迭代命令,通过游标进行分段式读取,负载压力从而不会堵塞 redis 线程,但是速度会慢于 hgetall。hscan 主要用到 ScanParams,通过 ScanParams.count() 方法可以设置每次迭代获取的数据量,假设hgetAll redis read峰值很高,正常值 200,那就可以设定 count(200)。还有一个参数是 SCAN_POINTER_START,该字符型变量标记当前获取的游标,当游标为"0"时,代表全部元素获取完毕。
Tips:
hscan 每次返回的结果可能存在重复,最后整合所有结果时需要自己去重
3.还有方法减小压力嘛
A.redis.dump
redis.dump(key) 可以获取对应元素序列化后的内容 Array[Byte],可以使用 redis 相同的序列化协议进行反序列化,从而避免在 redis 客户端执行序列化,缩短时间
B.拆分 key-value
将原始 HashMap 分布在多个 key 上,缩小每个 Hmap 的大小,整体的数据量变化不大
C.加机器
和拆分的思想类似,可以提高 redis 数量,通过 redis-pool 减轻单点 redis 的压力
D.数据量很大
转存 Hbase
三.hscan 实现代码
A.ScanParams 初始化每次迭代的数量,count 为迭代量
B.SCAN_POINTER_START 为计数游标,标记为"0"时代表全部迭代结束
C.scanResult.getResult() 返回 util.Map.Entry 接口,此接口为泛型,定义为Entry<K,V>,转换后存入 map 即可
def redisHScan(jedis: Jedis, key: String, count: Int = 100): mutable.HashMap[String, String] = {val infoMap = mutable.HashMap[String, String]()val scanParams = new ScanParams().count(count)var cur = redis.clients.jedis.ScanParams.SCAN_POINTER_STARTvar cycleIsFinished = falsewhile (!cycleIsFinished) {val scanResult = jedis.hscan(key, cur, scanParams)val result = scanResult.getResult.asScala.map(entry => (entry.getKey, entry.getValue))infoMap ++= resultcur = scanResult.getStringCursorif (cur == "0") cycleIsFinished = true}infoMap}val scanMap = redisHScan(redis, key, 100000)
下面对一个 55w+ key 的 HashMap 进行读取测试:
四.总结
hgetAll 获取大 key 时可以用 hscan 替代,但也需要注意 count 的大小和 Redis 具体的压力,除此之外还有一点需要注意,由于 hscan 是迭代获取执行,所以可能存在数据不一致的情况,获取靠前的数据时,靠后的数据已被修改,这时候会出现先到的数据为老数据,后到的数据为新数据的情况。
Scala - Redis hgetAll 优化 by hscan相关推荐
- 第四课 实战go语言改造php仿优酷-Redis改造优化接口
第四课 实战go语言改造php仿优酷-Redis改造优化接口 tags: Beego 慕课网 categories: redis 文章目录 第四课 实战go语言改造php仿优酷-Redis改造优化接口 ...
- Redis——性能优化与技术选型原理
摘要 redis的拥有众多优点,但是的技术有利有弊,所以只有在redis最擅长的场景中才能让redis的作用发挥到最大的作用.同样的redis一样存在很多优化和改进的点. 一.Redis的性能测试 技 ...
- Redis存储优化--小对象压缩
小对象压缩 Redis是一种内存数据库,内存是计算机中一种比较宝贵的资源,如果我们不注意节约,Redis很可能出现内存不足,最终导致崩溃.Redis为了优化数据结构的内存占用,增加了非常多的优化点,这 ...
- .net Redis缓存优化提高加载速度和服务器性能(二)
上文详细测试了每次都读取数据库的接口和通过缓存读取接口的性能对比 这里我们就准备实际简介肿么将原来的数据库加上Redis缓存优化部分接口 1.下载Redis和Redis视图管理工具 点击下载 提取码: ...
- 微博计数:从关系服务到访问计数, Redis 持续优化支撑万亿级访问(含 PPT)
关注"数据和云",精彩不容错过 编者按:本文由刘东辉向高可用架构供稿,基于在 Redis 用户交流会上的演讲内容整理.这是一篇历史文章,但是仍然可以帮助我们理解 Redis 的应用 ...
- Redis配置优化和使用
一.redis编码使用优化 1.尽量使用短的key 当然在精简的同时,不要为了key的"见名知意".对于value有些也可精简,比如性别使用0.1. 2.避免使用keys * ke ...
- java lambda 画蛇添足_技术史上的画蛇添足: Redis HGETALL 排序问题
一个系列 在技术史上,有很多彼时的 bug 历经岁月锤炼最后化身 feature 的事儿发生. 在阅读一些热门开源框架代码时,经常能发现狗血的.难以置信的.童真的.幽默的.这也能写的,代码. 以上这些 ...
- redis学习笔记(5)之redis内存优化
redis内存优化 配置优化 Linux 配置优化 Redis配置优化 缩减键值对象 命令处理 缓存淘汰优化 动态改配置命令 设置最大内存 设置淘汰策略 内存淘汰策略 如何选择淘汰策略 内容来源为六星 ...
- Redis BigKey优化与使用方式
一.什么是BigKey 在Redis中,一个字符串最大512MB,一个二级数据结构(例如hash.list.set.zset)可以存储大约40亿个(2^32-1)个元素,但实际上中如果下面两种情况,我 ...
- 首长,Redis性能优化十三条军规立好了,请过目~
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 前言 Redis作为高性能的内存数据库,在大数据量的情况下 ...
最新文章
- java下输出中文的一点研究
- Delphi XE2 之 FireMonkey 入门(35) - 控件基础: TFmxObject: 其它
- PinPoint分布式全链路监控
- android edittext 不可编辑
- Remove Extra One(思维)
- 三全食品:信息化建设狂飙突进的六年
- 项目支持规划标准文档编写要点
- 【笔记】高效率但却没用过的一些numpy函数
- 从计算机向外接硬盘传输照片,如何将iPhone照片移动到外部硬盘驱动器
- 盘点软件开发中那些有趣的边际效应
- 测序数据量,测序深度和测序覆盖度
- php 全等 性能,在PHP中,相等(==)和全等(===)的含义是一样的。
- 监控神器普罗米修斯Prometheus安装配置
- 职高高一计算机知识点,职高高一上半学期所有数学公式
- 2018年90后薪资报告出炉:看看你被甩了多远!
- Adobe Acrobat Reader DC 2019 (19.8)
- 福布斯:雅虎代理权争夺战背后的十大问题
- hdoj 1869 六度分离
- 思维导图---SQL Queries for Mere Mortals (1 - 4章)
- JSch 实际使用中的问题
热门文章
- 技术分解:光纤传感在交通监控中的应用
- SVN分支合并冲突解决
- bp神经网络数据预测实例,bp网络神经预测模型
- Datasqueeze v2.0.7
- java ojdbc14 查询数据表,Oracle10g JDBC ojdbc14 DATE类型hibernate查询时分秒问题
- 代码走查(Code Review)25条疑问
- matlab 颜色代码 大全_空客 | 红、绿、蓝、白,各类颜色代码的含义
- Confluence 会议记录(Meeting Notes)蓝图
- 一文读懂TOGAF企业架构
- jdbcTemplate测试报错:没有合适的驱动