关于java:Redis-存储结构体信息选-hash-还是string

32次阅读

共计 2599 个字符,预计需要花费 7 分钟才能阅读完成。

在讲到应用 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 payload

2. Using hashes

HSET 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:users
SET user:{id} '{"name":"Fred","age":25}'
SADD users {id}
  • 劣势:能够认为是“最佳实际”,因为每个对象都是全个性的 key,JSON 解析特地块,尤其是一次性查问很多个字段的时候
  • 劣势:如果只查问一个字段,速度就显得比较慢了

2. 在 hash 中存储每个对象的属性

INCR id:users
HMSET user:{id} name "Fred" age 25
SADD users {id}
  • 劣势:这也能够认为是最佳工夫。每个对象都是一个全个性的 key。不须要解析 JSON 字符串
  • 劣势:如果要查问对象的全副字段会比较慢。嵌套类型的对象(即对象外面还包着对象)无奈轻易存储

3. 将对象转化为 JSON 字符串,用 hash 构造存储

INCR id:users
HMSET users {id} '{"name":"Fred","age":25}'

这个计划能够仅用两个 key,不须要很多 key。然而没法对每个用户对象设置 TTL(Time to Live,残余生存工夫),因为对象仅仅是 hash 中的一个字段,而不是全个性的 key

  • 劣势:JSON 解析很快,尤其是一次查问多个字段时,对主 key 的命名空间净化更少
  • 劣势:如果要存储很多对象,那么内存应用和计划 1 相当。当只须要查问一个字段时,会比计划 2 速度慢。答者不认为这是一个“最佳实际”

4. 存储对象的每个属性作为独自的 key

INCR id:users
SET user:{id}:name "Fred"
SET user:{id}:age 25
SADD 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 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0