数据损毁!250 亿美金的 Pinterest,在数据库选型上的翻车经历

news2024/11/19 17:30:44

原文链接

Pinterest 是一个以图片为主的社交网络,用户可以将图片保存或 "钉 / pin" 在自己的图板上。Pinterest 在 2019 年上市,目前市值 250 亿美金。本文内容主要根据 2012 年 Scaling Pinterest 的分享。

file

2012 年 1 月,Pinterest 的月独立用户数量达到 1170 万,而当时只有 6 名工程师。 Pinterest 于 2010 年 3 月推出,是当时月活用户突破 1000 万最快的公司

扩展 Pinterest 的经验教训

  • 使用已知的成熟技术。Pinterest 当时涉足较新的技术,导致了数据损坏等问题。
  • 保持简单。(反复出现的主题!)
  • 不要太有创意。团队采用的架构可以增加更多相同的节点来扩大规模。
  • 限制选项。
  • 数据库分片 > 集群。这减少了跨节点的数据传输,是件好事。
  • 享受乐趣!新工程师能够在第一周内贡献代码。

2010 年 3 月:Closed beta 发布,1 名工程师

Pinterest 于 2010 年 3 月推出,当时只有一个小型 MySQL 数据库、一个小型 web server 和一名工程师(还有两位联合创始人)。

file

2011 年 1 月:10,000 名用户,2 名工程师

九个月后的 2011 年 1 月,Pinterest 的架构已经发展到可以处理更多用户。当时他们仍然只接受邀请,只有两名工程师。

他们拥有:

  • 基本的 web server 技术栈(亚马逊 EC2、S3 和 CloudFront)
  • 用于后端的 Django(Python)
  • 4 台 web server 作为冗余
  • NGINX 作为反向代理和负载均衡。
  • 1 个 MySQL 主数据库 + 1 个只读数据库
  • 用于计数的 MongoDB
  • 1 个任务队列和 2 个任务处理器,用于异步任务

file

2011 年 10 月:320 万用户,3 名工程师

从 2011 年 1 月到 2011 年 10 月,Pinterest 的增长速度极快,用户数量每隔一个半月就翻一番。

他们在 2011 年 3 月推出的 iPhone 应用程序是推动这一增长的因素之一。

当事物快速发展时,技术出现问题的频率会超出你的预期。

这时Pinterest 犯了一个错误:他们把架构弄得过于复杂了

他们只有 3 名工程师,但却采用了 5 种不同的数据库技术来存放数据。

他们既要手动对 MySQL 数据库进行分片,又要使用 Cassandra 和 Membase(现在的 Couchbase)对数据进行集群。

他们「过于复杂的技术栈」:

  • Web server 栈(EC2 + S3 + CloudFront)
  • Pinterest 开始使用 Flask(Python)作为后端服务器
  • 16 台 web server
  • 2 个 API 引擎
  • 2 个 NGINX 代理服务器
  • 5 个手动分片的 MySQL DB + 9 个只读
  • 4 个 Cassandra 节点
  • 15 个 Membase 节点(3 个独立集群)
  • 8 个 Memcache 节点
  • 10 个 Redis 节点
  • 3 个任务路由器 + 4 个任务处理器
  • 4 个 Elastic Search 节点
  • 3 个 Mongo 集群

file

⚠️ 集群崩了

数据库集群 (Database Clustering) 是将多个数据库服务器连接起来作为一个系统共同工作的过程。

从理论上讲,集群可以自动扩展数据存储、提供高可用性、自由负载平衡,并且不会出现单点故障。

遗憾的是,在实践中,集群过于复杂,升级机制困难,而且存在一个大的单点故障 (SPOF)。

file

每个 DB 都有一个集群管理算法,在 DB 之间进行路由。

当一个数据库出现问题时,就会添加一个新的数据库来替代它。

理论上,集群管理算法应该可以很好地处理这个问题。

但实际上,Pinterest 的集群管理算法中存在一个 bug,破坏了所有节点上的数据,破坏了数据该如何重新平衡,并产生了一些无法修复的问题

file

Pinterest 的解决方案是什么?

从系统中移除所有集群技术(Cassandra、Membase)。全面采用 MySQL + Memcached(更成熟)。

MySQL 和 Memcached 都是久经考验的技术。Facebook 利用这两种技术创建了世界上最大的 Memcached 系统,每秒轻松处理数十亿次请求。

2012 年 1 月:1100 万用户,6 名工程师

2012 年 1 月,Pinterest 的月活跃用户约为 1100 万,日活跃用户在 1200 万到 2100 万之间。

此时,Pinterest 已经花时间简化了他们的架构。

他们删除了当时不太成熟的方案,如集群和 Cassandra,取而代之的是成熟的方案,如 MySQL、Memcache 和分片。

他们简化后的技术栈:

  • 亚马逊 EC2 + S3 + Akamai(取代 CloudFront)
  • AWS ELB(弹性负载平衡)
  • 90 个 web servers + 50 个 API 引擎(使用 Flask)
  • 66 个 MySQL DB + 66 个只读
  • 59 个 Redis 实例
  • 51 个 Memcache 实例
  • 1 个 Redis 任务管理器 + 25 个任务处理器
  • 分片式 Apache Solr(取代 Elasticsearch)
  • 移除 Cassanda、Membase、Elasticsearch、MongoDB、NGINX

file

Pinterest 如何手动分片数据库

数据库分片 (Database Sharding) 是一种将单个数据集分割成多个数据库的方法。 优点:高可用性、负载平衡、数据放置算法简单、易于拆分数据库以增加容量、易于定位数据

Pinterest 首次对数据库进行分片时,需要冻结新功能发布。在几个月的时间里,他们以渐进和手动的方式对数据库进行了分片:

file

团队删除了数据库层中的表 Join 和复杂查询。他们添加了大量缓存。

由于跨数据库维护唯一约束需要额外的工作,他们将用户名和电子邮件等数据保存在一个巨大的、未分片的数据库中。

这个数据库下的所有表都存在于所有分片中。

手动分片的一个小例子

由于他们有数十亿个 "pin",他们的数据库索引会耗尽内存。

他们会将数据库中最大的表转移到自己的数据库中。

然后,当数据库空间耗尽时,他们就会将其分片。

2012 年 10 月:2200 万用户,40 名工程师

2012 年 10 月,Pinterest 的月度用户约为 2200 万,但他们的工程团队却翻了两番,达到了 40 名工程师。

架构是一样的。他们只是增加了更多相同的系统。

  • 亚马逊 EC2 + S3 + CDN(EdgeCast、Akamai、Level 3)
  • 180 台 web servers + 240 个 API 引擎(使用 Flask)
  • 88 个 MySQL DB + 88 个只读
  • 110 个 Redis 实例
  • 200 个 Memcache 实例
  • 4 个 Redis 任务管理器 + 80 个任务处理器
  • 分片式 Apache Solr

file

他们开始从 HDD 转向固态硬盘 SSD。

一个重要的教训是:有限的、经过验证的选择是件好事

坚持使用 EC2 和 S3 意味着他们只有有限的配置可供选择,从而减少了麻烦,提高了简便性。

与此同时,新实例可以在几秒钟内准备就绪。这意味着他们可以在几分钟内添加 10 个 Memcache 实例。

Pinterest 的数据库结构 ID

和 Instagram 一样,Pinterest 也有一个独特的 ID 结构,因为他们有分片数据库。

他们的 64 位 ID 看起来像

file

分区 ID:哪个分区(16 位) 类型:对象类型,如针(10 位) 本地 ID:在表中的位置(38 位)

这些 ID 的查找结构是一个简单的 Python 字典。

数据库表

它们有对象表和映射表。

对象表适用于 pin、板块、评论、用户等。它们有一个映射到 MySQL blob(如 JSON)的本地 ID。

映射表用于对象之间的关系数据,如将板块映射到用户或将赞映射到 pin。它们有一个映射到完整 ID 和一个时间戳的完整 ID。

为了提高效率,所有查询都使用 PK(主键)或索引查找。他们删除了所有 JOIN。

译者语,Pinterest 高速发展的时期正好也出现了各种新数据库系统。尤其是 NoSQL 这块,除了 Pinterest 提到过的这些,还有 Riak, Tokyo Cabinet, Voldemort 等。 还是那句话,我们应该采用无聊的技术去构建创新的产品,而不是倒过来。


💡 更多资讯,请关注 Bytebase 公号:Bytebase

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1351630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ARM NEON 指令

NEON指令 按照操作数类型可以分为正常指令、宽指令、窄指令、饱和指令、长指令。 正常指令:生成大小相同且类型通常与操作数向量相同到结果向量。长指令:对双字向量操作数执行运算,生产四字向量到结果。所生成的元素一般是操作数元素宽度到…

从0搭建github.io网页

点击跳转到🔗我的博客文章目录 从0搭建github.io网页 文章目录 从0搭建github.io网页1.成果展示1.1 网址和源码1.2 页面展示 2.new对象2.1 创建仓库 3.github.io仓库的初始化3.1 千里之行,始于足下3.2 _config.yml3.3 一点杂活 4.PerCheung.github.io.p…

Qt(三):udp组播的发送与接收

1. 创建UDP套接字 使用QUdpSocket类创建一个UDP套接字。 udpSendnew QUdpSocket(this);udpRecenew QUdpSocket(this); 2. 绑定套接字 绑定套接字到一个本地地址和端口。可以使用bind()函数来完成。 如果要在组播中发送数据,可以将套接字绑定到一个通配符地址&#…

【CASS精品教程】CASS11计算城镇建筑密度

CASS中可以很方便计算建筑密度。 文章目录 一、建筑密度介绍二、CASS计算建筑密度1. 绘制宗地范围2. 绘制建筑物3. 计算建筑密度三、注意事项一、建筑密度介绍 建筑密度(building density;building coverage ratio),指在一定范围内,建筑物的基底面积总和与占用地面积的比…

计算机网络-以太网交换基础

一、网络设备的演变 最初的网络在两台设备间使用传输介质如网线等进行连接就可以进行通信。但是随着数据的传输需求,多个设备需要进行数据通信时就需要另外的设备进行网络互联,并且随着网络传输的需求不断更新升级。从一开始的两台设备互联到企业部门内部…

【OpenCV】在MacOS上源码编译OpenCV

在MacOS上源码编译OpenCV 1. 下载项目源码2. 创建CMake编译文件3. 编译安装4. 案例测试5. 总结 前言 在做视觉任务时,我们经常会用到开源视觉库OpenCV,OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件…

Spring技术内幕笔记之IOC的实现

IOC容器的实现 依赖反转: 依赖对象的获得被反转了,于是依赖反转更名为:依赖注入。许多应用都是由两个或者多个类通过彼此的合作来实现业务逻辑的,这使得每个对象都需要与其合作的对象的引用,如果这个获取过程需要自身…

Java学习苦旅(十六)——List

本篇博客将详细讲解Java中的List。 文章目录 预备知识——初识泛型泛型的引入泛型小结 预备知识——包装类基本数据类型和包装类直接对应关系装包与拆包 ArrayList简介ArrayList使用ArrayList的构造ArrayList常见操作ArrayList遍历 结尾 预备知识——初识泛型 泛型的引入 我…

WebStorm 创建一个Vue项目(1)

一、下载并安装WebStorm 步骤一 步骤二 选择激活方式 激活码: I2A0QUY8VU-eyJsaWNlbnNlSWQiOiJJMkEwUVVZOFZVIiwibGljZW5zZWVOYW1lIjoiVU5JVkVSU0lEQURFIEVTVEFEVUFMIERFIENBTVBJTkFTIiwiYXNzaWduZWVOYW1lIjoiVGFvYmFv77yaSkVU5YWo5a625qG25rAIOa0uW3peS9nOWup…

json解析本地数据,使用JSONObject和JsonUtility两种方法。

json解析丨网址、数据、其他信息 文章目录 json解析丨网址、数据、其他信息介绍一、文中使用了两种方法作为配置二、第一种准备2.代码块 二、第二种总结 介绍 本文可直接解析本地json信息的功能示例,使用JSONObject和JsonUtility两种方法。 一、文中使用了两种方法…

R语言——R函数、选项参数、数学统计函数(六)

目录 一、R函数 二、选项参数 三、数学统计函数 四、参考 一、R函数 1.lm() lm()是R语言中经常用到的函数&#xff0c;用来拟合回归模型。它是拟合线性模型最基本的函数 lm()格式如下&#xff1a; fit<-lm(formula,data) 其中&#xff0c;formula指要拟合的模型形式…

【QT 自研上位机 与 ESP32下位机联调>>>串口控制GPIO-基础样例-联合文章】

【QT 自研上位机 与 ESP32下位机联调&#xff1e;&#xff1e;&#xff1e;串口控制GPIO-基础样例-联合文章】 1、概述2、实验环境3、 自我总结4、 实验过程1、验证上位机QT程序1、下载样例代码2、修改qt程序3、运行测试验证 2、验证下位机ESP32程序1、下载样例代码2、更改ESP3…

Ubuntu18 安装chatglm2-6b

记了下Ubuntu18 上安装chatglm2-6遇到的问题。 环境&#xff1a;Ubuntu18.04 V100(显卡) nvcc 11.6 显卡驱动cudacudnnaniconda chatglm6b 的安装 网上有很多&#xff0c; 不记录 了。 chatglm2-6b 我从别的地方拷贝的&#xff0c; 模型也包含了。 遇到的问题&#xf…

【MMC子系统】三、MMC子系统框架

我的圈子&#xff1a; 高级工程师聚集地 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强企业&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; …

【SpringBoot开发】之商城项目案例(购物车相关操作)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringBoot开发之商城项目系列》。&#x1f3af…

GZ075 云计算应用赛题第4套

2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷4 某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenSt…

Pytorch上采样

文章目录 Upsample特殊上采样 Upsample 所谓上采样&#xff0c;实则是一个插值过程。所以上采样对象在初始化时&#xff0c;需要指定一个插值类型&#xff0c;Upsample是torch.nn中最基础的上采样类&#xff0c;初始化参数如下 Upsample(sizeNone, scale_factorNone, modenea…

计算机组成原理 主存和CPU连接与主存提速方案

文章目录 主存与CPU的连接译码器线选法译码片选法总结 位拓展字拓展字位同时拓展 主存提速方案存储周期双端口RAM多模块存储器单体多字存储器多模块多体并行存储器存储器高位交叉编址低位交叉编址 主存与CPU的连接 #mermaid-svg-3wv6WzRP2BvKEHQZ {font-family:"trebuchet…

GZ075 云计算应用赛题第1套

2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷1 某企业根据自身业务需求,实施数字化转型,规划和建设数字化平台,平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”,拟采用开源OpenStack搭建企业内部私有云平台,开源Kubernetes搭建云原生服务平台,…

HTML5 和 CSS3 新特性(常用)

HTML5 的新特性 HTML5 的新增特性主要是针对于以前的不足&#xff0c;增加了一些新的标签、新的表单和新的表单属性等。 这些新特性都有兼容性问题&#xff0c;基本是 IE9 以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量使用这 些新特性。 HTML…