redis系列文章目录

  • Redis 利用Hash存储节约内存
  • 使用spring-data-redis实现incr自增
  • Redis学习笔记(九)redis实现时时直播列表缓存,支持分页[热点数据存储]
  • Redis学习笔记(八)redis之lua脚本学习
  • Redis学习笔记(七)jedis超时重试机制注意事项
  • Redis学习笔记(六)redis实现分布式锁
  • Redis学习笔记(五)jedis(JedisCluster)操作Redis集群 redis-cluster
  • redis学习笔记(四)缓存与数据库一致性问题
  • redis学习笔记(三)数据淘汰策略
  • redis学习笔记(二)JedisCluster + redis 3.2.5集群
  • redis学习笔记(一)redis3.2.5集群安装与测试

Instagram可以说是网拍App的始祖级应用,也是当前最火热的拍照App之一,Instagram的照片数量已经达到3亿,而在Instagram里,我们需要知道每一张照片的作者是谁,下面就是Instagram团队如何使用Redis来解决这个问题并进行内存优化的。

首先,这个通过图片ID反查用户UID的应用有以下几点需求:

1. 查询速度要足够快
2. 数据要能全部放到内存里,最好是一台EC2的 high-memory 机型就能存储(17GB或者34GB的,68GB的太浪费了)   
3. 要合适Instagram现有的架构(Instagram对Redis有一定的使用经验,比如这个应用)   
4. 支持持久化,这样在服务器重启后不需要再预热

Instagram的开发者首先否定了数据库存储的方案,他们保持了KISS原则(Keep It Simple and Stupid),因为这个应用根本用不到数据库的update功能,事务功能和关联查询等等牛X功能,所以不必为这些用不到的功能去选择维护一个数据库。

于是他们选择了Redis,Redis是一个支持持久化的内存数据库,所有的数据都被存储在内存中(忘掉VM吧),而最简单的实现就是使用Redis的String结构来做一个key-value存储就行了。像这样:

SET media:1155315 939   
GET media:1155315   
> 939

其中1155315是图片ID,939是用户ID,我们将每一张图片ID为作key,用户uid作为value来存成key-value对。然后他们进行了测试,将数据按上面的方法存储,1,000,000数据会用掉70MB内存,300,000,000张照片就会用掉21GB的内存。对比预算的17GB还是超支了。
其实这里我们可以看到一个优化,我们可以将key值存成纯数字,经过实验,内存占用会降到50MB,总的内存占用是15GB,是满足需求的,但是Instagram后面的改进任然有必要。

于是Instagram的开发者向Redis的开发者之一Pieter Noordhuis询问优化方案,得到的回复是使用Hash结构。具体的做法就是将数据分段,每一段使用一个Hash结构存储,由于Hash结构会在单个Hash元素在不足一定数量时进行压缩存储,所以可以大量节约内存。这一点在上面的String结构里是不存在的。而这个一定数量是由配置文件中的hash-zipmap-max-entries参数来控制的。经过开发者们的实验,将hash-zipmap-max-entries设置为1000时,性能比较好,超过1000后HSET命令就会导致CPU消耗变得非常大。

于是他们改变了方案,将数据存成如下结构:

HSET "mediabucket:1155" "1155315" "939"   
HGET "mediabucket:1155" "1155315"   
> "939"

通过取7位的图片ID的前四位为Hash结构的key值,保证了每个Hash内部只包含3位的key,也就是1000个。
再做一次实验,结果是每1,000,000个key只消耗了16MB的内存。总内存使用也降到了5GB,满足了应用需求。
同样的,这里我们还是可以再进行优化,首先是将Hash结构的key值变成纯数字,其次是将Hash结构中的key值变成三位数,如下所示。经过实验,内存占用量会降到10MB,总内存占用为3GB

HSET "1155" "315" "939"   
HGET "1155" "315"   
> "939"

优化无止境,只要肯琢磨。希望你在使用存储产品时也能如此爱惜内存。

附上String和Hash存储的比较
存储对象User String存储方式:

SET media:1155315 939
GET media:1155315
> 939

String结构存储该对象

存储量 使用内存(KB) 使用时间(毫秒) 使用cpu
100 30.72 2983
100 30.72 1224
100 40.96 2638
100 40.96 1543
100 40.96 3335
4487 1934.62 21760 0.05
4487 1934.59 21732 0.05

Hash结构存储该对象

HSET "mediabucket:1155" "1155315" "939"
HGET "mediabucket:1155" "1155315"
> "939"

存储量 使用内存(KB) 使用时间(毫秒) 使用cpu
100 367.76 454
100 37.37 458
100 50.50 461
100 40.44 467
100 35.50 489
4487 1805.1 21729 0.06
4487 1844.23 21712 0.05
4487 1844.23 21778

Hash结构继续优化

类似

HSET "1155" "315" "939"
HGET "1155" "315"
> "939"

存储量 使用内存(KB) 使用时间(毫秒) 使用cpu
100 367.76 454
100 37.37 458
100 50.50 461
100 40.44 467
100 35.50 489
4487 1803.29 21879 0.06
4487 1842.43 21931 0.05

原文地址:http://blog.panaihua.com/archives/326?utm_source=tuicool&utm_medium=referral

Redis 利用Hash存储节约内存相关推荐

  1. redis java hash存储对象

    前言: redis缓存的hash数据类型可以让用户将多个key-value对存储到一个redis键里,适合用来存储对象. 本文介绍在spring-redis环境上使用RedisTemplate操作对象 ...

  2. 节约内存:Instagram的Redis实践(转)

    一.问题: 数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求. 二.解决方案: 1.通过高速服务器Cache缓存数据库数据 2.内存数据库 三.主流解Cache和数据库对比: 从以上 ...

  3. redis中对象存储内存占用预估和相关对象

    redis中数据类型的使用,并发问题,list重复插入问题,redis使用实例-简单消息队列和排名统计_深山猿的博客-CSDN博客_redis 不重复的list java对象应该存成string还是m ...

  4. Redis数据结构Hash应用场景-存储商品、购物车、淘宝短链接、分布式Session、用户注册、发微博功能

    Hash应用场景 Hash Hash应用场景 redis存储java对象常用String,那为什么还要用hash来存储? SpringBoot+redis+hash存储商品数据 短链接 场景1:淘宝短 ...

  5. Redis Hash存储对象

    Hash 哈希表是一种数据结构,而Redis Hash也是采用哈希表来实现的存储. Hash命令 1.赋值(hset key filed value) 127.0.0.1:6379> hset ...

  6. 阿里实现Redis亿级存储的方案

    1 需求背景 该应用场景为DMP缓存存储需求,DMP需要管理非常多的第三方id数据,其中包括各媒体cookie与自身cookie(以下统称supperid)的mapping关系,还包括了supperi ...

  7. 聊一聊 Redis 数据内部存储使用到的数据结构

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 R ...

  8. java使用xml存储数据_聊一聊 Redis 数据内部存储使用到的数据结构

    Redis 数据库虽然一直都在使用,但是对其内部存储结构之类的,都没有研究过,哪怕是面试的时候都没有准备过这方面的东西.最近在看一门网课,里面有讲到过这一块的内容,结合了<Redis 设计与实现 ...

  9. php session存到redis,php Session存储到Redis的方法

    php Session存储到Redis的方法 当然要写先安装php的扩展,可参考这篇文章:Redis及PHP扩展安装修改php.ini的设置 复制代码 代码如下: session.save_handl ...

最新文章

  1. 原型模式(ProtoType) - Java里的对象复制
  2. JMeter场景设置叙述
  3. Liunx 命令大全
  4. 论文浅尝 - IJCAI2020 | Mucko:基于事实的多层跨模态知识推理视觉问答
  5. JAVA基础知识之Collections工具类
  6. ajax保持会话,Ajax请求会话过期处理(JS)
  7. spring揭秘_「死磕 Spring」—– IOC 之深入理解 Spring IoC
  8. delphi 的GetTickCount计时用法缺陷及管制
  9. python大数据分析入门实例-记一次小机器的 Python 大数据分析
  10. 上级对下级用通知合适吗_【判断题】通知只能作为下行文使用,下级对上级不能使用通知。 ( )...
  11. 光照贴图(个人笔记)
  12. 如何修改搜索关键词内容
  13. 【人工智能项目】LSTM实现数据预测分类实验
  14. python批量修改及创建txt
  15. NETBASE DAY05(04):设计大型网络拓扑图
  16. K近邻(k-Nearest Neighbor,KNN)算法,一种基于实例的学习方法
  17. python3抓取杭州房价信息
  18. matlab 系统稳态误差,MATLAB实验报告3
  19. 智慧农业解决方案-最新全套文件
  20. 微信企业转账JAVA版(包括:1,转账个人零钱;2,转账个人银行卡;3,微信官网的SDK3.0.9存在的支付问题)

热门文章

  1. configure: error: Curl library not found
  2. 简要说明类的结构java_【深入Java虚拟机】之二:Class类文件结构
  3. 春晚营销大战枪声响起,快手度小满各怀心思
  4. 计算机网络ip数据包标志df,计算机网络(三)--IP数据报格式
  5. 大数据产业驱动中国经济新增长
  6. 谈谈SQL数据库中滥用临时表、排序的解决方案优化(举例:汉字转拼音函数)
  7. 求12个月的挣得值在c语言中,施工项目进度控制-1.ppt
  8. python 字符视频_Python20行代码实现视频字符化
  9. C语言每日一练(六)——华为机试
  10. 20145209 《信息安全系统设计基础》第13周学习总结