Làm thế nào một site lớn như Facebook lưu trữ, truy vấn và cập nhật dữ liệu người dùng?

Post Reply
User avatar
stararound
Posts: 22
Joined: Wed Apr 17, 2019 1:29 pm

Làm thế nào một site lớn như Facebook lưu trữ, truy vấn và cập nhật dữ liệu người dùng?

Post by stararound »

How does a site as large as Facebook store, query, and update user data?
Tình cờ gặp câu hỏi này trên Quora, tạm gg translate cho dễ đọc, và lưu để đọc lại sau này.
Câu trả lời này hoàn toàn dựa trên nhiều năm tôi theo dõi nhiều dự án nguồn mở, các cuộc nói chuyện và đặc biệt là các bài đăng trên blog kỹ thuật của họ và cho hồ sơ tôi không làm việc tại Facebook.

Để bắt đầu, Facebook tuyên bố rằng họ là người dùng cơ sở dữ liệu MySQL lớn nhất và từ nhiều bài đăng kỹ thuật của họ, bạn sẽ hiểu rằng họ cũng đã sử dụng phiên bản cộng đồng của MySQL (5.6) để dựa vào việc lưu trữ dữ liệu mạnh hơn. Hệ thống lưu trữ được bảo vệ nghiêm ngặt và phân bổ trên khắp các trung tâm dữ liệu ở Hoa Kỳ cũng như Châu Âu

Nếu bạn đã xem mã nguồn Photypeator và dự án nguồn mở Squangle, bạn sẽ thấy ngay một mẫu để xây dựng một truy vấn SQL. Photypeator sử dụng một hệ thống truy vấn hoàn toàn chịu trách nhiệm thoát khỏi các truy vấn tấn công MySQL, một điều tốt là họ phải xử lý dữ liệu khác nhau có thể tạo thành sự tàn phá cho hệ thống của họ, do đó, phát triển một hệ thống mà qua đó họ truy vấn các kênh truy vấn để xử lý trước có nghĩa là tất cả các kỹ sư sẽ phải tuân theo cùng một mô hình cho sự thống nhất. Ví dụ: nếu bạn đang viết một truy vấn để tìm nạp một bản ghi với danh sách id 1,2,3,4 trong Photypeator thì nó sẽ được viết là:

Code: Select all

$ app = new PhotypeatorX ();
$ data = $ app-> load ALLWhere ("id IN (% Ld)", array(1,2,3,4));
Bây giờ truy vấn trên sử dụng giữ chỗ% Ld, có nghĩa là danh sách các số nguyên, trước khi truy vấn đơn giản này đến cơ sở dữ liệu, nó phải được trình xây dựng truy vấn phân tích cú pháp để đảm bảo rằng bạn không trộn lẫn các loại dữ liệu trong truy vấn của mình. Squangle là một dự án C ++ để phân tích cú pháp và xây dựng các truy vấn SQL, cú pháp của nó khá giống với câu lệnh được sử dụng trong Photypeator. Vì vậy, tôi đoán rằng Facebook có thể đang sử dụng phiên bản C ++, điều đó có nghĩa là việc cung cấp tốc độ đó là tối quan trọng đối với dịch vụ hàng ngày của họ đối với hàng triệu truy vấn. Tôi cũng giả định rằng họ đã trừu tượng hóa cả công cụ truy vấn và trình phân tích cú pháp truy vấn để các kỹ sư không cần lo lắng về cách dữ liệu thực sự được lưu trữ trong phân đoạn đưa ra hoặc cách hệ thống truy vấn truy xuất bản ghi từ hệ thống lưu trữ bên dưới.

Tôi nhớ đã xem một slide thuyết trình về cách họ phân chia hệ thống lưu trữ của họ nhưng nó chỉ cung cấp một cái nhìn tổng quan và không chi tiết, tuy nhiên một điều tôi học được từ bài thuyết trình là họ có một hệ thống xác định phân đoạn dữ liệu nào được lưu trữ, sau đó đã tạo một id đối tượng cho dữ liệu và sau đó gửi dữ liệu để lưu trữ đến phân đoạn cho. Id đối tượng được tạo sẽ mã hóa thông tin về vị trí của phân đoạn để khi bạn muốn tìm lại dữ liệu, bạn sẽ chỉ trình bày id đối tượng và hệ thống sẽ giải mã vị trí của dữ liệu từ id đối tượng trước khi gửi truy vấn đến mục tiêu shard cho dữ liệu.

Họ dường như duy trì một thiết lập Tái tạo Master-Slave đơn giản cho các hệ thống cơ sở dữ liệu của họ và tất cả các ghi hoặc cập nhật đều được chuyển đến kho lưu trữ Master trong khi tất cả các lần đọc chuyển đến lưu trữ Slave. Đó là lý do tại sao đôi khi bạn thực hiện một số thay đổi nhất định về thông tin của mình trên Facebook, đôi khi bạn được thông báo rằng các thay đổi đó sẽ không có hiệu lực ngay lập tức, tôi đoán đó là do thời gian để các máy chủ Slave nhận các thay đổi từ máy chủ Master binlog. Ngoài thiết lập Master-Slave đơn giản này, họ còn có các trang trại máy chủ Memcache để đệm dữ liệu thường xuyên truy cập.

Tôi hy vọng điều này cung cấp cho bạn ý tưởng về cách họ có thể lưu trữ, truy vấn và cập nhật dữ liệu trên hệ thống lưu trữ của họ.

=================
This answer is entirely based on my years of following many of Facebook's open source projects, talks and most especially their engineering blog posts and for the record i don't work at Facebook.

To start with, Facebook stated that they are the largested user of the MySQL database and from many of their engineering postings you would understand that they also have heavily tweeked the community version of MySQL(5.6) to rely on for thier data storage. The storage system is heavily sharded and destributed across datacenters in the U.S as well as Europe

If you had looked at Phabricator source code and the Squangle open source project, you will immediately notice a pattern for building an SQL query. Phabricator uses a query system that is entirely responsible for escaping queries that hit MySQL which is a good thing given that they have to deal with divergent data which can constitute havoc to their system, so developing a system through which they funnel queries for preprosessing means that all engineers will have to following the same pattern for consistency. For example if you are writing a query to fetch a record with a a list of ids 1,2,3,4 in Phabricator it would be written as
$app = new PhabricatorX();
$data = $app->loadAllWhere("id IN (%Ld)", array(1,2,3,4));

Now the above query uses the placeholder %Ld, which means list of integers, before this simple query gets to the database, it has to be parsed by the query builder to ensure that you are not mixing up data types in your query. Squangle is a C++ project for parsing and building SQL queries, its syntax is pretty much like that used in Phabricator. So i am guessing that Facebook is probably using the C++ version which makes sense giving that speed is paramount to their day to day service to millions of queries. I am also assuming that they have abstracted both the query engine and the query parser so that engineers need not worry about how the data is actually stored in a giving shard or how the query system retrieves record from the underlying storage system.

I remember seeing a presentation slide on how they sharded their storage system but it only give an overview and not details, however one thing i learned from the presentation was that they have a system that determines on which shard a pieces of data get stored, then generated an object id for the data and then dispatches the data for storage to the giving shard. The generated object id encodes information about the location of the shard so that when you want to fetch the data back, you would only present the object id and the system will decode the location of the data from the object id before sending off query to the target shard for the data.

They seemed to maintain a simple Master-Slave Replication setup for their database systems and all writes or updates go to the Master storages while all reads go to the Slave storage. That is why sometimes when you make certain changes on your information on Facebook, you sometimes get told that the changes will not immediately take effect, i guess its because of the time it takes for the Slave servers to pick up the changes from the Master server binlog. In addition to this simple Master-Slave setup, they have farms of Memcache servers for buffering frequently accessed data.

I hope this gives you an idea of how they may be storing, querying and updating data on their storage system.

Post Reply