+23

Cách Instagram đạt tới 14 triệu người dùng chỉ với 3 kỹ sư

Instagram chỉ mất hơn 1 năm, từ tháng 10 năm 2010 đến tháng 12 năm 2011, để từ con số 0 người dùng tăng vọt lên 14 triệu người dùng, và chỉ với... 3 kỹ sư!

Họ đã đạt được điều này bằng cách tuân thủ 3 nguyên tắc cốt lõi và sở hữu một bộ công nghệ nền tảng đáng tin cậy. Hãy cùng khám phá xem họ đã làm như thế nào.

Nguyên tắc hoạt động của Instagram

  1. Giữ mọi thứ đơn giản: Trong giai đoạn đầu, Instagram tập trung vào những tính năng cốt lõi như chia sẻ ảnh và video, bỏ qua những chức năng phức tạp không cần thiết. Điều này giúp họ dễ dàng phát triển, vận hành và bảo trì hệ thống, đồng thời mang đến trải nghiệm người dùng trực quan và dễ hiểu.
  2. Sử dụng công nghệ đã được kiểm chứng: Instagram không cố gắng "phát minh lại bánh xe". Họ sử dụng các công nghệ như Python, Django và Gunicorn, vốn đã được thử nghiệm và tin cậy trong ngành công nghệ. Điều này giúp họ tiết kiệm thời gian và công sức phát triển, đồng thời đảm bảo tính ổn định và bảo mật của hệ thống.
  3. Tập trung vào hiệu suất: Instagram ưu tiên tối ưu hóa tốc độ tải trang và thời gian phản hồi. Họ liên tục theo dõi và cải thiện hiệu suất của hệ thống, đảm bảo người dùng có trải nghiệm nhanh chóng và mượt mà.

Câu chuyện về sự phát triển vượt bậc của Instagram chỉ với 3 kỹ sư là một minh chứng cho sức mạnh của sự đơn giản, tin cậy và hiệu quả. Họ đã chứng minh rằng không cần phải có một đội ngũ hùng hậu để tạo ra một sản phẩm thành công, mà chỉ cần tập trung vào những điều cốt lõi và thực hiện chúng một cách xuất sắc.Hy vọng câu chuyện này sẽ truyền cảm hứng cho bạn trong hành trình khởi nghiệp hoặc phát triển sản phẩm của mình!

Đơn giản hóa Cấu trúc của Instagram

Để hiểu cách vận hành ban đầu của Instagram, chúng ta cùng nhìn vào cơ sở hạ tầng của họ, được xây dựng trên Amazon Web Services (AWS) bằng dịch vụ EC2 với hệ điều hành Ubuntu Linux. EC2 là dịch vụ cho thuê máy tính ảo của Amazon dành cho các nhà phát triển.

Để dễ hình dung và thấu hiểu góc nhìn kỹ sư, hãy cùng theo dõi hành trình của một phiên sử dụng của người dùng Instagram. (Đánh dấu bằng Session)

Frontend

Session: Một người dùng mở ứng dụng Instagram.

Instagram ban đầu được phát hành dưới dạng ứng dụng iOS vào năm 2010. Vì Swift mới được phát hành vào năm 2014, nên có thể chắc chắn rằng Instagram được viết bằng Objective-C kết hợp với các thư viện khác như UIKit để xây dựng giao diện người dùng.

b1f72ce0-1963-4176-a493-517a1788a277_374x395.png

Load Balancing

Session: Sau khi mở ứng dụng, một yêu cầu lấy ảnh của nguồn cấp chính được gửi đến phía backend, nơi nó sẽ chạm vào trình cân bằng tải của Instagram.

Instagram đã sử dụng Trình cân bằng tải đàn hồi (Elastic Load Balancer) của Amazon. Họ có 3 phiên bản NGINX có thể được trao đổi linh hoạt tùy thuộc vào trạng thái hoạt động của chúng.

Mỗi yêu cầu sẽ đi qua trình cân bằng tải trước khi được chuyển tiếp đến máy chủ ứng dụng thực tế.

Để giải thích rõ hơn:

  • Trình cân bằng tải đàn hồi (Elastic Load Balancer - ELB): Đây là một dịch vụ của Amazon Web Services (AWS) giúp phân phối lưu lượng truy cập đến các máy chủ khác nhau một cách hợp lý, nhằm đảm bảo hiệu suất và tính khả dụng của ứng dụng.
  • NGINX: Đây là một máy chủ web mã nguồn mở, được sử dụng để phục vụ các trang web và ứng dụng web. Instagram đã sử dụng 3 phiên bản NGINX để tăng khả năng chịu tải và khả năng mở rộng của hệ thống.
  • Trao đổi linh hoạt: Các phiên bản NGINX có thể được tự động đưa vào hoặc loại bỏ khỏi hệ thống dựa trên trạng thái hoạt động của chúng. Điều này giúp đảm bảo rằng chỉ những phiên bản khỏe mạnh mới xử lý các yêu cầu của người dùng.
  • Chuyển tiếp yêu cầu: Khi một yêu cầu đến, ELB sẽ chuyển tiếp nó đến một trong các phiên bản NGINX đang hoạt động. Phiên bản NGINX này sau đó sẽ xử lý yêu cầu và gửi phản hồi trở lại cho người dùng.

c2e2b88d-751d-4c2c-b87e-95cd90aef20e_642x395.png

Backend

Session: Trình cân bằng tải chuyển tiếp yêu cầu đến máy chủ ứng dụng, nơi chứa logic cần thiết để xử lý yêu cầu một cách chính xác.

Máy chủ ứng dụng của Instagram sử dụng Django, được viết bằng Python, với Gunicorn đóng vai trò là máy chủ WSGI.

Để nhắc lại, WSGI (Web Server Gateway Interface - Giao diện cổng máy chủ web) là một giao thức giúp chuyển tiếp các yêu cầu từ máy chủ web đến ứng dụng web.

Instagram sử dụng Fabric để chạy các lệnh song song trên nhiều phiên bản cùng một lúc. Điều này cho phép triển khai mã chỉ trong vài giây.

Hệ thống này hoạt động trên hơn 25 máy chủ Amazon High-CPU Extra-Large. Vì bản thân máy chủ không lưu trạng thái, nên khi cần xử lý nhiều yêu cầu hơn, họ có thể dễ dàng bổ sung thêm máy chủ.

d644ba96-4f13-4fe2-8e9f-e01cdec85171_1005x395.png

General Data Storage

Session: Máy chủ ứng dụng nhận thấy rằng yêu cầu cần dữ liệu cho nguồn cấp dữ liệu chính. Để đáp ứng điều này, giả sử máy chủ cần:

  1. ID ảnh mới nhất có liên quan: Những ID này xác định những bức ảnh nên được hiển thị trong nguồn cấp dữ liệu.
  2. Ảnh thực tế khớp với các ID ảnh đó: Máy chủ cần truy xuất các ảnh thực tế từ kho lưu trữ để hiển thị chúng cho người dùng.
  3. Dữ liệu người dùng cho những ảnh đó: Bao gồm thông tin như tên người dùng, ảnh đại diện và thông tin mô tả đi kèm với mỗi bức ảnh.

Database: Postgres

Session: Máy chủ ứng dụng lấy các ID ảnh mới nhất có liên quan từ Postgres

Máy chủ ứng dụng sẽ lấy dữ liệu từ PostgreSQL, nơi lưu trữ hầu hết dữ liệu của Instagram, chẳng hạn như người dùng và siêu dữ liệu ảnh.

Các kết nối giữa Postgres và Django được kết hợp (pooled) bằng Pgbouncer để tối ưu hóa việc sử dụng kết nối và cải thiện hiệu suất.

Instagram đã phân mảnh (sharding) dữ liệu của họ do khối lượng lớn dữ liệu họ nhận được (hơn 25 ảnh và 90 lượt thích mỗi giây). Họ đã sử dụng mã để ánh xạ vài nghìn phân mảnh 'logic' thành một số phân mảnh vật lý.

Một thách thức thú vị mà Instagram phải đối mặt và giải quyết là tạo ra các ID có thể sắp xếp theo thời gian. Các ID sắp xếp theo thời gian của họ trông như thế này:

  • 41 bit cho thời gian tính bằng mili giây (cung cấp 41 năm ID với kỷ nguyên tùy chỉnh)
  • 13 bit đại diện cho ID phân mảnh logic
  • 10 bit đại diện cho một chuỗi tự động tăng, modulo 1024. Điều này có nghĩa là họ có thể tạo 1024 ID, mỗi phân mảnh, mỗi mili giây

Nhờ các ID có thể sắp xếp theo thời gian trong Postgres, máy chủ ứng dụng đã nhận thành công các ID ảnh mới nhất có liên quan.

Photo Storage: S3 and Cloudfront

Session: Máy chủ ứng dụng sau đó truy xuất các ảnh thực tế khớp với những ID ảnh đó bằng các liên kết CDN nhanh để đảm bảo chúng tải nhanh cho người dùng.

Hàng terabyte ảnh được lưu trữ trên Amazon S3. Những ảnh này được cung cấp cho người dùng một cách nhanh chóng thông qua Amazon CloudFront.

Caching: Redis and Memcached

Session: Để lấy dữ liệu người dùng từ Postgres, máy chủ ứng dụng (Django) khớp các ID ảnh với ID người dùng bằng Redis.

Instagram sử dụng Redis để lưu trữ ánh xạ của khoảng 300 triệu ảnh với ID người dùng đã tạo ra chúng. Điều này giúp họ biết shard nào cần truy vấn khi lấy ảnh cho nguồn cấp dữ liệu chính, nguồn cấp hoạt động, v.v. Toàn bộ Redis được lưu trữ trong bộ nhớ (in-memory) để giảm độ trễ và nó được phân mảnh trên nhiều máy.

Với một số kỹ thuật hash thông minh, Instagram đã có thể lưu trữ 300 triệu ánh xạ khóa trong chưa đầy 5 GB. (o.O)

Ánh xạ khóa-giá trị từ photoID sang userID này là cần thiết để biết shard Postgres nào cần truy vấn.

Session: Nhờ vào việc sử dụng bộ nhớ đệm hiệu quả của Memcached, việc lấy dữ liệu người dùng từ Postgres rất nhanh vì phản hồi đã được lưu trong bộ nhớ đệm gần đây.

Đối với việc lưu trữ bộ nhớ đệm chung, Instagram đã sử dụng Memcached. Họ có 6 phiên bản Memcached vào thời điểm đó. Memcached tương đối đơn giản để tích hợp với Django.

Một sự thật thú vị: 2 năm sau, vào năm 2013, Facebook đã phát hành một bài báo mang tính bước ngoặt về cách họ mở rộng quy mô Memcached để giúp họ xử lý hàng tỷ yêu cầu mỗi giây.

Session: Người dùng hiện thấy nguồn cấp dữ liệu chính, được hiển thị với những bức ảnh mới nhất từ những người mà họ đang theo dõi.

96c6476f-b900-4591-a672-295048bda0a4_1466x597.png

Master-Replica Setup

Cả Postgres và Redis đều chạy trong thiết lập master-replica và sử dụng tính năng snapshort của Amazon EBS (Elastic Block Store) để sao lưu hệ thống thường xuyên.

Push Notifications và Async Tasks

Session: Bây giờ, giả sử người dùng đóng ứng dụng nhưng sau đó nhận được thông báo đẩy cho biết một người bạn vừa đăng ảnh.

Thông báo đẩy này được gửi bằng pyapns, cùng với hơn một tỷ thông báo đẩy khác mà Instagram đã gửi trước đó. Pyapns là một nhà cung cấp Apple Push Notification Service (APNS) mã nguồn mở, đa năng.

Session: Người dùng thực sự thích bức ảnh này! Vì vậy, anh ấy quyết định chia sẻ nó trên Twitter.

Ở phía backend, tác vụ được đưa vào Gearman, một hàng đợi tác vụ phân công công việc cho các máy phù hợp hơn. Instagram có khoảng 200 Python worker sử dụng hàng đợi tác vụ Gearman.

Gearman được sử dụng cho nhiều tác vụ bất đồng bộ như đẩy các hoạt động (như ảnh mới được đăng) đến tất cả người theo dõi của một người dùng (được gọi là fanout).

b586cf1d-c74f-4166-abe3-c143c54c4151_682x678.png

Monitoring

Session: Ồ không! Ứng dụng Instagram bị trục trặc do một lỗi trên máy chủ gửi về phản hồi sai lầm. Ba kỹ sư của Instagram ngay lập tức nhận được cảnh báo.

Instagram sử dụng Sentry, một ứng dụng Django mã nguồn mở, để theo dõi lỗi Python theo thời gian thực.

Munin được sử dụng để vẽ đồ thị các số liệu hệ thống và cảnh báo bất thường. Instagram có một số plug-in Munin tùy chỉnh để theo dõi các số liệu cấp ứng dụng, chẳng hạn như ảnh được đăng mỗi giây.

Pingdom được sử dụng để theo dõi dịch vụ bên ngoài và PagerDuty được sử dụng để xử lý sự cố và thông báo.

Tổng quan về kiến trúc

a279781f-8c76-4e67-8a63-6b9930d1a48c_1984x937.png


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí