Simplicity - 读Instagram的成长故事笔记

Simplicity

简单,理解简单的意义,最近好多项目,还有思想,做事的方式都感觉比较复杂,最近深刻理解下Simplicity的含义,最近看到了Instagram的PPT,更是有想写一篇的冲动。

先来看看Instagram创始人Mike Krieger  的 Scaling Instagram  ,微盘下载

Instagram

在现实社会中通过图片进行交流和分享

不到2年里面发展了3000万+用户

the story of how we scaled it.

讲讲我们scaled它的故事   

a brief tangent  

一个简单的目标

the beginning  

刚刚开始的时候

2 product guys

2个做产品的家伙

no real back-end experience

没有实际的后端开发的经验

analytics & python @ meebo 

在meebo公司做分析会写些python

meebo.com - Cut through the clutter  

Create an interest profile to get new and timely information about the things that matter to you.

Meebo是一家互联网公司,之前的影响是一个集成多个IM登陆后可以相互交流的公司,看来现在改变了,新注册后会要求用户分析喜欢的URL连接,并对连接进行评价

如喜欢,laugh at this, smile at this, frown at this ,不过一注册进来感觉还是自己和自己完,交互的较少

 

CouchDB

数据库使用了CouchDB,一款mem的nosql db,没这么用过具体还是不是很清楚,也属于比较活跃的NOSQL中的一种

CrimeDesk SF

这个google了,可能是一个iphone app 的框架或者类库之类的东西,不是很了解

let's get hacking  

让我们开始吧

good components in place early on

早点把对的东西放在对的地方

…but were hosted on a sinale machine somewhere in LA

但把这台机器托管在洛杉矶的哪个地方?

less powerful than my MacBook Pro

性能比我的MacBookPro 还次些。

Okay,we launched.now what?

最后我们把它托管了,现在正是启动了

25k signups in the first day

第一天注册了25000用户,这点真的还是挺不可思议的,在2010年的时候,iphone在美国的app数量应该还不是很多吧,具体还不了解,不过第一天有这么多用户还算是很报错的,还是他们的推广做的比较好?

everything is on fire!

到处都出问题

best & worst day of our lives so far

这个也是最好的也是最糟糕的一天

load was through the roof 

都在顶上跑

first culprit  第一个罪魁祸首

favicon.ico  是站点小图标  

404-ing on Django,causing tons of errors  Django中的404的生成了大量的错误log

lesson #1: don't forget your favicon   第一课,不要忘记站点图标,这个应该也算是一个http的请求吧

real lesson #1:most of your initial scaling problems won't be glamorous  刚刚开始不要太有魅力

favicon

ulimit -n   设置limit 

memchaced -t 4   这里应该是指memcached的工具吧

prefork/postfork  预fork和发送fork  ???

friday rolls around  周五在挣扎 ??

not slowing down  不能在慢的了

let's move to EC2  迁移到 Amazon EC2 

scaling = replacing all components of a car while driving it at 100mph   

当开100码的时候需要替换掉车的所有组件

since 

开始

canonical [architecture] of an early stage startup in this era.(HighScalability.com)

在早些时候就考虑好架构还是很有必要的。

所以选了一下的技术架构

Nginx & HAProxy &  Redis & Memcached & Postgres & Gearman &  Django 

 

24 Ops

24小时操作完成

 

our philosophy 我们的哲理

1 simplicity 简单

2 optimize for minimal operational burden  对最小化的操作压力进行优化

3 instrument everything 一切都工具化

 

walkthrough:   演练

1.scaling the database  数据库扩展

2 choosing technology 技术选型

3 staying nimble   保持敏捷

4 scaling for android  扩展到android平台

 

1 scaling the db  数据库的扩展

early days  早些时候

django ORM,postgresql  使用的是Django ORM 和 PostgreSQL ,这个和CouchDB是一个时期的么? 图片直接存储在数据库里面?? 汗了去了解了下PostgreSQL

why pg? postgis.   为什么使用PG,支持地理数据对象 postgis 

moved db to its own machine  移动db到独立的db server上  

but photos kept growing and growing…     但是图片还是一直在增长,一直在增长

…and only 68GB of RAM on biggest machine in EC2

 

so what now?  现在怎么样的了?

vertical partitioning  垂直切分

django db routers make it pretty easy  使用Django 数据库路由器使得分区变得很容易 

…once you untangle all your foreign key relationships   在这之前,先解除外键约束,不过现在涉及的数据库的外键约束貌似很少用的了。

 

a few months later…  几个月后

photosdb>60GB  图片数据库超过了60GB

 

what now?  那现在的呢?

horizontal partitioning 水平切分

 

aka:sharding   使用sharding

"surely we'll have hired someone experienced before we actually need to share. 

当我们真的需要share的时候,我们雇佣有经验的人来做

you don't get to choose when scaling challenes come up

当scaling挑战来的时候你别无选择,随着用户数和流量上来的时候水平切分需要考虑的了,这个时候必须来面对

evaluated solutions 评估解决方案

 

at the time,none were up to task of being our  primary DB

在这个时候,谁也不做主DB来承担这个任务,其实当需要水平切分的时候,主库往往会存在瓶颈,读写分离是必须的,做缓存更是非常的必要的。

did in Postgres itself   配置Postgres的解决方案?

what's painful about sharding?  sharding过程什么有痛苦?

1 data retrieval   数据检索

 hard to know what your primary access patterns will be w/out any usage in most cases,userID

很难知道你主要的访问模式的写/读的使用情况,通过userID来?其实我自己也没有做过水平的sharding

 

2 what happens if one of your shards gets to big?    当你的shards中的一个增大的时候将发生什么?

in range-based schemes (like MongoDB),you split   范围的schemes,需要进行拆分

A-H:shard0       

I-Z:shard1

A-D:shard0

E-H:shard2

I-P:shard1

Q-Z:shard2

downsides(especially on EC2):disk IO

这里是说划分的模式,  最低层的EC2,存在IO问题

 

instead,we pre-split   代替方案,我们进行预划分

many many many (thousands) of logical shards  划分成逻辑shards

that map to fewer physical ones  将逻辑的shards映射到物理shards上

little known but awesome PG feature:schemas   在PG级别下,也能工作的好好的就好了

not "columns" schema     schema切分之间到逻辑中,不是到字段,而是到库级别,比如我们之前的sharding 都是库名,到表明,这里的之间sharding库了

这样的做法其实是逻辑层上控制就好就好了,不管这个是在那个物理机器上的    

machineA:

    shard0

          photos_by_user  

    shard1

          photos_by_user 

     shard2 

          photos_by_user

当单机压力大的时候就把这些shard拆到其他的物理机器上去

can do this as long as you have more logical shards than physical ones

这样做,你的逻辑的shards大大多余物理机的shards然后当流量增加的时候加机器就可以的了

 

lesson:take tech/tools you know and try first to adapt them into a simple solution

用自己熟悉的技术和工具,然后在简单的解决方案中试用他们

2 which tools where?  我们都用了那些工具

where to cache/otherwise denormalize data   在那里缓存非结构化的数据?

we < 3 redis   我们使用了3组redis

what happens when a user posts a photo?  当用户发送一张图片的时候的执行过程是什么样的?

1 user uploads photo with(optional) caption and location   用户上传带有标题和地理位置信息的图片

2 synchronous write to the media database for that user   同步写入用户的媒体数据库

3 queues!   队列

3a   if geotagged ,async worker POSTS to Solr  如果打了地理位置标签,异步进程将POST他们到SOLR,SOLR是一个全文检索的解决方案基于Lucence.

3b   follower delivery   关注者的信息投递

can't have every user who loads her timeline look up all their followers and then their photos

不能使所有的用户查看他们的timeline的时候查看到他所有的关注者和他们的图片,因为会随着关注人的增多而timeline的信息量会很大

instead,everyone gets their own list in Redis

替代方案,所有人都从redis中读取他们的列表

media ID is pushed onto a list for every person who's following this user

用户读取自己的inbox列表中的内容,这个Inbox里面的东西,是当用户关注的人发了消息后,这个消息id就会被放到inbox中,这样就能看到关注用户发的消息了

Redis is awesome for this;rapid insert,rapid subsets

redis做这个很在行,快速的插入,快速的获取子部分,其实这里用redis是membase,然后支持数据类型的,这个时候,对于写入一个list,还有读取list的部分元素,做的都比较容易,基本全内存操作列表,所以很快

when time to render a feed,we take small of IDs, go look up info in memcached

当我们获取feed的时候,就读取用户的 inbox ,获取到一个id集合,然后用这些id集合在去memcache中取出数据,并展现结果

Redis is great for data structures that are relatively bounded

redis对于结构化数据的相对集合操作是很适合的。

(don't tie yourself to a solution where your in memory DB is your main datastore)

不要把自己绑在主库为全内存数据库的解决方案上,

caching complex objects where you what to more than GET

当读取多的时候对这些复杂的对象都进行缓存

ex:counting,subranges,testing memberships

例如技术,数组,还有会员关系 ? 

especially when laylor Swift posts live from the CMAs ?

 

follow graph  关注图

v1:simple DB table (source_id,target_id,status)  简单的数据表来存储

who do I follow?   

who follows me?

do I follow X ?

does X follow me?

DB was busy,so we started storing parallel version in Redis   我们使用red is来代替

follow_all(300 item list)  每个人最多follow 300 个?  

 

inconsistency  易变的

extra logic  扩展逻辑

so much extra logic  扩展很多的逻辑

exposing your support team to the idea of cache invalidation  (reset red is cache)

考虑cache的操作方案,升级逻辑后需要清除cache

redesign took a page from twitter's book

从twitter的经验中学习,重新设计一个页面的方式,feed的页面就一个页面还是挺好的。

PG can handle tens of thousands of requests,very light memcached caching

轻量级的缓存能处理大陆的请求。

 

two takeaways   2个抛弃的想法

1 have a versatile complement to your core data storage(like Redis) 给核心数据存储弄补充,比如使用redis

2 try not to have two tools trying to do the same job  不要尝试2个工具做同样的事情

3 staying nimble  保持敏捷

2010: 2 engineers   2个工程师  总共2个人

2011: 3engineers    3个工程师  

2012:5engineers     5个工程师  总共13个人  

scarcity -> focus     不足 -- 关注 

engineer solutions that you're not constantly returning to because they broke  1 extensive unit-tests and functional tests

工程解决方案不要去不断的回归,因为他们会打破一个单元测试或者函数测试????  

2 keep it DRY  确保是干货? 这个咋个理解?

3 loose coupling using notifications / signals  使用通知/信号实现低耦合

4 do most of our work in Python,drop to C when necessary  多使用python来替代C

5 frequent code reviews,pull requests to keep things in the 'shared brain' 经常的代码review,通过思维共享来推动事情

6 extensive monitoring  大量监控

munin 

statsd

"how is the system right now?"   现在的系统运行的怎么样?

"how does this compare to historical trends?" 现在和过去比趋势是什么样的?

scaling for android   扩展android方面的

1 million new users in 12 hours   在过去的12小时里面增加了100万用户

great tools that enable easy read scalability  用好的工具而且容易扩展

redis : slave of <host> <port>   挂redis从库

our Redis framework assumes 0+ reads slaves  使用red is框架支持多个从库的读取

tight iteration loops  速度的迭代

statsd & pgfouine   这个就不知道

know where you can shed load if needed  性能优化发霉的了

(e,g, shorter feeds)

if you're tempted to reinvent the wheel…  不要冒险重复制造轮子

don't 

下面介绍HAProxy和性能监控发霉的

"our app servers sometimes kernel panic under load "   

"what if we write a monitoring deamon…"   

wait! this is exactly what HAProxy is great at surround yourself with awesome advisors

culture of openness around engineering

give back; e,g, node2dm

focus on making what you have better   关注在如何做的更好

"fast,beautiful photo sharing"  更快,更好的图片分享

"can we make all of our requests 50% the time?"  性能优化,性能提高50%

staying nimble = remind yourself of what's important 保持敏捷,提醒自己什么是最重要的

your users around the world don't care that you wrote your own DB  保持DB的稳定

wrapping up    包装自己

unprecedented times  现在是空前的好时候

2 backend engineers can scale a system to 30+ million users  其实只用2个后端工程师就可以解决3000万用户的系统问题

key word = simplicity    关键词还是简单,简洁

cleanest solution with the fewest moving parts as possible   尽可能的干净的解决方案尽可能的少移动组成部分

don't over-optimize or expect to know ahead of time how site will scale  不要过度的优化除非超前的意识到站点的将如何scale

don't think "someone else will join & take car of this"  不要想这这些事情等新加入人在解决,其实很多时候新加入人不大可能提高效率

will happen sooner than you think;surround yourself with great advisors  发生的往往比自己想到的要多,让自己身边有好的提意见的人

when adding software to stack :only if you have to,optimizing for operational simplicity 当上架的时候,保证已经优化而且操作是简单的

few,if any,unsolvable scaling challenges for a social startup  对于刚刚起步的social还要很多不能解决的的问题,将继续下去。。。

 

have fun  结束

 

到今天看了2便PPT了,花了点时间翻译了下有些体会想写下来

1.其实很少的人也能够把项目run起来的

不管是一个人还是2个人都可以先把项目run起来,其实不管这个项目的发起人的技术怎么样,但是如果是会技术,他就可以不依赖于于别人就把项目做起来,这里的2个创始人就是他们自己有想法然后去实现的。先推出一个版本,目标的标志是上线。上线让用户真正来用了,这个才可以说项目是run起来的了

其实在这个过程中,是否要去租办公地点,是否需要一个强大的团队,其实我个人感觉真的很没有必要,首先项目知名度不是很高,很多人会带来协作的复杂度,也会增加开发成本和交流成本,不便于快速的进行,租房子什么的其实更是没有什么必要的了,因为现在还是没有上线。但是一些不会技术的人去租房子,可以带给团队更可靠的感觉,这个还是很好的,但是建议前期带给开发团队一些好的支持,不管是情感上的,还是经济上的都是非常的重要的。

 

2.其实技术选型非常重要

前期,可以先实现,但是随着用户的增加,你的系统底层的架构是无法满足要求的,这里也提到了,但第一天来了很多人就出问题的了。这个我也经历过,发布了系统后第一天很多人来,DB就出问题报警的了。所以前期可以多花点时间做技术选型还是很有必要的,比如这里提供的一个比较好的技术架构方案,完全可以使用,这个取决于项目技术团队的领导者对技术的看法,其实很多的技术方案都是结果生产环境验证过的完全可以使用。

PPT中提到的instagram的架构方案

Nginx & HAProxy &  Redis & Memcached & Postgres & Gearman &  Django  & Solr 

现在在进行中的wsmj的方案

Nginx  & Redis & Memcached & Mysql & Sphinx  & Buddy Framework  & Httpsqs  & UpYun Image Store

前期的技术选型可以对后期的开发带来好处,因为你可以遇见接下来的流量和数据量到PB级别后系统还是不需要多少的改动就能解决.

 

3.其实垂直划分和水平划分是都会预见到的可以提前做好准备

其实对于系统而且,无时无刻都会有数据的增加,只要它在线上都会遇到这样的问题,所以要做好应对的准备,按照目前的情况来看,移到云端是一大趋势,现在很多牛人都在推荐AMAZONE的云服务,自己也在做这个方面的探讨,这个还是很有必要的,其实早期托管服务器的成本与托管到Amazone EC2的成本都差不多。为了省去迁移的成本,其实可以之间布在Amazone Cloud上了

考虑数据中心的延迟问题,考虑分布式和sharding的问题都是很有必要的。这里instagram 使用的划分成逻辑的小的shard也是很经常用的,其实读写都写主库,写完后在从库读取并建memcache缓存,之后在缓存中读取,然后对于特定的用户结构型数据可以从mysql中解耦出来,使用redis的结构化数据来存储也是一个很好的方案。这些现在的项目中也在尝试在用。

 

4.专注

其实专注还是很难做到的,在instagram这里他们没有很多繁杂的功能,只是一个主要的功能,通过图片实现用户之间的交流和分享,并且不断的把这个事情做好,在做到机制,在平台上不断的覆盖全平台,从最早的ios,到android,到现在被收购,更是说明了专注的价值,其实很多的功能都是可以去掉的。完全可以,只要对用户来说这个产品好用而且有朋友可以一起用能形成互动就好的了。

 

5.13个人其中只有5个工程师2个后端工程师

对于有3000万+用户的人,其实就5个工程师和2个的后端的工程师就能搞定,其实这个说明后端系统的业务逻辑不是很复杂,在者就是这些人都是很专业的。

只有很专业的人做好了本分才能保证系统的正常运行,其实这个又反回来,自己经历过的这些公司,研发人员上面,团队还是比较大的,往往都是垂直的功能切分造成的,在国内的环境下也可以理解。

 

6.简单,simplicity   简单,保持敏捷

简单保持敏捷,现在这个在国内还是很不容易,往往拍版的人都不是技术出身,都是要团队人员就位后开始,而且往往人员规模是比较大的,比如,PM,RD,QA,OP,MANAGER 等等,人数上就已经很多的了。还有CEO,CTO,董事长,COO等,目前接触过的团队往往起初人数就超过8人的了。

这样保持简单还是挺困难的。所以根本上还是人数少才行。

 

7.善于学习

学习其他的公司的技术方案,参考了twitter和其他的公司的现成的问题及解决方案还是可以节省很多的开发时间的,善于学习,不管是产品还是技术,这句都是通用的。

 

8.回归还是执行力

最终还是要有执行力的,所以往往简单的事情,做起来简单,执行力也会好,对于技术人员来说也是,对于产品人员来说更是。

最后光说没有用,还是现在开始,在创业过程中的人们好好的多看看这个ppt,并能够按照这里来做,能做到的话,其实还是很有可能成功的。

这个不仅仅给创业的大家,也是给自己提醒,简单………

我自己也在使用Instagram其实也许很多的创业者也在使用,是否在用的时候会有所警示呢?想想简单....想想简单....

 

想起了:

简单可依赖

简单快速,简单敏捷………………..

简单才是根本的基础,共勉!

 

PS:有翻译不当的地方,欢迎大家拍砖!

posted @ 2012-04-16 14:45 xinqiyang 阅读(...) 评论(...) 编辑 收藏