首页 > 编程知识 正文

Scala Redis hgetAll 优化 by hscan

时间:2023-05-03 23:11:40 阅读:178908 作者:2010

一、引言在Redis的实际使用中,Redis hgetAll数据量过大,导致在线redis进程阻塞,读取缓慢,影响了任务的执行效率,切换到了hscan优化。

Case分析1.hgetAll为什么很慢

hgetAll获取指定密钥的所有散列结果,时间复杂度o(n )、散列的密钥越多,在kv值越小时,hgetAll就非常有用,但是使用hgetAll获取的数据量越多,获取性能就越低。 与此相似的是hdel,随着key的增加,获取时间可能是两倍,而不是完全的线性增加。 因此,在高并发的场景中,请尽量避免在大数据上进行hgetAll、hdel、emembers等操作。

2.hscan如何替代

scan、hscan是增量迭代指令,通过用光标逐步读取来施加压力以避免阻塞redis线程,但速度比hgetall慢。 hscan主要使用扫描参数。 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界面。 此接口是通用的,定义为EntryK,v。 转换后存储在map里就可以了

defRedisHscan(Jedis3360Jedis,key: String,count: Int=100 ) :mutable.Hashmap(string, string )={valinfable} String] () val scanParams=new ScanParams ).count ) var cur=redis.clients.jedis.scan params.scan _ point TTS cycleisfinished scanParams ) valresult=scanresult.get result.as Scala.ma acala entry.getvalue () info map=result cur=scanresult.gett e ) e } infoMap } ) ) ) ) ) ) 65 valscanmap=RedisHscan(Redis、key、100000 )以下,对55w key的HashMap进行读取测试:

四.总结

hgetAll获取大密钥时可以用hscan代替,但也需要注意计数的大小和Redis的具体压力。 除此之外还需要注意。 因为hscan是反复获取执行,所以数据可能不一致。 获取上一个数据时,后面的数据已更改。 此时,前面的数据是旧数据,后面的数据是新数据。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。