redis“万金油”的String,为什么不好用了?

本文探讨了Redis中String类型在存储大量键值对时的内存开销问题,指出String类型的元数据开销较大。文章通过一个图片存储系统的案例,展示了如何使用集合类型(如Hash)和压缩列表来节省内存,特别是通过二级编码方法实现单值键值对的存储,从而降低内存消耗。总结了String类型的内存消耗来源,并提供了优化方案。

从今天开始,我们就要进入“实践篇”了。接下来,我们会用5节课的时间学习“数据结构”。我会介绍节省内存开销以及保存和统计海量数据的数据类型及其底层数据结构,还会围绕典型的应用场景(例如地址位置查询、时间序列数据库读写和消息队列存取),跟你分享使用Redis的数据类型和module扩展功能来满足需求的具体方案。

今天,我们先了解下String类型的内存空间消耗问题,以及选择节省内存开销的数据类型的解决方案。

先跟你分享一个我曾经遇到的需求。

当时,我们要开发一个图片存储系统,要求这个系统能快速地记录图片ID和图片在存储系统中保存时的ID(可以直接叫作图片存储对象ID)。同时,还要能够根据图片ID快速查找到图片存储对象ID。

因为图片数量巨大,所以我们就用10位数来表示图片ID和图片存储对象ID,例如,图片ID为1101000051,它在存储系统中对应的ID号是3301000051。

photo_id: 1101000051
photo_obj_id: 3301000051

可以看到,图片ID和图片存储对象ID正好一一对应,是典型的“键-单值”模式。所谓的“单值”,就是指键值对中的值就是一个值,而不是一个集合,这和String类型提供的“一个键对应一个值的数据”的保存形式刚好契合。

而且,String类型可以保存二进制字节流,就像“万金油”一样,只要把数据转成二进制字节数组,就可以保存了。

所以,我们的第一个方案就是用String保存数据。我们把图片ID和图片存储对象ID分别作为键值对的key和value来保存,其中,图片存储对象ID用了String类型。

刚开始,我们保存了1亿张图片,大约用了6

### 使用云服务提供商的 Redis 服务 #### 优点 - **易于部署**:无需进行复杂的服务器配置和软件安装过程,只需在云平台上创建 Redis 实例,即可快速获取连接信息并开始使用。 - **高可用性**:云服务提供商通常提供高可用性保证,具备自动故障转移、数据备份等功能,能有效减少因硬件故障、网络问题等导致的服务中断时间。 - **可扩展性**:可以根据业务需求灵活调整 Redis 实例的规格和性能,如增加内存、带宽等,无需担心硬件资源的限制。 - **专业维护**:由云服务提供商负责 Redis 服务的日常维护、监控、安全防护等工作,可节省大量的运维成本和精力。 - **安全保障**:云服务提供商提供了多种安全防护措施,如网络隔离、访问控制、数据加密等,能有效保障 Redis 服务的安全性。 #### 缺点 - **成本较高**:使用云服务需要按照使用量付费,长期使用可能会产生较高的费用,尤其是在业务规模较大时。 - **数据控制权有限**:数据存储在云服务提供商的服务器上,可能会受到云服务提供商的政策、法规等限制,对数据的控制权相对较弱。 - **网络依赖**:需要通过网络连接到云服务提供商的 Redis 服务,网络延迟和稳定性可能会影响服务的性能。 ### 自己安装 Redis 服务 #### 优点 - **成本较低**:只需购买服务器硬件或使用虚拟机,一次性投入成本相对较低,适合预算有限的小型项目或个人开发者。 - **数据控制权高**:数据完全存储在自己的服务器上,可以根据需要进行灵活的管理和控制,满足特定的安全和合规要求。 - **定制性强**:可以根据业务需求对 Redis 服务进行定制化配置,如调整参数、优化性能等,以满足特定的业务场景。 #### 缺点 - **部署和维护复杂**:需要自行完成服务器的配置、Redis 软件的安装和配置、日常维护、监控等工作,对技术人员的要求较高,且需要投入大量的时间和精力。 - **高可用性和扩展性较差**:需要自行实现高可用性和扩展性方案,如搭建集群、进行数据备份等,技术难度较大,且成本较高。 - **安全风险**:需要自行负责服务器和 Redis 服务的安全防护,如网络隔离、访问控制、数据加密等,安全风险相对较高。 ### 示例代码 以下是使用 StackExchange.Redis 连接到云服务提供商的 Redis 服务和自己安装的 Redis 服务的示例代码: #### 连接到云服务提供商的 Redis 服务 ```csharp using StackExchange.Redis; // 连接到云服务提供商的 Redis 服务 ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("your-cloud-redis-server:6379,password=your-password"); IDatabase db = redis.GetDatabase(); // 设置键值对 db.StringSet("key", "value"); // 获取键值对 string value = db.StringGet("key"); ``` #### 连接到自己安装的 Redis 服务 ```csharp using StackExchange.Redis; // 连接到自己安装的 Redis 服务 ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost:6379"); IDatabase db = redis.GetDatabase(); // 设置键值对 db.StringSet("key", "value"); // 获取键值对 string value = db.StringGet("key"); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韩淼燃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值