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

add by zhj:本文只翻译了一部分,更多分析要参考英文原文

译文:节约内存:Instagram的Redis实践

英文原文:Storing hundreds of millions of simple key-value pairs in 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还是超支了。

于是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个。

时间: 2024-08-02 11:02:19

节约内存:Instagram的Redis实践(转)的相关文章

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

一.问题: 数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求. 二.解决方案: 1.通过高速服务器Cache缓存数据库数据 2.内存数据库 三.主流解Cache和数据库对比: 从以上各数据可知,对于我们产品最可行的技术方案有两种: 1.Memcached         内存Key-Value Cache 2.Redis                     内存数据库 四,节约内存:Instagram的Redis实践 Instagram可以说是网拍App的始祖级应用,也是当

libCURL动态分配buffer——节约内存

libCURL是一个免费的.开源的强大客户端url传输库.支持的平台.协议甚广.平台上有Windows.Linux.FreeBSD:协议上有FTP.HTTP(S).Telnet.DICT.File等.它是线程安全的,而且支持ipv6.同时,它还是线程安全的. 本文所讲述的内容,要基于Libcurl的基础.具体的了解.官方具体描述地址在:http://curl.haxx.se/libcurl/c/上面.需要多看例子,才能灵活运用. 通常libCURL的数据下载都是通过回调函数下载到buffer中的

通用的Bitmap压缩算法,进一步节约内存

前几天我写了一篇通过压缩Bitmap,减少OOM的文章,那篇文章的目的是按照imageview的大小来压缩bitmap,让bitmap的大小正好是imageview.但是那种算法的通用性比较差,仅仅能适合fit_xy的情况.对此我进一步分析了下这个问题,并且参考了Volley的源码,最终得出了结论:如果你要让这个压缩后的bitmap完全适合多种imageview拉伸模式,你就必须重写拉伸模式的算法,但这过于小题大做了.讨巧一点的办法就是让这个imageview不完全按照imageview的长宽进

iOS内存管理策略和实践

来源:http://www.baidu.com/link?url=irojqCBbZKsY7b0L2EBPkuEkfJ9MQvUf8kuNWQUXkBLk5b22Jl5rjozKaJS3n78jCnSsUZjVQvFIW1IKcJMlR2fGj9eiy-gCY7ulTRyEuAi 关于iOS内存管理 应用程序内存管理是:程序运行时,开辟的内存空间.使用它,释放它的过程,写的好的程序尽可能少使用内存.在Objective-C中,内存管理被看做是:在很多数据.代码下,分配 转自hherima的博客

全内存的redis用习惯了?那能突破内存限制类redis产品ssdb呢?

原文:全内存的redis用习惯了?那能突破内存限制类redis产品ssdb呢? 首先说一下背景,在双十一的时候,我们系统接受X宝的订单推送,同事原先的实现方式是使用redis的List作为推送数据的承载,在非大促的场景下, 一切运行正常,内存占用大概3-4G,机器是16G内存.由于提前预计不足,在双十一来临的时候,订单瞬时量达到了平时的10X倍,内存非常吃紧,情况算 是非常紧急了,采取的临时解决方案就是再开一个redis,将程序中的redis地址指向这台新的,重启一下程序,把数据暂时引导过去.

基于内存的类似redis的缓存方法

项目中需要用到redis,业务起来之后用到的地方更多,问题来了,因为操作redis太频繁,导致操作redis成为整个项目的瓶颈,经过调研和比较这时候基于内存的cache登场,简单来说就是纯内存层面的cache,可以实现1.缓存数量的限制(不能无限制的堆内存,会撑爆)2.能设置过期时间(内存中只缓存高频出现的数据) 放上业务流程的对比图,就是在redis之前加了一层,比较redis虽然基于内存但是连接包括操作还是得产生网络io操作 下面是我做的对比测试: 普通数据: 1.假设全部不命中(内存和re

Redis 实践之安装运行

本文原创自 http://blog.csdn.net/voipmaker  转载注明出处. Redis是nosql数据库家族的一员,与memcached类似, 是高性能的基于内存的key-value存储系统,笔者将逐步把学习和使用redis的过程记录成笔记. (1)     编译安装: 官方网站下载redis-3.0.0-beta8.tar.gz 解压后源码目录: cd /opt/redis/redis-3.0.0-beta8 make make install Redis安装过程很简答,下载源

Redis实践之 配置文件解析

本文原创自 http://blog.csdn.net/voipmaker  转载注明出处. 要掌握redis的用法,配置文件的重要参数必须掌握,下面是笔者对各个参数的学习笔记,同时会针对特殊参数的使用场景做简短说明. include /path/to/other.conf 解释:include和c里面的include概念类似,可以把redis的的参数分散到其他文件,当运行多个redis实例时,通过include一个common的配置文件让所有redis-server共享,简化redis.conf

Redis 实践1- redis介绍和安装

redis是一个key-value存储系统,官方站点 http://redis.io 和memcached类似,但支持数据持久化 支持更多value类型,除了和string外,还支持hash.lists(链表).sets(集合)和sorted sets(有序集合)几种数据类型 redis使用了两种文件格式:全量数据(RDB)和增量请求(aof).全量数据格式是把内存中的数据写入磁盘,便于下次读取文件进行加载.增量请求文件则是把内存中的数据序列化为操作请求,用于读取文件进行replay得到数据 r