存储在Redis中的数据多大比较合适
存储在Redis中的数据多大比较合适
- 背景
- 过大的数据对 Redis 的影响
- 『过大』的定义是什么
- 结论
背景
本文是工作中应对一个实际业务场景的调研总结过程。在使用 redis 作为数据缓存的时候,一个 key 里面需要存储许多个 map 结构。
缓存需要序列化后存储在redis,这时候就出现了两种方案:
将多个map结构分开序列化,N 个 map N个 key:map1:{“foo”:“bar”}; map2: {“foo”:“bar”}… mapN:{“foo”:“bar”},好处是可以对不同 map 增量更新到redis。
将所有map整体序列化为一个大key: cache: “{“map1”:{“foo”:“bar”}… “mapN”:{“foo”:“bar”}”,好处是从 redis 读取到数据的时候,反序列化要比方案1快。
过大的数据对 Redis 的影响
哪到底选哪个方案呢?这两个方案对 redis 的影响如何呢?万事不决先 google。
首先看到 Redis 官方的说法是:『A String value can be at max 512 Megabytes in length.』。当然我们不能这么任性的真的扔这么大的数据进去,还觉得没问题。过大的 key 和 value 有两个问题:
Redis 是一个内存数据库,如果容量过大的 key 和 value 首先会导致服务器中的内存碎片。这会影响 Redis 的内存分配的效率,进一步导致内存的使用率下降。
容量过大的 key 和 value 还有这样几个影响:
a. 这些过大的数据需要更多的时间去传输数据,对网络缓存、带宽都有影响
b. 过大的数据传输可能会导致其他的请求超时:
假设客户端设置的超时时间是 1 秒。如果应用同时请求 ‘A’ 和 ‘B’ 两个 key。通常我们会使用 pipelining 的方法,这时 A 和 B 会逐个等待服务器对它们的响应。如果 A 的响应数据过大,它可能会吃掉其他请求的超时时间。如下图例子,如果 A 的响应数据过大,它会吃掉其他请求的超时时间
c. 如果是经常访问的数据,以上的影响会更加经常发生。
所以当 key 和 value 过大的时候,可能更需要优化数据结构,将 key 和 value 的值都变小。
『过大』的定义是什么
然而到底多大的 key 和 value 算大?我们上面描述的两种方案到底哪个好些?
这个时候就需要使用一些性能测试工具来评估一下实际的影响,恰好 Redis 有官方的 redis-benchmark工具。它类似 Apache 的 ab测试。
redis-benchmark 使用示例:
redis-benchmark -n 1000000 -t set,get -P 16 -qSET: 718390.81 requests per secondGET: 864304.25 requests per second
回到对应到上面说的两个方案,使用 SCRIPT LOAD 命令,利用 lua 脚本构造我们想要的数据。这里使用 10000 次操作,每100次一个pipeline 命令提交。
方案1,多个map分别序列化后存储:
redis-benchmark -n 10000 -P 100 -q SCRIPT LOAD "local bulk = {}; local s = '{\'foo\':\'bar\',\'foo1\':\'bar1\',\'foo2\':\'bar2\',\'foo3\':\'bar3\'}'; for i=0,10,1 do bulk[i] = s; end; redis.call('HMSET', 'foo', unpack(bulk));"结果:> 370370.38 requests per second
方案2,一个大string
redis-benchmark -n 10000 -P 100 -q SCRIPT LOAD "local plain = '' local s = '{\'foo\':\'bar\',\'foo1\':\'bar1\',\'foo2\':\'bar2\',\'foo3\':\'bar3\'}'; for i=0,10,1 do plain= plain..s; end; redis.call('HMSET', 'foo', 'cache', plain);"结果:> 208333.33 requests per second
可以看到,我们开头提到的业务场景下,方案1要快了不少。
那对于一般的场景结论是什么呢?到底什么时候需要拆分,什么时候用一个大的序列化 string 节约CPU资源呢?
结论
建议是大于 50k 的数据,就优先选择拆分吧。具体情况可以结合上面的流程,逐个分析:
- redis 本身剩余存储空间够吗?
- 这类数据频率大不大,带宽和超时会是问题吗?
- 用redis-benchmark跑一下实际业务场景,看性能是否满足需求。
本文是搬运我自己博客到 CSDN 的第一篇,原文点此。
存储在Redis中的数据多大比较合适相关推荐
- 使用Hive或Impala执行SQL语句,对存储在HBase中的数据操作
https://www.zybuluo.com/aitanjupt/note/209941 使用Hive或Impala执行SQL语句,对存储在HBase中的数据操作 〇.摘要 一.基础环境 二.数据存 ...
- [转载] python怎么获取redis中的数据_python操作redis数据库
参考链接: 使用Python在Selenium中进行非阻塞等待 3.redis基本命令 String set(name, value, ex=None, px=None, nx=False, xx=F ...
- 【Redis系列】面试官:Redis中的数据已经过期,为什么还占用这内存?
如果有面试官问Redis中的数据已经过期为什么还占用这内存? 它是因为Redis本身的过期策略和缓存淘汰机制所导致的. 说说Redis的过期策略和缓存淘汰机制 先来说说Redis的过期策略,Redis ...
- C语言:使用冒泡算法将数组中的数据从大到小进行排序
/*使用冒泡算法将数组中的数据从大到小进行排序*/ #include<stdio.h> #define N 5 int main() {int a[N];int i,j,t;printf( ...
- 将list对象存储进redis中去
如何将list对象存储进redis中去 如何将list对象存储进redis中去 将list转成字符串对象 从redis中获取json字符串并将其放入到list集合中 如何将list对象存储进redis ...
- 【译】在Android中保护数据-加密大数据
目录 按键大小 该怎么办 默认提供者 对称键 按键包装 使用范例 下一步是什么 安全提示 按键大小 到目前为止,我们已经尝试加密小的" Hello World"消息.让我们尝试加密 ...
- hbase中为何不能向表中插入数据_大数据HBase理论实操面试题
1.HBase的特点是什么? 1)大:一个表可以有数十亿行,上百万列: 2)无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列: 3)面向列: ...
- android 读取内部存储文件格式,Android中的数据储存之文件存储
当我们在使用各种程序时,其实际上是在和各种数据打交道,当我们聊QQ,刷微博,看新闻,其实都是在和里面的数据交互 例如在聊天时发出的消息,以及在登录时输入的账号密码,其实都是瞬时数据,那什么是瞬时数据呢 ...
- redis 清空db下_如何清空redis中的数据
Redis Flushall 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key ). 语法 redis Flushall 命令基本语法如下:redis 127.0.0.1:63 ...
最新文章
- Android Studio打包生成APK
- 别把你的目光停留在周围
- 人人出售56不亏:三方得利
- 比較++和+的运算符优先级
- Java的值传递和引用值传递的区别
- C#基础|面向对象之多态
- Python采集知乎小姐姐图片,打造颜颜值排行榜!
- 新模型SkipNet在ImageNet分类任务大放光彩!优化损失函数!
- Qt调用jrtplib实现单播、多播和广播
- Linux制作补丁与打补丁简单用法
- 三子棋游戏(C语言实现)
- 拟人拟物法求解不等圆Packing问题
- 2.数据分析-面板数据变系数模型
- Scala REPL的使用
- CSAPP Lab2
- 【解决方案】Ubuntu设置Matlab桌面启动快捷方式
- 腾讯 地图 机器学习岗 春招实习123面(猝)
- MATLAB GUI设计 多个选项卡/子页面
- 安装Node-sass的时候,报ensuring that file exists: C:\Python27\python.exe
- 透明漂亮的桌面天气预报工具-中国农历天气预报1.6.1