Bỏ qua nội dung chính
OpenAI

22 tháng 1, 2026

Kỹ thuật

Mở rộng quy mô PostgreSQL cho 800 triệu người dùng ChatGPT

Bởi Bohan Zhang, Thành viên của Ban Kỹ thuật

Đang tải…

Trong nhiều năm, PostgreSQL là một trong những hệ thống dữ liệu quan trọng nhất, cung cấp năng lượng cho các sản phẩm cốt lõi như ChatGPT và API của OpenAI. Khi cơ sở người dùng của chúng tôi phát triển nhanh chóng, nhu cầu về cơ sở dữ liệu của chúng tôi cũng tăng theo cấp số nhân. Trong năm qua, tải lượng PostgreSQL của chúng tôi đã tăng hơn 10 lần và nó tiếp tục tăng nhanh chóng.

Những nỗ lực của chúng tôi nhằm thúc đẩy cơ sở hạ tầng sản xuất để duy trì sự tăng trưởng này đã tiết lộ một cái nhìn sâu sắc mới: PostgreSQL có thể được mở rộng để hỗ trợ một cách đáng tin cậy khối lượng công việc đọc nặng hơn nhiều so với nhiều người nghĩ trước đây. Hệ thống (ban đầu được tạo bởi một nhóm các nhà khoa học tại Đại học California, Berkeley) đã cho phép chúng tôi hỗ trợ lưu lượng truy cập toàn cầu khổng lồ với một phiên bản máy chủ linh hoạt Azure PostgreSQL(mở trong cửa sổ mới) chính duy nhất và gần 50 bản sao đọc trải rộng trên nhiều khu vực trên toàn cầu. Đây là câu chuyện về cách chúng tôi đã mở rộng PostgreSQL tại OpenAI để hỗ trợ hàng triệu truy vấn mỗi giây cho 800 triệu người dùng thông qua các tối ưu hóa nghiêm ngặt và kỹ thuật vững chắc; chúng tôi cũng sẽ đề cập đến những kết quả quan trọng mà chúng tôi đã học được trên đường đi.

Những vết nứt trong thiết kế ban đầu của chúng tôi

Sau khi ra mắt ChatGPT, lưu lượng truy cập tăng với tốc độ chưa từng có. Để hỗ trợ nó, chúng tôi nhanh chóng triển khai tối ưu hóa mở rộng ở cả lớp cơ sở dữ liệu ứng dụng và PostgreSQL, tăng quy mô bằng cách tăng kích thước phiên bản và thu nhỏ bằng cách thêm nhiều bản sao đọc hơn. Kiến trúc này đã phục vụ tốt chúng tôi trong một thời gian dài. Với những cải tiến liên tục, nó tiếp tục cung cấp đường băng rộng rãi cho sự phát triển trong tương lai.

Nghe có vẻ đáng ngạc nhiên khi một kiến trúc chỉ sử dụng một bộ xử lý chính lại có thể đáp ứng được nhu cầu quy mô của OpenAI; tuy nhiên, việc hiện thực hóa điều này trong thực tế không hề đơn giản. Chúng ta đã thấy một số SEV gây ra bởi quá tải Postgres và chúng thường tuân theo cùng một mô hình: một vấn đề ngược dòng gây ra sự tăng đột ngột về tải cơ sở dữ liệu, chẳng hạn như lỗi bộ nhớ cache lan rộng do lỗi lớp bộ nhớ đệm, sự gia tăng các kết nối đa chiều đắt tiền làm bão hòa CPU hoặc một cơn bão ghi từ sự ra mắt tính năng mới. Khi việc sử dụng tài nguyên tăng lên, độ trễ truy vấn tăng lên và các yêu cầu bắt đầu hết thời gian. Các lần thử lại sau đó càng khuếch đại tải, kích hoạt một vòng luẩn quẩn với khả năng làm suy giảm toàn bộ các dịch vụ ChatGPT và API.

Biểu đồ tải trọng quy mô.

Mặc dù PostgreSQL mở rộng tốt cho khối lượng công việc đọc nặng của chúng tôi, chúng tôi vẫn gặp phải những thách thức trong thời gian lưu lượng ghi cao. Điều này phần lớn là do việc triển khai kiểm soát đồng thời đa phiên bản (MVCC) của PostgreSQL, điều này làm cho nó kém hiệu quả hơn đối với khối lượng công việc nặng ghi. Ví dụ: khi truy vấn cập nhật một tuple hoặc thậm chí một trường duy nhất, toàn bộ hàng sẽ được sao chép để tạo phiên bản mới. Dưới tải ghi nặng, điều này dẫn đến khuếch đại ghi đáng kể. Nó cũng làm tăng khuếch đại đọc, vì các truy vấn phải quét qua nhiều phiên bản tuple (tuple chết) để truy xuất phiên bản mới nhất. MVCC đưa ra những thách thức bổ sung như đầy bảng và chỉ số, tăng chi phí bảo trì chỉ số và điều chỉnh tự động phức tạp. (Bạn có thể tìm thấy một bài viết sâu về những vấn đề này trong một blog mà tôi đã viết với Giáo sư Andy Pavlo tại Đại học Carnegie Mellon có tên là The Part of PostgreSQL We Hate the Most(mở trong cửa sổ mới), được trích dẫn(mở trong cửa sổ mới) trong trang Wikipedia PostgreSQL.)

Mở rộng PostgreSQL lên hàng triệu QPS

Để giảm thiểu những hạn chế này và giảm áp lực ghi, chúng tôi đã di chuyển và tiếp tục di chuyển, có thể chia sẻ (tức là khối lượng công việc có thể được phân vùng theo chiều ngang), khối lượng công việc nặng ghi vào các hệ thống được chia nhỏ như Azure Cosmos DB, tối ưu hóa logic ứng dụng để giảm thiểu các ghi không cần thiết. Chúng tôi cũng không cho phép thêm bảng mới vào hệ thống PostgreSQL hiện tại nữa. Khối lượng công việc mới mặc định cho các hệ thống được chia nhỏ.

Ngay cả khi cơ sở hạ tầng của chúng tôi đã phát triển, PostgreSQL vẫn không được chia sẻ, với một phiên bản chính duy nhất phục vụ tất cả các ghi. Lý do chính là việc chia khối lượng công việc ứng dụng hiện có sẽ rất phức tạp và tốn thời gian, đòi hỏi phải thay đổi hàng trăm điểm cuối ứng dụng và có khả năng mất nhiều tháng hoặc thậm chí nhiều năm. Vì khối lượng công việc của chúng tôi chủ yếu là đọc nhiều và chúng tôi đã triển khai tối ưu hóa rộng rãi, kiến trúc hiện tại vẫn cung cấp nhiều khoảng trống để hỗ trợ tăng lưu lượng truy cập liên tục. Mặc dù chúng tôi không loại trừ khả năng chia sẻ PostgreSQL trong tương lai, nhưng đó không phải là ưu tiên trong ngắn hạn với đường băng đầy đủ mà chúng tôi có cho sự phát triển hiện tại và tương lai.

Trong các phần sau, chúng tôi sẽ đi sâu vào những thách thức mà chúng tôi phải đối mặt và các tối ưu hóa rộng rãi mà chúng tôi đã thực hiện để giải quyết chúng và ngăn chặn sự cố trong tương lai, đẩy PostgreSQL đến giới hạn của nó và mở rộng nó lên hàng triệu truy vấn mỗi giây (QPS).

Giảm tải cho máy chủ chính

Thách thức: Chỉ với một người viết, thiết lập đơn sơ cấp không thể mở rộng quy mô ghi. Các đợt ghi đột biến cao có thể nhanh chóng làm quá tải các dịch vụ chính và tác động như ChatGPT và API của chúng tôi.

Giải pháp: Chúng tôi giảm thiểu tải trên bản chính càng nhiều càng tốt — cả đọc và ghi — để đảm bảo nó có đủ khả năng xử lý các đợt ghi đột biến. Lưu lượng đọc được chuyển sang bản sao bất cứ khi nào có thể. Tuy nhiên, một số truy vấn đọc phải vẫn ở trên primary vì chúng là một phần của các giao dịch ghi. Đối với những trường hợp đó, chúng tôi tập trung vào việc đảm bảo chúng hiệu quả và tránh các truy vấn chậm. Đối với lưu lượng ghi, chúng tôi đã di chuyển khối lượng công việc có thể chia sẻ, nặng ghi sang các hệ thống được chia sẻ như Azure CosmosDB. Khối lượng công việc khó phân mảnh hơn nhưng vẫn tạo ra khối lượng ghi cao sẽ mất nhiều thời gian hơn để di chuyển và quá trình đó vẫn đang diễn ra. Chúng tôi cũng tích cực tối ưu hóa các ứng dụng của mình để giảm tải ghi; ví dụ, chúng tôi đã sửa các lỗi ứng dụng gây ra ghi dư thừa và giới thiệu tính năng viết lười, nếu thích hợp, để làm mượt mà lưu lượng truy cập tăng đột biến. Ngoài ra, khi lấp đầy các trường bảng, chúng tôi thực thi các giới hạn tỷ lệ nghiêm ngặt để ngăn chặn áp lực ghi quá mức.

Tối ưu hóa truy vấn

Thách thức: Chúng tôi đã xác định một số truy vấn đắt tiền trong PostgreSQL. Trước đây, các đợt tăng đột biến về khối lượng trong các truy vấn này đã tiêu tốn lượng lớn CPU, làm chậm cả ChatGPT và các yêu cầu API.

Giải pháp: Một vài truy vấn tốn kém, chẳng hạn như những truy vấn kết hợp nhiều bảng với nhau, có thể làm suy giảm đáng kể hoặc thậm chí khiến toàn bộ dịch vụ ngừng hoạt động. Chúng ta cần liên tục tối ưu hóa các truy vấn PostgreSQL để đảm bảo chúng hoạt động hiệu quả và tránh các mẫu chống xử lý giao dịch trực tuyến (OLTP) phổ biến. Ví dụ: chúng tôi đã từng xác định một truy vấn cực kỳ tốn kém liên kết với 12 bảng, trong đó các đợt tăng đột biến trong truy vấn này chịu trách nhiệm cho các SEV có mức độ nghiêm trọng cao trong quá khứ. Chúng ta nên tránh các kết nối đa bảng phức tạp bất cứ khi nào có thể. Nếu các liên kết là cần thiết, chúng tôi đã học cách xem xét việc phá vỡ truy vấn và chuyển logic liên kết phức tạp sang lớp ứng dụng thay vào đó. Nhiều truy vấn có vấn đề này được tạo ra bởi các khung đối tượng - quan hệ đối tượng (ORM), vì vậy điều quan trọng là phải xem xét cẩn thận SQL mà chúng tạo ra và đảm bảo nó hoạt động như mong đợi. Việc tìm thấy các truy vấn không hoạt động chạy dài trong PostgreSQL cũng là điều phổ biến. Cấu hình thời gian chờ như idle_in_transaction_session_timeout là điều cần thiết để ngăn chặn chúng chặn autoacuum.

Điểm giảm thiểu thất bại duy nhất

Thử thách: Nếu bản sao đọc bị hỏng, lưu lượng truy cập vẫn có thể được định tuyến đến các bản sao khác. Tuy nhiên, dựa vào một người viết duy nhất có nghĩa là có một điểm thất bại duy nhất — nếu nó bị hỏng, toàn bộ dịch vụ sẽ bị ảnh hưởng.

Giải pháp: Hầu hết các yêu cầu quan trọng chỉ liên quan đến truy vấn đọc. Để giảm thiểu điểm thất bại duy nhất trong bản chính, chúng tôi đã chuyển các lần đọc đó từ trình ghi sang bản sao, đảm bảo các yêu cầu đó có thể tiếp tục phục vụ ngay cả khi bản chính bị hỏng. Mặc dù các thao tác ghi vẫn sẽ thất bại, tác động sẽ giảm; nó không còn là SEV0 vì các lần đọc vẫn có sẵn.

Để giảm thiểu các lỗi chính, chúng tôi chạy hệ thống chính ở chế độ Độ sẵn sàng cao (HA) với chế độ chờ nóng, một bản sao được đồng bộ hóa liên tục luôn sẵn sàng tiếp quản lưu lượng phục vụ. Nếu thiết bị chính bị hỏng hoặc cần phải ngoại tuyến để bảo trì, chúng tôi có thể nhanh chóng thúc đẩy chế độ chờ để giảm thiểu thời gian ngừng hoạt động. Nhóm Azure PostgreSQL đã thực hiện công việc quan trọng để đảm bảo các dự phòng này vẫn an toàn và đáng tin cậy ngay cả khi tải rất cao. Để xử lý lỗi bản sao đọc, chúng tôi triển khai nhiều bản sao trong mỗi khu vực với đủ dung lượng trống, đảm bảo rằng một lỗi bản sao duy nhất không dẫn đến mất điện khu vực.

Cách ly khối lượng công việc

Thách thức: Chúng tôi thường gặp phải các tình huống mà một số yêu cầu nhất định tiêu thụ một lượng tài nguyên không cân xứng trên các phiên bản PostgreSQL. Điều này có thể dẫn đến giảm hiệu suất cho các khối lượng công việc khác đang chạy trên cùng một phiên bản. Ví dụ như việc khởi chạy tính năng mới có thể giới thiệu các truy vấn không hiệu quả tiêu thụ nhiều CPU PostgreSQL, làm chậm các yêu cầu đối với các tính năng quan trọng khác.

Giải pháp: Chúng tôi vận hành gần 50 bản sao đọc trên nhiều vùng địa lý để giảm thiểu độ trễ. Tuy nhiên, với kiến trúc hiện tại, sơ cấp phải truyền WAL đến mọi bản sao. Mặc dù hiện tại nó có quy mô tốt với các loại phiên bản rất lớn và băng thông mạng cao, chúng tôi không thể tiếp tục thêm bản sao vô thời hạn mà không làm quá tải phần chính. Để giải quyết vấn đề này, chúng tôi đang cộng tác với nhóm Azure PostgreSQL về sao chép theo tầng, trong đó các bản sao trung gian chuyển(mở trong cửa sổ mới) tiếp WAL đến các bản sao hạ nguồn. Cách tiếp cận này cho phép chúng tôi mở rộng quy mô lên hơn một trăm bản sao mà không áp đảo bản chính. Tuy nhiên, nó cũng giới thiệu sự phức tạp hoạt động bổ sung, đặc biệt là xung quanh quản lý chuyển đổi dự phòng. Tính năng này vẫn đang được thử nghiệm; chúng tôi sẽ đảm bảo nó mạnh mẽ và có thể thất bại một cách an toàn trước khi đưa nó ra sản xuất.

postgreSQL sơ đồ sao chép phân cấp

Giới hạn tốc độ

Thách thức: Lưu lượng truy cập đột ngột trên các điểm cuối cụ thể, sự gia tăng các truy vấn đắt tiền hoặc một cơn bão thử lại có thể nhanh chóng làm cạn kiệt các tài nguyên quan trọng như CPU, I/O và kết nối, gây ra suy giảm dịch vụ trên diện rộng.

Giải pháp: Chúng tôi đã triển khai giới hạn tốc độ trên nhiều lớp — ứng dụng, bộ chia kết nối, proxy và truy vấn — để ngăn chặn lưu lượng truy cập đột ngột do áp đảo các phiên bản cơ sở dữ liệu và gây ra lỗi xếp tầng. Điều quan trọng là tránh các khoảng thời gian thử lại quá ngắn, có thể kích hoạt các cơn bão thử lại. Chúng tôi cũng tăng cường lớp ORM để hỗ trợ giới hạn tốc độ và khi cần thiết, chặn hoàn toàn các bản phân tích truy vấn cụ thể. Hình thức giảm tải được nhắm mục tiêu này cho phép phục hồi nhanh chóng từ sự gia tăng đột ngột của các truy vấn đắt tiền.

Quản lý lược đồ

Thách thức: Ngay cả một thay đổi lược đồ nhỏ, chẳng hạn như thay đổi kiểu cột, cũng có thể kích hoạt viết lại bảng đầy đủ. Do đó,(mở trong cửa sổ mới) chúng tôi áp dụng các thay đổi lược đồ một cách thận trọng — giới hạn chúng trong các hoạt động nhẹ và tránh bất kỳ thay đổi nào viết lại toàn bộ bảng.

Giải pháp: Chỉ cho phép thay đổi lược đồ nhẹ, chẳng hạn như thêm hoặc xóa một số cột nhất định không kích hoạt viết lại bảng đầy đủ. Chúng tôi thực thi thời gian chờ 5 giây nghiêm ngặt đối với các thay đổi lược đồ. Tạo và thả các chỉ mục đồng thời được cho phép. Thay đổi lược đồ bị giới hạn đối với các bảng hiện có. Nếu một tính năng mới yêu cầu các bảng bổ sung, chúng phải ở trong các hệ thống chia nhỏ thay thế như Azure CosmosDB chứ không phải PostgreSQL. Khi lấp đầy một trường bảng, chúng tôi áp dụng các giới hạn tỷ lệ nghiêm ngặt để ngăn chặn việc ghi đột biến. Mặc dù quá trình này đôi khi có thể mất hơn một tuần, nhưng nó đảm bảo sự ổn định và tránh mọi tác động sản xuất.

Kết quả và con đường phía trước

Nỗ lực này chứng minh rằng với thiết kế và tối ưu hóa phù hợp, Azure PostgreSQL có thể được mở rộng để xử lý khối lượng công việc sản xuất lớn nhất. PostgreSQL xử lý hàng triệu QPS cho khối lượng công việc đọc nặng, cung cấp năng lượng cho các sản phẩm quan trọng nhất của OpenAI như ChatGPT và nền tảng API. Chúng tôi đã thêm gần 50 bản sao đọc, trong khi giữ độ trễ sao chép gần bằng không, duy trì độ đọc có độ trễ thấp trên các khu vực phân phối địa lý và xây dựng đủ dung lượng để hỗ trợ tăng trưởng trong tương lai.

Việc mở rộng quy mô này hoạt động trong khi vẫn giảm thiểu độ trễ và cải thiện độ tin cậy. Chúng tôi luôn cung cấp độ trễ phía máy khách hàng hai chữ số mili giây p99 thấp và khả dụng năm chín trong sản xuất. Và trong 12 tháng qua, chúng tôi chỉ có một sự cố SEV-0 PostgreSQL (nó xảy ra trong quá trình khởi chạy virus(mở trong cửa sổ mới) của ChatGPT ImageGen, khi lưu lượng ghi đột ngột tăng hơn 10 lần khi hơn 100 triệu người dùng mới đăng ký trong vòng một tuần.)

Mặc dù chúng tôi hài lòng với việc PostgreSQL đã đưa chúng tôi đi xa như thế nào, nhưng chúng tôi vẫn tiếp tục đẩy mạnh giới hạn của nó để đảm bảo chúng tôi có đủ đường băng cho sự phát triển trong tương lai. Chúng tôi đã di chuyển khối lượng công việc nặng ghi có thể chia sẻ sang các hệ thống được chia sẻ của chúng tôi như CosmosDB. Các khối lượng công việc nặng ghi còn lại khó chia nhỏ hơn — chúng tôi cũng đang tích cực di chuyển những khối lượng đó để giảm tải hơn nữa các lần ghi từ PostgreSQL chính. Chúng tôi cũng đang làm việc với Azure để cho phép sao chép theo tầng để chúng tôi có thể mở rộng quy mô một cách an toàn để có nhiều bản sao đọc hơn đáng kể.

Trong tương lai, chúng tôi sẽ tiếp tục khám phá các phương pháp tiếp cận bổ sung để mở rộng quy mô hơn nữa, bao gồm PostgreSQL chia nhỏ hoặc các hệ thống phân tán thay thế, khi nhu cầu cơ sở hạ tầng của chúng tôi tiếp tục tăng lên.

Tác giả

Bohan Zhang

Lời cảm ơn

Đặc biệt cảm ơn Jon Lee, Sicheng Liu, Chaomin Yu và Chenglong Hao, những người đã đóng góp cho bài đăng này và toàn bộ nhóm đã giúp mở rộng PostgreSQL. Chúng tôi cũng muốn cảm ơn nhóm Azure PostgreSQL vì sự hợp tác mạnh mẽ của họ.