交流群号:222486251
Pinterest 架构
Amazon EC2 + S3 + MySQL + Redis + Memcache + Sharded Solr + Java
认识Pinterest
Pinterest网上的贴图板让我们组织分享带来灵感的图片,现在看到的是我自己Pinterest的主页,有一些画板,可以贴图。结合了图形和照片,非常特别,不管在什么地方找到图形,比如说一个产品很喜欢,追溯到哪里买的。为什么用户觉得很特别,可以关注他们的画板,关注的时候如果贴一张图,也可以获得这张图。他们贴图我们也会收到。
如果进入数据库的模式,现在看到的是数据的结构,有一个用户有画板,可以贴图,其他的用户自己有自己的画板,另外还有其他一些关系的方法,可以转贴,表示喜欢他的贴图。2011年5月刚刚推出这个网站,很多意义上来说,可以看到我们做了一些设计的功能,那个时候找RockSpace来托管,一个工程师就够了,网站开发我们也不知道开发到哪个阶段,保持灵活,不大量投资。
2001年1月,我们的创始人说现在还是处于一个隐身模式,大家没有听过我们的名字。这时稍稍有一点知名度,我们用了Amazon,他们给我们做托管。接下来的的9个月已经忘了睡觉是什么滋味了,加强建设,网站发展太快,每天翻倍,每天有各种失误,我们要保障很多问题,很快问题一发不可收拾。
我们不想看这里有多少的东西,可以感受一下这里有多少的技术、多少复杂性,把PPT所示的技术结合在一起,都有自己微妙的工作方式,每天带来各种头疼、各种麻烦,有三名工程师处理恶梦,因为扩张太快,肯定有问题。我们第一个经验教训是这个系统会有问题的,所以尽量保持简单。
未来一定要保障我们的架构
我们不想用一些太复杂的技术和方法,希望能够让过程变得简单,比较容易去修改或者维修。
2012年的时候,我们架构不断的演变,这时基本上已经成形了,大量的简化,用了66个MySQL的数据库,这时已经成形了,从这个模式上进行增长,不会有太多的问题。我们有MySQL和Memcache,有6名工程师,也做了分片的服务器。几个月之后,比较接近今天的现状,我们增加了一些设备,但是目前来说架构已经从1月份以来成型固定了,有25名工程师。重点是扩大我们的团队。
Amazon很好用,有很多周边有很多工具帮助管理公司,不想管理也可以做缓存,帮助你做数据库管理。也许在以后我们也可以让Amazon来帮我们做周边的管理。更重要的一点是如果要再做一此第三个原因用Amazon,因为几秒钟之内生成一个实力,发展很快不知道用什么东西,5秒钟形成一个新的实力。缺点是选择比较少,可能就几个设备,就这些选择,比如说26G,那时买不了X60或者更快的选择。但是选择不多也是好处,不需要太多的动心,不需要挑乱眼。
MySQL也是系统的基石,一致的为我们带来很好的表现,26年的历史了,非常成熟,非常多人知道,很喜欢,工程师有自己的经验,我自己也做MySQL,我也经常使用也做管理,很多人是这方面的专家,我也为MySQL编过码,几乎很少有大量数据缺失,这是硬件问题不是软件问题,反应时间可以随着请求率进行增长。有一定的技术到一定的量响应时间是掉下来了。但是MySQL可以随着线性扩张的,对明天有所预见,而且社区非常活跃,搜MySQL肯定有很多东西帮忙,很多公司给支持,而且MySQL是免费的。当然,作为一个小的网页公司,当初的资金有限,用MySQL资金是一个解决条件。
Memcache非常成熟,功能表现非常好,而且很多人喜欢,也知道怎么用,很少有失效和崩溃的时候,而且失效模式非常少。因为比较简单,没有什么可以出错的地方,还有一点非常好,免费,免费谁不喜欢呢?
Redis是新的公司,有自己的一些小玩意,有自己的复制和持续性,而且结构非常好,想进行分类、进行散列都有这个功能。很多功能都可以用得上,而且这还是比较新的公司,但是很多人都非常喜欢它。我在社区里面听过很多人表示好评,也进行大量的使用。我们听了好评声去使用,表现非常好,有一定的失效模式,比MySQL稍微多一点,但至少还是可以的。另外,还是免费。
网站架构的调整
到底用集群还是分片,我们肯定要调整架构的,网站发展有太多的技术可以进行全自动化的调整。很多人说买了这个设备可以自动的进行分配,如果这个盒子坏了,另外一个盒子能够备用。我们到底是不是真的想要集群呢?后来用分片,发现分片手动性强一点,集群和分片是非常多的选择,对于集群来说,是自动化的数据,数据可以迁移的,可以重新分配装载容量。另外一端是分片,是用手工进行数据的。换句话说,必须要用编码,一定不是自动化的,这是一个决定。数据进入某个分片以后,基本上不再移动了。同时数据进行分解,数据一半放这个片,一半放那个片,每一片有更多的容量分配数据。而且结点之间不了解,不会互相沟通的。
所以,用集群有什么样的好处,我列出了一些例子,比如说像集群的技术。比如说Cassandra、MemBase等可以自动扩展,非常容易设置,5分钟就可以设置了。可以空间分配来,数据有非常高的可用性,均衡而且没有单一的失效点。
如果一切美梦成真的话,什么事都不用干了,但是会有什么事出错呢?如果什么都好的话为什么不用集群呢?做了几年之后还是非常复杂的,而且比较复杂、历史也不长,社区支持也比较少。没有太多人推动这个技术,寻找帮助社区对你的帮助非常有限,现在有这个知识的工程师为数不多。比如说我了解的Clustering的工程师不多。
有时候会觉得非常害怕,原来从0.8到0.3有一点步骤要做,做了又不一定会成功,运气好做好,运气不好突然会失效,我觉得比较不幸的是影响到我们好几次的。首先看我们集群,所有东西都是绿色的,大家很开心,但是突然服务器不行了,一般来说找一个替代的服务器换上去,把所有的东西分到新的服务器。出现什么问题呢?看到里面的服务器每个都使用同样的算法来计算,之前也是前期沟通的,希望服务器有问题和漏洞的话,所有的服务器都有问题,项目沟通的漏洞也会转移到其他的服务器上。
你写的一条比较复杂的代码影响到所有的节点,出现的问题首先包括数据在均衡会失效。很多个盒子,把东西分到不同的盒子里,发现镜头80%停下来,只能取消。另外,所有的节点都有数据的损坏,托管层有漏洞的话会影响下面的成绩。每个漏洞导致每个服务器出现数据损坏。另外,无法有效治愈的错误的平衡。不同的服务器加了90%的数据,剩下1%不到,怎么办呢?可能需要一个技术手动进行分布。
另外数据授权的失灵,其中有一个盒子可以说是主本,做一个副本,大概做了80%的时候副本才能决定到底数据从哪来的。副本拿80%的时候,其他觉得80%的副本是主服务器,把信息再拉进来,导致主服务器出现偏移,从而无法进行正确的传输。这些技术发展的时间比较短,现在有些问题让人比较害怕。
为什么要做分片的,分片是手动操作的,把数据库分开来增加容量,可以在空间上进行分布,高可用性进行附载均衡。我们放置数据的算法非常简单,写下来之后有一天在进行测试,非常小的算法。我们用很简单的机制来生成ID,下面有请我的搭档Evrhet Milam讲一讲什么时候该做分片,怎么做分片。
【Evrhet Milam】首先,要做分片的话,板式设计、模式设计更加困难,要放对地方才行,等稳定了才能分辨,等太久,转移数据更困难。所以要选择一个合适的时机,把你的数据从一个模式转到另外一个模式。另外,在做分片的时候,设计靠得住的,就像我们有的用户以及图板、贴图等。这就是我们网站的设计,网站设计先确定下来,还要确定后端的架构怎么样。
下面所有的连接和复杂的查询要取消掉。现在很多连接非
▲Evrhet Milam
常麻烦,分片是独立开的数据库,加上复杂的查询不行。加上缓存会好很多。让分片发挥系统的功效。我们的数据库、系统中有很多不同的贴图,贴图放到数据库里面,让不同的分片发挥功效。另外,如果你的网站不断发展、不断增长的话,最好用分片的技术。有些人网站到了一定技术,不用分片,如果量不断增加,用分片比较好。
这是不断迁移不断发展的过程
先是有一个服务器,有外件、有很多的连接,比如说有一个用户通过连接和贴图连接在一起,把数据进行非正规化做得更快一点。很多数据重复的,我们也做了很多的高速缓存。我们还有读取的仓库,再把数据分片,分成不同功能范围的分片。比如说有一个分片里面专门放用户信息,有些是专门放贴图的,还有专门放客户用户的评论的。
我们当时比较早的采用分片来应对我们的数据,如果做得稍微迟一点的话,分片就比较困难了,毕竟有很多外件牵涉到其中。我们做了最后一个跨越,通过ID进行数据库的分片。不同的数据库能够更好以一种水平的,而非垂直的方式把数据进行分类,放到不同的分片里。
如果做分片,会发现原来有这么多的连接必须要拿走,不能放在里面去了。当然,做分片无法实现数据交易。不用分片方式可以实现其中的交易,现在做分片不可能了。另外,确保一些独特的约束,比如说有一些特殊的数据库,用户的信息、电子邮件等。必须要有特别的系统确保不同的分片、不同的运输。更换摆设的话要很长时间,要做非常多的工作才行。
另外,报告。原来选择一个搜索把数据找出来,现在有上千个数据库,写一些脚本反复执行找到查询的结果。下面看一看我们怎么分片的。
现在看到的这张图,所有的数据库都放在这里,我们一开始有八个物理服务,每个上面都有512个数据库,都是DB0001和00513、3072数据量都一样,里面ID分开不同的数据,包括用户数据、贴图的数据。另外,多主库的应用。每一个服务器都有它的主库,有很高的可用性,非常的强大。不同的会崩溃,如果有问题的话,把里面导出来传输其他的服务器就可以了。
我们有八个服务器,但是服务器上面有太多的用户信息了,数据附载太大怎么办?有512个数据库,可以把数据分开放到数据库里面。比如说DB0001放到其他的服务器上。我们做同样的工作,分开来放进去就可以了。
下面看怎么改变ID的,对我们ID的分片非常重要的,我们的对象有独特的ID,64位的,根据不同的类型进行分片、进行分离。比如说刚才讲的数据库有不同的编号,有它的类别,要么是图板、要么贴图、要么评论、要么用户。是不同类型,类型也是能够给他专业性。看数据看有没有把东西放混了,把用户的数据放到评论的数据里面了。
分片的ID到底放在哪个数据库里,现在用的表里面我们属于哪个位置的。本地ID看这个表里面具体的放置信息有什么作用,是关于评论还是用户信息的。我们看看有简单的映射,整个管理数据库,还有反向的图。我们的系统代码可以有效的找到相关的过滤信息。如果想找用户信息,就看一看到底分片的ID在哪里。找到后在分片的ID里面具体找到1057,再在1057里面找到具体需要的类别,找用户。这样的分片使到我们工作非常的简单。从这样ID的结构,新的用户就是随机分布在不同的分片里面,希望能够根据不同类型的信息放到不同的分片里面。至少在本地你把用户需要的东西和需求连接在一起会比较简单。
我们可以使用自动增量放在本地ID上,系统里面每个分片就是根据ID在里面存储信息的具体情况。如果建立好ID能有6万个不同的分片。现在只用了4096个。所以现在还有很多的ID空间可以使用,而且可以能够以水平的方式进行不断扩张。
在数据库中,有一些比较简单的模式或者板式,每个角色都有它的ID,通过映射对应到图表里面,进行序列化。有索引表和映射表,用户喜欢哪些图板,建了哪些图。就像传统的系统一样,很快找到表的有效信息。重点是这些映射从一个完整的ID到另一个ID产生映射。
对于系统来说,喜欢某个贴图或者喜欢某一个用户的贴图,整个ID都是完整的,把所有的连接在一起,当然时间戳也非常有价值,分类的时候确保ID是独一无二的。我们的查询都是组件查找和索引的查找。如果数据库过于拥挤可以进行分移,但是不会移动分片上的数据。所有的分片上都会装在所有的映射表。这样的话不需要进行范式的更改。因为不需要担心有任何的改变,比如说增加一些新的索引的话,就可以使用索引来形成新的映射表。
所有的分片上都有映射表。比如说我们网站是怎样运作的,看某个用户的主页,想提取用户的数据,渲染用户主页,抽取画板和贴图,从此来渲染。很多一两次查找进行搜索就可以了。而且因为这些非常容易,可以在本地进行连接。很多工作是重复性的,可以进行大量高速缓存。一些很简单的MySQL的操作,在高速缓存中提取就可以了。而且我们还可以去抵消一些操作。
如果是提取150个贴图,可以根据这些操作取消一些对冲和抵消的操作。另外,还要编写脚本,这些数据需要进行清理,数据库设置的时候有不同的格式,我们需要把这些不同的格式进行整理才能放入分片里面。我们用的Pyres,这个工具比较容易,可以简单进行数据调整。我们有5亿的贴图,16亿的关注者,我们做一些脚本,不断测试,把这么多的数据进行分片。另外,考虑数据怎么产生,用简单的脚本来进行所有分片的过滤。
从这点往后,MySQL将会成为主流,而且也会成为正确的选择,集群会慢慢成熟。目前来说,这个技术还是分配在几个不同的公司当中,我们的公司比较关注于自动的分片。MySQL上面进行自动的分片,我们觉得这个是可行的。另外,集群将在以后会大有作为,但是不是现在。现在集群技术目前来说,对数据来说还是有各种问题的,还是要等个五到十年才能硬化。
原来有一个单片的系统,我们开始进行分片的系统,转为一个基于服务的架构。有几个不同的原因,因为规模不断扩大的时候,会有越来越多连接上限,不断达到连接上限。还需要把所有的盒子连接在一起,连接的上限也是一个很大的问题。比如说100多个ATI要连上缓存的服务器,使到服务器瘫痪,而且功能要进行隔离和分离,比如说把某些服务进行分区。当然,这也是我们继续做的方向,帮助我们清理系统。
同时,安全的隔离也是很重要的,因为安全性很有方法。因为隔离之后有安全性了。如果在一个单片或者非常复杂的环境中很难跟踪的,最重要在未来不断扩大团队的人数,现在有很多的工程师,随着用户的增加、人力也要增加。除了提供基于服务的架构,确保架构简单。现在不断招人,现在的工程师招人绝对是简单易用的,隔离开来区别对待,这样工程师不用面对整套的大摊子,工程师上手非常容易的。
最后一个跟大家分享的经验,要保持乐趣。
工作当中有很多压力,每天晚上熬夜加班肯定不好玩,如果网站运行非常顺畅,带来大量的满足。一定要让工作保持乐趣,而且让这一切能够井井有条。