Rate this post

Làm thế nào để Facebook, với hàng tỷ người dùng hoạt động hàng tháng, quản lý để phục vụ tất cả người dùng trên toàn cầu mà hầu như không có bất kỳ thời gian ngừng hoạt động nào. Chúng ta hãy có một cái nhìn!

Các bài viết liên quan:

Điều đầu tiên, chúng ta hãy xem xét các yêu cầu trước.

Yêu cầu chức năng

  • Bài đăng – Văn bản, hình ảnh, video, liên kết, v.v.
  • Thích bình luận chia sẻ
  • Thêm bạn bè – mối quan hệ không định hướng
  • Xem dòng thời gian
  • Xem bài đăng, hồ sơ của người dùng
  • Nhật ký hoạt động – về lượt thích, nhận xét và chia sẻ

Những yêu cầu vô lý

  • Tỷ lệ đọc nặng – đọc để ghi rất cao
  • Kết xuất và đăng tải nhanh chóng
  • Trễ là được, nhưng độ trễ phải thấp – sẽ không sao nếu chúng tôi nhận được thông báo về bài đăng của ai đó trễ vài phút, nhưng sau khi nhận được, nó sẽ hiển thị gần như ngay lập tức
  • Mẫu truy cập cho bài đăng – thực hiện tối ưu hóa để nội dung phương tiện có thể dễ dàng truy cập khi bài đăng có lượng tương tác tối đa
  • Khả dụng trên toàn cầu – trên nhiều thiết bị, hỗ trợ nhiều ngôn ngữ và tất cả các loại băng thông internet
  • Có thể mở rộng

Bây giờ trước khi thảo luận về kiến ​​trúc, chúng ta sẽ phân loại người dùng thành năm danh mục và mỗi danh mục này sẽ được xử lý khác nhau một chút. 

Các danh mục này là – Người dùng nổi tiếng, Người dùng đang hoạt động, Người dùng trực tiếp, Người dùng thụ động và Người dùng không hoạt động.

Facebook hiện có giới hạn về số lượng bạn bè mà bạn có thể có, vì vậy những người dùng nổi tiếng không thực sự là một điều cần thiết. 

Nhưng trong trường hợp một yêu cầu như vậy xuất hiện, chẳng hạn trong trường hợp của một hệ thống như Instagram, người dùng nổi tiếng sẽ là người dùng có nhiều bạn bè hoặc người theo dõi. 

Người dùng đang hoạt động là những người đã truy cập vào hệ thống gần đây, trong trường hợp của chúng tôi là trong vòng ba ngày qua. 

Người dùng trực tiếp là những người đang sử dụng ứng dụng hiện tại. Người dùng thụ động là người dùng không nổi tiếng không hoạt động và người dùng không hoạt động về cơ bản là tài khoản đã bị xóa mềm.

Kiến Trúc Hệ Thống Facebook

Để đơn giản, chúng tôi đã chia kiến ​​trúc tổng thể thành nhiều luồng.

Các hoạt động liên quan đến việc giới thiệu người dùng, đăng nhập và hồ sơ người dùng do một dịch vụ người dùng xử lý. 

Dịch vụ người dùng nằm trên cơ sở dữ liệu MySQL, Mysql vì nó là một dữ liệu rất quan hệ theo quan điểm cấu trúc. 

Ngoài ra, thông tin người dùng sẽ khó đọc hơn ghi, và MySQL là đủ cho một mẫu truy vấn như vậy. 

Dịch vụ người dùng cũng được kết nối với Redis để lưu vào bộ nhớ đệm tất cả thông tin người dùng. 

Khi dịch vụ người dùng nhận được một yêu cầu, đầu tiên nó sẽ được tra cứu trong Redis. Nếu Redis có thông tin, nó sẽ được trả lại cho người dùng, 

nếu không, dịch vụ người dùng kiểm tra trong MySQL DB sẽ chèn thông tin vào Redis để sử dụng trong tương lai, rồi trả lại cho người dùng. 

Ngoài ra, bất cứ khi nào người dùng mới được thêm vào hoặc thông tin được cập nhật, một sự kiện sẽ được chèn vào Kafka để các dịch vụ khác trong hệ thống biết về sự thay đổi.

Thêm bạn bè thì sao? Nó hoạt động như thế nào?

Đây là nơi dịch vụ đồ thị xuất hiện. Nó theo dõi mối quan hệ giữa người dùng, trọng số của họ, v.v. Dịch vụ đồ thị lại nằm trên cơ sở dữ liệu MySQL, MySQL vì dữ liệu này sẽ đơn giản là ánh xạ của id người dùng, id bạn bè và những thông tin như vậy khác liên quan đến mối quan hệ giữa hai người dùng, đó là một dữ liệu rất có cấu trúc. 

Giờ đây, dịch vụ đồ thị lại duy trì bộ nhớ cache trong Redis để mỗi khi chúng tôi cần tìm nạp bạn bè của người dùng, chúng tôi không phải truy vấn lại MySQL DB.

Một điều khác mà chúng tôi lưu vào bộ nhớ cache trong Redis là kiểu người dùng, tức là nếu người dùng đang hoạt động hoặc sống hoặc nổi tiếng, v.v. 

Thẻ liên quan là một thứ khác được lưu trong bộ nhớ cache trong Redis, để đảm bảo dòng thời gian của người dùng phù hợp hơn với sở thích của họ. 

Ví dụ: các bài đăng liên quan đến thể thao sẽ được hiển thị cho những người bạn quan tâm đến thể thao hơn, tương tự, những người đam mê du lịch sẽ thấy những gì bạn bè của họ đăng về du lịch. 

Đây là cách Facebook làm cho trải nghiệm hấp dẫn và thú vị hơn cho người dùng. Cuối cùng, chúng tôi cũng sẽ lưu trữ lần cuối được nhìn thấy cho người dùng trong Redis, điều này có thể hữu ích trong trường hợp chúng tôi xây dựng chức năng trò chuyện trong tương lai.

Bây giờ chúng ta hãy bắt đầu với kiến ​​trúc của hệ thống. Một lần nữa chúng tôi sẽ chia hệ thống thành nhiều luồng người dùng khác nhau. Trước tiên, hãy xem cách người dùng đăng nội dung và cách họ truy xuất dòng thời gian của họ.

Có một thành phần được gọi là dịch vụ URL ngắn, sẽ rút ngắn các URL dài hơn sẽ được đăng trên nền tảng của chúng tôi và khi người dùng nhìn thấy bài đăng này nhấp vào liên kết ngắn, họ sẽ được chuyển hướng đến URL ban đầu. 

Tất cả điều này được thực hiện bởi dịch vụ URL ngắn. Chúng tôi sẽ không thảo luận về cách dịch vụ này hoạt động, nhưng bạn có thể xem qua hướng dẫn thiết kế hệ thống URL nhỏ của chúng tôi, nơi chúng tôi đã giải thích chi tiết về vấn đề này. 

Bây giờ, một thành phần quan trọng khác mà chúng tôi có là dịch vụ tài sản. Hãy nhớ rằng bài đăng của chúng tôi có thể có liên kết, văn bản, hình ảnh và video. 

Ngoài ra, ảnh và video sẽ được đăng từ các loại thiết bị khác nhau, điều này cũng ảnh hưởng đến tỷ lệ co, độ phân giải của hình ảnh, v.v. 

Giả sử người dùng đăng ảnh vuông từ máy tính xách tay của họ, ảnh đó có thể không đẹp trên điện thoại di động. 

Hoặc giả sử một người dùng trên mạng rất nhanh đăng video có độ phân giải cao và độ nét rất cao, video này sẽ mất nhiều thời gian để tải trên internet tốc độ chậm. Đây là lúc dịch vụ nội dung của chúng tôi xuất hiện. 

Dịch vụ nội dung sẽ đảm nhận việc chuyển đổi việc truyền trực tuyến tệp sang nhiều định dạng, tỷ lệ khung hình và băng thông mạng. Một lần nữa, chúng tôi không thảo luận chi tiết về dịch vụ Nội dung vì chúng tôi đã giải thích nó trong hướng dẫn thiết kế hệ thống Netflix của chúng tôi, vì vậy hãy đảm bảo xem qua điều đó.

Hãy nhớ cách chúng tôi đã đề cập đến mô hình truy cập trong NFR của chúng tôi? Rằng bài viết sẽ nhận được rất nhiều sức hút khi nó vừa được đăng lên, và theo thời gian thì mức độ phổ biến sẽ giảm dần. 

Khi bài đăng không được truy cập thường xuyên, chúng tôi có thể xóa bài đăng đó khỏi CDN và một số nội dung khác có thể sử dụng cùng dung lượng. 

Đây là một điều khác mà tài sản chăm sóc. Nó quyết định nội dung nào đi vào CDN và nội dung nào đi vào S3, nơi chúng tôi đang sử dụng làm kho lưu trữ tài sản vĩnh viễn. Bây giờ, giả sử một người nổi tiếng thích ảnh cũ của một người nổi tiếng khác. 

Bây giờ, bức ảnh này sẽ lại nhận được rất nhiều lực kéo, vì vậy nó sẽ được kéo từ S3 sang CDN ở các vị trí địa lý mà nó đang được truy cập thường xuyên.

Nhưng làm thế nào để người dùng của chúng tôi đăng nội dung của họ?

Đây là nơi dịch vụ nhập bài đăng của chúng tôi hoạt động. Nếu bài đăng có âm thanh / video hoặc hình ảnh, dịch vụ nhập bài đăng sẽ liên hệ với dịch vụ nội dung. 

Nếu bài đăng có liên kết, dịch vụ nhập bài đăng sẽ nói chuyện với dịch vụ URL ngắn. Sau đó, nội dung cuối cùng sẽ được tiếp tục trong Cassandra. 

Bây giờ một khi bài đăng được lưu vào Cassandra, thông tin bài đăng sẽ được cung cấp cho dịch vụ Đăng. 

Nó cũng sẽ hiển thị các API cho các dịch vụ khác để truy cập vào tất cả các bài đăng. Khi một bài đăng xuất hiện, dịch vụ nhập bài đăng cũng kích hoạt một sự kiện vào Kafka, sự kiện này sẽ tiếp tục chuyển sự kiện đó cho các hệ thống con khác. 

Giờ đây, Kafka cũng được kết nối với hệ thống con của Analytics, hệ thống này sẽ có một loạt người tiêu dùng phát trực tuyến lắng nghe các sự kiện này. 

Những người tiêu dùng này bây giờ sẽ phân loại bài đăng thành các danh mục khác nhau với sự trợ giúp của một số thuật toán ML. 

Sau khi một danh mục được gắn thẻ vào bài viết, nó sẽ được gửi đến Kafka. Sau đó đến bộ xử lý bài. 

Bộ xử lý bài đăng, cũng nhận bài đăng được gắn thẻ này, nói chuyện với dịch vụ người dùng và dịch vụ nhóm để tìm nạp bạn bè của người dùng này, 

những người có thể xem bài đăng này và tìm ra các thẻ liên quan để tìm ra người dùng nào có thể quan tâm đến bài đăng này. 

Nó đưa ra một tập hợp con gồm những người bạn của người dùng, những người hiện sẽ thấy bài đăng này và đưa tất cả các bài đăng có liên quan vào Redis. 

Bây giờ bạn có thể nhớ từ hướng dẫn thiết kế hệ thống Twitter của chúng tôi, rằng Redis cũng đang lưu vào bộ nhớ đệm các dòng thời gian của tất cả người dùng. 

Vì vậy, khi chúng tôi phát hiện ra rằng một bài đăng có liên quan đến một chủ đề cụ thể, dòng thời gian của họ sẽ được cập nhật với bài đăng mới này.

Điều gì xảy ra khi một người dùng đến dòng thời gian của họ?

Khi một người nhìn thấy dòng thời gian của một số người dùng khác, một yêu cầu sẽ được gửi đến dịch vụ dòng thời gian, dịch vụ này sẽ truy vấn thêm dịch vụ đăng dịch vụ để tìm nạp tất cả các bài đăng của người dùng cụ thể đó và trả lại cho người dùng đó. 

Khi một người cố gắng xem dòng thời gian của chính họ, yêu cầu sẽ được gửi đến dịch vụ dòng thời gian, dịch vụ này sẽ tìm nạp tất cả các bài đăng của tất cả bạn bè từ Redis (tham khảo hướng dẫn thiết kế hệ thống Twitter). 

Giả sử chúng tôi đang xây dựng một cái gì đó giống như Instagram, nơi người dùng của chúng tôi có thể theo dõi một số người rất nổi tiếng. 

Bây giờ khi một người cố gắng xem dòng thời gian của họ, dịch vụ dòng thời gian đã có các bài đăng của tất cả những người dùng bình thường. 

Nó sẽ tìm thấy những người bạn nổi tiếng của người dùng từ dịch vụ người dùng và nhóm. Khi nó có những người bạn nổi tiếng của người dùng của chúng tôi, dịch vụ dòng thời gian sẽ nói chuyện với dịch vụ đăng bài để tìm nạp tất cả các bài đăng mới của tất cả những người dùng nổi tiếng bằng id của họ. 

Dữ liệu này hiện cũng có thể được lưu giữ trong Redis với một dấu thời gian. Bây giờ, lần tiếp theo dịch vụ dòng thời gian của chúng tôi nhận được truy vấn, chúng tôi sẽ kiểm tra xem dấu thời gian có phải là từ vài giây trước hay không. 

Nếu dấu thời gian là từ vài phút trước, chúng tôi sẽ tìm nạp lại thông tin từ dịch vụ Đăng để xem có bài đăng mới nào đến từ những người dùng nổi tiếng của chúng tôi hay không.

Bây giờ chúng tôi đã xử lý thành công những người dùng tích cực và nổi tiếng của mình. Nhưng bạn có nghĩ rằng những người dùng trực tiếp của chúng tôi sẽ được đối xử đặc biệt không?

Khi bài đăng đến bộ xử lý bài đăng, nó cũng đã truy vấn dịch vụ người dùng, vì vậy nó biết những người dùng nào đang hoạt động. 

Vì vậy, cùng với việc viết vào Redis, bộ xử lý bài đăng cũng sẽ gửi một sự kiện đến Kafka nói rằng người dùng này đang hoạt động và dòng thời gian của họ cần được cập nhật. 

Đây là nơi dịch vụ người dùng trực tiếp xuất hiện. Nó duy trì kết nối mở với tất cả người dùng Ứng dụng và Web và thông báo cho họ về bài đăng mới.

Bây giờ có một cái gì đó được gọi là một dịch vụ lưu trữ. Như chúng ta đã biết, Redis không thể lưu trữ nhiều dữ liệu. 

Vì vậy, chúng tôi sẽ chỉ lưu trữ dữ liệu của ngày hôm nay trong Redis và đối với các bài đăng cũ, chúng tôi sẽ sử dụng dịch vụ lưu trữ. 

Bây giờ vấn đề với dòng thời gian là những thứ mới sẽ được thêm vào nó, nhưng những thứ cũ sẽ vẫn như cũ. 

Vì vậy, chúng tôi có thể lưu trữ toàn bộ nội dung vào một kho lưu trữ dữ liệu lâu dài hơn như Cassandra. 

Vì vậy, đôi khi trong ngày, dịch vụ lưu trữ sẽ tìm nạp tất cả dòng thời gian của người dùng và đưa nó vào dòng thời gian tổng hợp Cassandra và xóa bộ nhớ cache của Redis.

HotSpots!

Giờ đây, dù chúng tôi đang sử dụng Cassandra ở đâu, chúng tôi đều có nguy cơ tạo ra một điểm phát sóng. 

Điều đó có nghĩa là, nếu chúng tôi không phân vùng dữ liệu cẩn thận, chúng tôi có thể kết thúc bằng một Cassandra được phân phối trên nhiều máy khác nhau để chỉ một số máy đang xử lý phần lớn tải. 

Điều này có thể xảy ra nếu chúng tôi phân vùng dữ liệu dựa trên ngày tháng, thay vì thứ gì đó chung chung hơn như id người dùng. 

Giả sử tất cả các bài viết từ hôm qua đến cùng một máy, thì miễn là bài viết có nhiều lực kéo, Cassandra đơn lẻ đó sẽ có rất nhiều lưu lượng truy cập, chuyển nó thành điểm nóng.

Thích, bình luận và chia sẻ!

Vâng, nó hoạt động như thế nào? Vì vậy, chúng tôi có một giao diện người dùng like / comment, có thể là điện thoại hoặc máy tính xách tay. Khi người dùng nhấn vào nút thích, yêu cầu sẽ được gửi đến dịch vụ thích. 

Dịch vụ thích sẽ đảm nhận việc tìm nạp lượt thích cho một bài đăng, thêm lượt thích vào bài đăng, về cơ bản là bất kỳ thứ gì và mọi thứ “thích”. 

Bất cứ khi nào một bài đăng được thích, thông tin sẽ được lưu trữ trong Cassandra. Thông tin này có thể là id bài đăng, loại bài đăng như bình luận hoặc bài đăng, và người dùng đã thích. 

Bây giờ thông tin này, tức là không có lượt thích đối với một bài đăng cũng sẽ được lưu trữ trong Redis so với các bài đăng gần đây. Vì vậy, khi một lượt thích xuất hiện và được thêm vào Cassandra, Redis cũng được cập nhật cho điều tương tự. 

Sau khi một lượt thích được đăng, nó cũng sẽ được thông báo tới Kafka để chúng tôi có thể chạy các phân tích sâu hơn trên cùng một lượt thích.

Bây giờ chúng tôi có một cái gì đó gọi là dịch vụ Nhận xét để xử lý tất cả các tác vụ liên quan đến nhận xét. 

Nó sử dụng Cassandra như một kho dữ liệu để lưu trữ tất cả các thông tin cụ thể về bình luận. Chúng tôi đặc biệt không cần phải lưu thông tin này vào bộ nhớ cache vì nó sẽ là một tra cứu đơn giản theo id, sẽ đủ nhanh. 

Vì vậy, chúng tôi không triển khai bộ nhớ đệm ở đây. Và tất nhiên, bất cứ khi nào một bình luận được đăng, một sự kiện lại được yêu cầu Kafka thực hiện các phân tích sâu hơn. 

Chia sẻ một bài đăng được thực hiện theo cách tương tự như một bài đăng thông thường. Một bài đăng được chia sẻ chỉ là một bài đăng khác với id cha của một bài đăng khác.

Bây giờ chúng ta hãy thảo luận về một thứ được gọi là trình theo dõi hoạt động. Hãy nhớ rằng chúng tôi đã đề cập đến một nhật ký hoạt động trong các yêu cầu chức năng của chúng tôi? 

Chúng tôi luôn theo dõi tất cả các hành động của người dùng trong Kafka. Bây giờ chúng ta chỉ cần lưu trữ thông tin của các hành động này dựa trên id người dùng và dấu thời gian.

 Nó cũng sẽ hiển thị các API để tìm nạp thông tin và điền vào giao diện người dùng hoạt động.

Tìm kiếm sẽ lại được triển khai theo cách tương tự như Twitter. Sẽ có một người tiêu dùng tìm kiếm lắng nghe các sự kiện đến với Kafka và lưu trữ chúng trong một tìm kiếm linh hoạt.

 Sẽ có một dịch vụ tìm kiếm ở trên cùng của tìm kiếm đàn hồi, chạy các truy vấn và lưu dữ liệu vào bộ nhớ cache trước khi gửi cho người dùng.

Chúng tôi có thể triển khai những phân tích nào ở đây?

Chúng tôi có thể sử dụng một số thuật toán ML tiêu chuẩn, để phân loại các bài đăng thành các danh mục khác nhau như chính trị, giải trí, thể thao, v.v. 

Chúng tôi sẽ có một trình phát trực tuyến người tiêu dùng chạy trên Kafka, sẽ lưu trữ hoạt động của người dùng vào cụm Hadoop, nơi chúng tôi có thể chạy các thuật toán đã đề cập trước đó để tìm ra sở thích của người dùng và thực hiện một số hồ sơ người dùng. 

Khi hồ sơ người dùng được tạo, chúng tôi đưa một sự kiện khác vào Kafka. Dịch vụ người dùng đọc sự kiện này và lưu trữ thẻ hồ sơ người dùng dựa trên id người dùng.

Bây giờ chúng ta có một thứ gọi là trọng số đồ thị. Biểu đồ trọng số theo dõi bài đăng mà người dùng có xu hướng hướng tới nhiều hơn dựa trên bài đăng mà chúng tôi thích thường xuyên hơn của ai. 

Điều này một lần nữa chạy trên một cụm Spark truy vấn dữ liệu trong Hadoop. Điều cuối cùng trong hệ thống của chúng tôi là Xu hướng. Điều này một lần nữa tương tự với các xu hướng trên twitter. 

Nó sẽ theo dõi những gì mọi người đang nói về Facebook ngay bây giờ. Công việc phát trực tuyến này sẽ xem xét tất cả các bài đăng và nhận xét trên Facebook, mã hóa chúng và xóa các từ như a, an, the, v.v. 

và xếp hạng chúng theo số lượng để tìm ra những từ được sử dụng nhiều nhất. 

Chúng tôi có thể sử dụng cái này để tìm hiểu những gì mọi người quan tâm ngay bây giờ. Thông tin này rất tạm thời và có liên quan trong một thời gian rất ngắn, vì vậy nó được lưu trữ trong bộ nhớ cache của Redis.

Bây giờ một điều không cần phải nói là tất cả các dịch vụ và thành phần này đều có thể mở rộng theo chiều ngang. 

Chúng tôi có thể thêm và xóa các phiên bản theo thông tin chúng tôi nhận được từ hệ thống cảnh báo và giám sát của chúng tôi. 

Các hệ thống này sẽ theo dõi độ trễ, yêu cầu đến, hiệu suất CPU, bộ nhớ được sử dụng, v.v. 

Ngay sau khi chúng tôi biết điều gì đó đang đạt đến giới hạn của nó, chúng tôi có thể tạo ra một phiên bản khác của dịch vụ cụ thể đó. 

Ngoài ra, nếu bạn đang thắc mắc tại sao chúng tôi lại sử dụng cơ sở dữ liệu mà chúng tôi đang sử dụng, hãy xem bài viết của chúng tôi về việc chọn giải pháp lưu trữ phù hợp, nơi chúng tôi đã thảo luận chi tiết về giải pháp nào hoạt động tốt nhất cho các tình huống nào.

Điều đó nên dành cho Thiết kế hệ thống Facebook! Gửi cho chúng tôi suy nghĩ của bạn về video youtube của chúng tôi!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Contact Me on Zalo
Call now