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

1.M emcached 内存Key-Value Cache

  1. Redis 内存数据库

四,节约内存:Instagram的Redis实践

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

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

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

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还是超支了。

(NoSQLFan:其实这里我们可以看到一个优化点,我们可以将key值前面相同的media去掉,只存数字,这样key的长度就减少了,减少key值对内存的开销【注:Redis的key值不会做字符串到数字的转换,所以这里节省的,仅仅是media:这6个字节的开销】。经过实验,内存占用会降到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,满足了应用需求。

(NoSQLFan:同样的,这里我们还是可以再进行优化,首先是将Hash结构的key值变成纯数字,这样key长度减少了12个字节,其次是将Hash结构中的subkey值变成三位数,这又减少了4个字节的开销,如下所示。经过实验,内存占用量会降到10MB,总内存占用为3GB)

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

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

参考:

Original: https://www.cnblogs.com/JoannaQ/p/4470272.html
Author: Joanna Qian
Title: 节约内存:Instagram的Redis实践(转)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529302/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 学习一下 SpringCloud (四)– 服务降级、熔断 Hystrix、Sentinel

    (1) 相关博文地址: 学习一下 SpringCloud (一)– 从单体架构到微服务架构、代码拆分(maven 聚合): https://www.cnblogs.com/l-y…

    Linux 2023年6月11日
    0105
  • [云原生]Kubernetes-介绍(第1章)

    一、应用部署方式演变 二、Kubernetes简介 三、Kubernetes组件 四、Kubernetes概念 参考: Kubernetes(K8S) 入门进阶实战完整教程,黑马程…

    Linux 2023年6月13日
    0102
  • Identity Server 4客户端认证控制访问API(一)

    一、说明 我们将定义一个api和要访问它的客户端,客户端将在identityser上请求访问令牌,并使用访问令牌调用api 二、项目结构与准备 1、创建项目QuickStartId…

    Linux 2023年6月13日
    093
  • Redis 三种集群策略

    Redis 是单线程的,但是一般的作为缓存使用的话,速度已经足够使用。官方有一个简单测试:测试完成 50 个并发执行 100000 个请求,设置和获取的值是一个 256 字节字符串…

    Linux 2023年5月28日
    098
  • 银河麒麟KYLIN安装wireshark进行抓包

    银河麒麟KYLIN安装wireshark进行抓包(前提是网络连通):sudo apt-get updatesudo apt-get install wireshark -y弹出框选…

    Linux 2023年6月13日
    0111
  • redis编译安装

    redis是一个强大的NoSQL数据库,相对于memcached,他提供了更丰富的数据类型,有string、hash、list、set、sorted set这几种类型;还支持数据持…

    Linux 2023年5月28日
    097
  • QLabel图片自适应

    故事背景:由于要做终端定制的需求,在服务端上传一张128像素的图片,下发给客户端,适配所有图标(界面左上角、任务栏、快捷方式、托盘等),但是由于每个位置的图标大小不一样,代码要根据…

    Linux 2023年6月13日
    083
  • redis client原理分析

    1:空闲连接池实现 空闲连接池存在一个双向链表中,一个连接用完后回收,就会从表头插入这个链表,当需要一个连接时也是从链表的表头取,从表头插入的时候会写入当前时间,所以链表是一个按时…

    Linux 2023年5月28日
    089
  • 基于Docker的redis集群搭建

    Redis集群官方介绍:http://www.redis.cn/topics/cluster-tutorial.html 基于Docker搭建Redis集群 环境:6个节点,三主三…

    Linux 2023年5月28日
    078
  • [转帖]shell 学习之until语句

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年5月28日
    098
  • JDK/MYSQL/TOMCAT环境变量

    IDE:智能开发环境 SDK:软件开发工具包 JDK:Java开发工具包 JRE:Java运行环境 JAR:Java档案文件 API:应用程序接口 1.JAVA_HOME的变量名下…

    Linux 2023年6月7日
    068
  • 四大高阶函数、匿名函数、递归

    四大高阶函数: map、reduce、filter、sorted 1.map函数: 根据提供的函数对指定序列做映射 使用可迭代对象(指定的序列)中的每个元素调用函数,将返回值作为新…

    Linux 2023年6月8日
    0101
  • ubuntu redis 集群配置

    1.下载并编译redis 去http://download.redis.io/releases/查看自己想要下载的redis,右键复制一下链接我的原始目录:/root wget h…

    Linux 2023年6月7日
    0104
  • LeetCode 406.根据身高重建队列 | 解题思路及代码

    There are (n) people, we want them line up in the following way. Given a two-dimensional a…

    Linux 2023年6月13日
    087
  • SSH升级版本–8.2p1

    前期准备 执行yum update openssh先升级下. 反正官方提供的这种升级是没问题的。如果之前手动编译操作过openssh的升级,变更了默认配置文件路径什么的请自行测试。…

    Linux 2023年6月8日
    084
  • [Git]Github代码版本管理

    参考: 安装Git 配置工具 对所有本地仓库的用户信息进行配置 $ git config –global user.name "[name]" 对你的comm…

    Linux 2023年6月13日
    0135
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球