在讲到应用hash还是string存储的抉择前,先理解Redis的hash和string构造。
以下材料引自老钱的Redis深度历险。
string
string和hash都是Redis的一种数据结构。string构造罕用来缓存用户信息,通常将用户信息结构体应用JSON序列化成字符串,而后将序列化后的字符串存入Redis进行缓存。
Redis的字符串是动静字符串,能够批改,内部结构相似于Java的ArrayList,采纳预调配冗余空间的形式来缩小内存的频繁调配。如上图锁实,外部为以后字符串理论调配的空间capacity,个别高于理论字符串长度len。应用的指令有set, get, mset, mget等
hash
Redis的hash相当于Java的HashMap,内部结构实现与HashMap统一,即数组+链表构造
不过Redis的hash的值只能是字符串,rehash形式不一样,为了进步性能,Redis保留新旧两个hash构造,采纳渐进式rehash策略,查问时会共事查问两个hash构造,在后续的定时工作中以及hash操作指令中,循序渐进将旧hash的内容迁徙到xinhash中,直至齐全取代旧hash。hash移除最初一个元素后会主动被删除,内存被回收。
后面说到string适宜存储用户信息,而hash构造也能够存储用户信息,不过是对每个字段独自存储,因而能够在查问时获取局部字段的信息,节俭网络流量。
因而就引出了这篇文章,存储构造体信息是用hash还是string?
以下信息出自StackOverflow Redis strings vs Redis hashes to represent JSON: efficiency?
I want to store a JSON payload into redis. There's really 2 ways I can do this:1. One using a simple string keys and values.key:user, value:payload (the entire JSON blob which can be 100-200 KB)SET user:1 payload2. Using hashesHSET user:1 username "someone"HSET user:1 location "NY"HSET user:1 bio "STRING WITH OVER 100 lines"Keep in mind that if I use a hash, the value length isn't predictable. They're not all short such as the bio example above.Which is more memory efficient? Using string keys and values, or using a hash?
该用户也是同样的疑难,因为值的长度是不确定的,所以不晓得采纳string还是hash存储更有效率
这个问题底下有个开发者答复的十分好,这里翻译进去供大家一起学习探讨,如果有更好的计划,欢送提出来 首先,答者倡议参考redis官网的内存优化的文章:https://redis.io/topics/memory-optimization
,用来了解官网的开发者是内存优化方面基于什么思考。
之后,答者列出了四个计划并给出了各个计划的利弊
1. 存储整个对象,其中JSON序列化过的字符串作为key
INCR id:usersSET user:{id} '{"name":"Fred","age":25}'SADD users {id}
- 劣势:能够认为是“最佳实际”,因为每个对象都是全个性的key,JSON解析特地块,尤其是一次性查问很多个字段的时候
- 劣势:如果只查问一个字段,速度就显得比较慢了
2. 在hash中存储每个对象的属性
INCR id:usersHMSET user:{id} name "Fred" age 25SADD users {id}
- 劣势:这也能够认为是最佳工夫。每个对象都是一个全个性的key。不须要解析JSON字符串
- 劣势:如果要查问对象的全副字段会比较慢。嵌套类型的对象(即对象外面还包着对象)无奈轻易存储
3. 将对象转化为JSON字符串,用hash构造存储
INCR id:usersHMSET users {id} '{"name":"Fred","age":25}'
这个计划能够仅用两个key,不须要很多key。然而没法对每个用户对象设置TTL(Time to Live,残余生存工夫),因为对象仅仅是hash中的一个字段,而不是全个性的key
- 劣势:JSON解析很快,尤其是一次查问多个字段时,对主key的命名空间净化更少
- 劣势:如果要存储很多对象,那么内存应用和计划1相当。当只须要查问一个字段时,会比计划2速度慢。答者不认为这是一个“最佳实际”
4. 存储对象的每个属性作为独自的key
INCR id:usersSET user:{id}:name "Fred"SET user:{id}:age 25SADD users {id}
依据下面的文章,即redis内存优化,这个计划不举荐(除非对象的属性须要专门设置TTL或者别的设置)
- 劣势:对象的属性是全特色key,对于利用来说比拟好解决
- 劣势:慢,内存耗费更大,不是一个“最佳实际”。对主key的命名空间有很大净化
总的来说,计划4是最不举荐的,计划1和计划2十分类似,也很常见。答者更举荐计划1,因为这个计划容许存储更简单的对象(也就是说对象能够有很多层嵌套)。计划3通常用在对命名空间比拟有要求的场景下,比如说不想要太多key,不关怀TTL等参数。
参考资料
《Redis深度历险》
https://juejin.im/book/5afc2e...
https://stackoverflow.com/que...
原文链接:https://blog.csdn.net/u010145...
版权申明:本文为CSDN博主「布鲁斯1990」的原创文章,遵循CC 4.0 BY-SA版权协定,转载请附上原文出处链接及本申明。
近期热文举荐:
1.1,000+ 道 Java面试题及答案整顿(2022最新版)
2.劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4.别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!
5.《Java开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞+转发哦!