浅谈redis key值内存消耗以及性能影响

 更新时间:2021年2月7日 19:36  点击:3529

一、redis key数量为1千万时。

存储value为"0",比较小。如果value较大,则存储内存会增多

redis key数量为一千万时,使用了865M的内存。

# Keyspace
db0:keys=11100111,expires=0,avg_ttl=0
内存使用情况
# Memory
used_memory:907730088
used_memory_human:865.68M
used_memory_rss:979476480
used_memory_rss_human:934.10M
used_memory_peak:1258244232
used_memory_peak_human:1.17G
used_memory_peak_perc:72.14%
used_memory_overhead:580102896
used_memory_startup:765664
used_memory_dataset:327627192
used_memory_dataset_perc:36.12%
total_system_memory:8365256704
total_system_memory_human:7.79G
used_memory_lua:37888
used_memory_lua_human:37.00K

二、redis key数量为1千5百万时。

redis key数量为一千五百万时,使用了1.13G的内存。

# Keyspace
db0:keys=15100031,expires=0,avg_ttl=0
# Memory
used_memory:1211733288
used_memory_human:1.13G
used_memory_rss:1247817728
used_memory_rss_human:1.16G
used_memory_peak:1258244232
used_memory_peak_human:1.17G
used_memory_peak_perc:96.30%
used_memory_overhead:740104496
used_memory_startup:765664
used_memory_dataset:471628792
used_memory_dataset_perc:38.95%
total_system_memory:8365256704
total_system_memory_human:7.79G
used_memory_lua:37888
used_memory_lua_human:37.00K

三、redis key数量为一千五百万时压测

redis-benchmark -h 127.0.0.1 -p 6379 -c 1000 -n 10000 -t get -q
GET: 34364.26 requests per second

四、使用map将key值打散存储,小key为1千五百万

使用hset存储打散为1024个key时,存储大小为921M,比直接存储节省了200M。

# Memory
used_memory:966758968
used_memory_human:921.97M
used_memory_rss:1002913792
used_memory_rss_human:956.45M
used_memory_peak:1749456304
used_memory_peak_human:1.63G
used_memory_peak_perc:55.26%
used_memory_overhead:1929880
used_memory_startup:765664
used_memory_dataset:964829088
used_memory_dataset_perc:99.88%
total_system_memory:8365256704
total_system_memory_human:7.79G
used_memory_lua:37888
used_memory_lua_human:37.00K 
# Keyspace
db0:keys=1024,expires=0,avg_ttl=0

五、使用hset存储打散为256个key

存储大小为1.09G,比直接存储小了80M。

used_memory:1170356864
used_memory_human:1.09G
used_memory_rss:1190223872
used_memory_rss_human:1.11G
used_memory_peak:1749456304
used_memory_peak_human:1.63G
used_memory_peak_perc:66.90%
used_memory_overhead:33759246
used_memory_startup:765664
used_memory_dataset:1136597618
used_memory_dataset_perc:97.18%
total_system_memory:8365256704
total_system_memory_human:7.79G

六、进行hget的压力测试

 redis-benchmark -h 127.0.0.1 -p 6379 -c 1000 -n 10000 -t hget myhash rand_int rand_int rand_int 
====== myhash rand_int rand_int rand_int ======
 10000 requests completed in 0.22 seconds
 1000 parallel clients
 3 bytes payload
 keep alive: 1 
46511.63 requests per second

七、总结

可见,当存储量特别大的时候,可以将key进行hash分散处理,可以减少存储内存。

并且当key的数量很大的时候,redis取值性能还是很高的。

补充:Redis 单key值过大 优化方式

Redis使用过程中经常会有各种大key的情况, 比如:

1: 单个简单的key存储的value很大

2: hash, set,zset,list 中存储过多的元素(以万为单位)

由于redis是单线程运行的,如果一次操作的value很大会对整个redis的响应时间造成负面影响,所以,业务上能拆则拆,下面举几个典型的分拆方案。

1、单个简单的key存储的value很大

1.1、 改对象需要每次都整存整取

可以尝试将对象分拆成几个key-value, 使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个redis实例中,降低对单个redis的IO影响;

1.2、该对象每次只需要存取部分数据

可以像第一种做法一样,分拆成几个key-value, 也可以将这个存储在一个hash中,每个field代表一个具体的属性,使用hget,hmget来获取部分的value,使用hset,hmset来更新部分属性

2、 hash, set,zset,list 中存储过多的元素

类似于场景一种的第一个做法,可以将这些元素分拆。

以hash为例,原先的正常存取流程是 hget(hashKey, field) ; hset(hashKey, field, value)

现在,固定一个桶的数量,比如 10000, 每次存取的时候,先在本地计算field的hash值,模除 10000, 确定了该field落在哪个key上。

newHashKey = hashKey + (*hash*(field) % 10000);  
hset (newHashKey, field, value) ; 
hget(newHashKey, field)

set, zset, list 也可以类似上述做法.

但有些不适合的场景,比如,要保证 lpop 的数据的确是最早push到list中去的,这个就需要一些附加的属性,或者是在 key的拼接上做一些工作(比如list按照时间来分拆)。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。如有错误或未考虑完全的地方,望不吝赐教。

[!--infotagslink--]

相关文章

  • @CacheEvict 清除多个key的实现方式

    这篇文章主要介绍了@CacheEvict 清除多个key的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-13
  • 详解如何清理redis集群的所有数据

    这篇文章主要介绍了详解如何清理redis集群的所有数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-18
  • Redis连接池配置及初始化实现

    这篇文章主要介绍了Redis连接池配置及初始化实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-29
  • 详解redis desktop manager安装及连接方式

    这篇文章主要介绍了redis desktop manager安装及连接方式,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-15
  • 浅谈redis key值内存消耗以及性能影响

    这篇文章主要介绍了浅谈redis key值内存消耗以及性能影响,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-07
  • @Cacheable 拼接key的操作

    这篇文章主要介绍了@Cacheable 拼接key的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-13
  • lua读取redis数据的null判断示例代码

    最近在工作中遇到了一个问题,通过查找相关资料才得知原因是因为返回结果的问题,下面这篇文章主要给大家介绍了关于lua读取redis数据的null判断的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下...2020-06-30
  • 详解分析MySQL8.0的内存消耗

    这篇文章主要介绍了详解分析MySQL8.0的内存消耗,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下...2021-03-23
  • SpringBoot集成Redis实现消息队列的方法

    这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
  • js遍历json的key和value的实例

    下面小编就为大家带来一篇js遍历json的key和value的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2017-01-26
  • redis setIfAbsent和setnx的区别与使用说明

    这篇文章主要介绍了redis setIfAbsent和setnx的区别与使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-04
  • uniapp微信小程序:key失效的解决方法

    这篇文章主要介绍了uniapp微信小程序:key失效的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-20
  • Redis的Expire与Setex区别说明

    这篇文章主要介绍了Redis的Expire与Setex区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-15
  • 解决使用OpenCV中的imread()内存报错问题

    这篇文章主要介绍了解决使用OpenCV中的imread()内存报错问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • 查看Redis内存信息的命令

    Redis 是一个开源、高性能的Key-Value数据库,被广泛应用在服务器各种场景中。本文介绍几个查看Redis内存信息的命令,包括常用的info memory、info keyspace、bigkeys等。...2021-01-15
  • 替换json对象中的key最佳方案

    本文给大家介绍如何替换json对象中的key,通过实例代码给大家介绍key的替换方法,代码也很简单,需要的朋友参考下吧...2021-06-02
  • 解决tensorflow训练时内存持续增加并占满的问题

    今天小编就为大家分享一篇解决tensorflow训练时内存持续增加并占满的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-22
  • Redis的持久化方案详解

    在本篇文章里小编给大家整理的是关于Redis的持久化方案详解,有兴趣的朋友们可以参考下。...2021-01-15
  • @CacheEvict + redis实现批量删除缓存

    这篇文章主要介绍了@CacheEvict + redis实现批量删除缓存方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-12
  • JAVA中 redisTemplate 和 jedis的配合使用操作

    这篇文章主要介绍了JAVA中 redisTemplate 和 jedis的配合使用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-13