Instagram技术文章导读系列-1
因为对Django蛮有兴趣的,同时又很好奇上亿级别的应用是怎么使用Django的
在知道Instagram也是用Django开发后,就蛮有兴趣了他们是怎么做系统架构与优化的
而他们团队在2011-2019年之间在Medium上有一系列的技术文章
我会针对一些我感兴趣的主题去做导读与添加一点点个人观点
而今天来看一篇2012年,Instagram团队写有关PostreSQL的技术文章:
Ig开发团队使用Django(基于python的Web框架)做开发,并且使用PostgreSQL做为资料库。在2012年的Instagram每秒就需要处理25张照片上传跟90个赞(2013年就成长到每秒破万赞数请求,现在更不敢想)
面对这样大量的资料不可能使用单一资料库做储存,所以需要将资料进行Sharding(底下简称分片)
但这样做的同时也代表:
Ig开发团队有考虑过不同的NoSQL解决方案,像针对上述情境Elasticsearch就能很好的处理,但最终还是决定在PostgreSQL上继续最为主力开发
PostgreSQL具备Schema这个特性(不是SQL schema),通常在单一DB层级中,表名是唯一的但是PostgreSQL可以在单一DB层级中建立多个Schema,每个Schema内则是可以建立表格。这就代表不同的Schema内可以有同表名的表格。在这个架构中,每一个Schema就相当于一个Shard
例如有一个表格名称为photo,负责储存用户上传的照片。大量的资料被分割成不同片段(Shard)这些分片被存到不同的Schema中,并且都是存在名为photo的表格中这样的设计架构在处理多租户模式时相当好用,因为资料隔离特性的缘故而在这个架构中,就不需要建立多个DB,而是在单一DB中就能储存多个分片
但是这时候回到开头说的第一个问题:ID的问题
在多方汇入资料的情境下,需要有一个方式能够维持资料的排序,又要不依赖太多额外套件(这是Ig开发团队的核心宗旨之一),并且为了兼容性ID最好是64位元
最后Ig开发团队选择使用PL/PGSQL、Postgres 的内部程式语言以及 Postgres 现有的自动增量功能来进行实现,同时制定ID组成:
41 位用于毫秒级时间戳13 位用于逻辑分片 ID10 位用于自增序列号(每毫秒每分片最多 1024 个 ID)
这样的作法有以下特点:
当然这是相当简化的版本,实际上还要考虑许多问题:
但是可能当下Ig团队考虑到其他需求,最终还是决定使用PostgreSQL最为主力,Elasticsearch等NoSQL为辅,而这样的决定完全不影响他们家产品日后的成长与成功
原文连结:https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c