Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Aloha, mọi người! Tên tôi là Oleg Anastasyev, tôi làm việc tại Odnoklassniki trong nhóm Nền tảng. Và ngoài tôi ra, còn có rất nhiều phần cứng đang hoạt động trong Odnoklassniki. Chúng tôi có bốn trung tâm dữ liệu với khoảng 500 giá đỡ với hơn 8 nghìn máy chủ. Tại một thời điểm nhất định, chúng tôi nhận ra rằng việc giới thiệu hệ thống quản lý mới sẽ cho phép chúng tôi tải thiết bị hiệu quả hơn, hỗ trợ quản lý truy cập, tự động hóa việc phân phối (tái) tài nguyên máy tính, tăng tốc độ ra mắt dịch vụ mới và tăng tốc độ phản hồi đến những vụ tai nạn quy mô lớn.

Điều gì đã xảy ra với nó?

Ngoài tôi và một nhóm phần cứng, còn có những người làm việc với phần cứng này: các kỹ sư làm việc trực tiếp tại trung tâm dữ liệu; nhà mạng thiết lập phần mềm mạng; quản trị viên hoặc SRE, những người cung cấp khả năng phục hồi cơ sở hạ tầng; và các nhóm phát triển, mỗi người trong số họ chịu trách nhiệm về một phần chức năng của cổng thông tin. Phần mềm họ tạo ra hoạt động giống như thế này:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Yêu cầu của người dùng được nhận cả ở mặt trước của cổng thông tin chính www.ok.ruvà trên các mặt khác, chẳng hạn như trên mặt trận API âm nhạc. Để xử lý logic nghiệp vụ, họ gọi máy chủ ứng dụng, khi xử lý yêu cầu, sẽ gọi các dịch vụ vi mô chuyên dụng cần thiết - một biểu đồ (biểu đồ kết nối xã hội), bộ đệm người dùng (bộ đệm của hồ sơ người dùng), v.v.

Mỗi dịch vụ này được triển khai trên nhiều máy và mỗi dịch vụ đều có các nhà phát triển chịu trách nhiệm về hoạt động của các mô-đun, hoạt động và phát triển công nghệ của chúng. Tất cả các dịch vụ này đều chạy trên máy chủ phần cứng và cho đến gần đây, chúng tôi đã khởi chạy chính xác một tác vụ cho mỗi máy chủ, tức là nó được chuyên dùng cho một tác vụ cụ thể.

Tại sao vậy? Cách tiếp cận này có một số lợi thế:

  • An tâm quản lý đại chúng. Giả sử một tác vụ yêu cầu một số thư viện, một số cài đặt. Sau đó, máy chủ được chỉ định cho chính xác một nhóm cụ thể, chính sách cengine cho nhóm này được mô tả (hoặc đã được mô tả) và cấu hình này được triển khai tập trung và tự động cho tất cả các máy chủ trong nhóm này.
  • giản thể chẩn đoán. Giả sử bạn nhìn vào tải tăng lên trên bộ xử lý trung tâm và nhận ra rằng tải này chỉ có thể được tạo bởi tác vụ chạy trên bộ xử lý phần cứng này. Việc tìm kiếm ai đó để đổ lỗi kết thúc rất nhanh.
  • giản thể giám sát. Nếu có sự cố xảy ra với máy chủ, màn hình sẽ báo cáo lỗi đó và bạn biết chính xác ai là người có lỗi.

Một dịch vụ bao gồm một số bản sao được phân bổ một số máy chủ - mỗi máy chủ cho một máy chủ. Khi đó tài nguyên tính toán cho dịch vụ được phân bổ rất đơn giản: số lượng máy chủ mà dịch vụ có, lượng tài nguyên tối đa mà dịch vụ có thể tiêu thụ. “Dễ” ở đây không có nghĩa là dễ sử dụng mà hiểu theo nghĩa là việc phân bổ tài nguyên được thực hiện thủ công.

Cách tiếp cận này cũng cho phép chúng tôi làm cấu hình sắt chuyên dụng cho một tác vụ đang chạy trên máy chủ này. Nếu tác vụ lưu trữ lượng lớn dữ liệu thì chúng tôi sử dụng máy chủ 4U với khung có 38 đĩa. Nếu nhiệm vụ hoàn toàn là tính toán thì chúng ta có thể mua máy chủ 1U rẻ hơn. Đây là tính toán hiệu quả. Trong số những điều khác, cách tiếp cận này cho phép chúng tôi sử dụng số lượng máy ít hơn bốn lần với mức tải tương đương với một mạng xã hội thân thiện.

Hiệu quả sử dụng tài nguyên máy tính như vậy cũng phải đảm bảo hiệu quả kinh tế, nếu chúng ta tiến hành từ tiền đề rằng thứ đắt nhất là máy chủ. Trong một thời gian dài, phần cứng là thứ đắt nhất và chúng tôi đã nỗ lực rất nhiều để giảm giá phần cứng, đưa ra các thuật toán chịu lỗi để giảm yêu cầu về độ tin cậy của phần cứng. Và ngày nay chúng ta đã đến giai đoạn mà giá máy chủ không còn mang tính quyết định nữa. Nếu bạn không xem xét các phiên bản mới nhất, thì cấu hình cụ thể của các máy chủ trong giá không thành vấn đề. Bây giờ chúng ta có một vấn đề khác - giá của không gian mà máy chủ chiếm giữ trong trung tâm dữ liệu, tức là không gian trong giá.

Nhận thấy trường hợp này xảy ra, chúng tôi quyết định tính toán xem chúng tôi đã sử dụng giá đỡ hiệu quả như thế nào.
Chúng tôi lấy giá của máy chủ mạnh nhất từ ​​những máy chủ hợp lý về mặt kinh tế, tính toán xem chúng tôi có thể đặt bao nhiêu máy chủ như vậy trong giá đỡ, bao nhiêu tác vụ chúng tôi sẽ chạy trên chúng dựa trên mô hình cũ “một máy chủ = một tác vụ” và số lượng như vậy là bao nhiêu. nhiệm vụ có thể sử dụng thiết bị. Họ đếm và rơi nước mắt. Hóa ra hiệu quả sử dụng giá đỡ của chúng tôi là khoảng 11%. Kết luận rất rõ ràng: chúng ta cần tăng hiệu quả sử dụng trung tâm dữ liệu. Có vẻ như giải pháp rất rõ ràng: bạn cần chạy nhiều tác vụ trên một máy chủ cùng một lúc. Nhưng đây là nơi những khó khăn bắt đầu.

Cấu hình hàng loạt trở nên phức tạp hơn nhiều - giờ đây không thể chỉ định bất kỳ nhóm nào cho một máy chủ. Rốt cuộc, bây giờ một số nhiệm vụ của các lệnh khác nhau có thể được khởi chạy trên một máy chủ. Ngoài ra, cấu hình có thể xung đột đối với các ứng dụng khác nhau. Việc chẩn đoán cũng trở nên phức tạp hơn: nếu bạn thấy mức tiêu thụ CPU hoặc ổ đĩa trên máy chủ tăng lên, bạn sẽ không biết tác vụ nào đang gây ra sự cố.

Nhưng điều quan trọng nhất là không có sự tách biệt giữa các tác vụ chạy trên cùng một máy. Ví dụ: đây là biểu đồ về thời gian phản hồi trung bình của một tác vụ máy chủ trước và sau khi một ứng dụng tính toán khác được khởi chạy trên cùng một máy chủ, không liên quan gì đến ứng dụng đầu tiên - thời gian phản hồi của tác vụ chính đã tăng lên đáng kể.

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Rõ ràng, bạn cần chạy các tác vụ trong vùng chứa hoặc trong máy ảo. Vì hầu hết tất cả các tác vụ của chúng tôi đều chạy trên một HĐH (Linux) hoặc được điều chỉnh cho phù hợp với hệ điều hành đó nên chúng tôi không cần hỗ trợ nhiều hệ điều hành khác nhau. Theo đó, ảo hóa là không cần thiết; do chi phí bổ sung nên nó sẽ kém hiệu quả hơn so với việc container hóa.

Là một triển khai các vùng chứa để chạy các tác vụ trực tiếp trên máy chủ, Docker là một ứng cử viên sáng giá: hình ảnh hệ thống tệp giải quyết tốt các vấn đề với cấu hình xung đột. Việc hình ảnh có thể bao gồm nhiều lớp cho phép chúng tôi giảm đáng kể lượng dữ liệu cần thiết để triển khai chúng trên cơ sở hạ tầng, tách các phần chung thành các lớp cơ sở riêng biệt. Sau đó, các lớp cơ bản (và có dung lượng lớn nhất) sẽ được lưu vào bộ nhớ đệm khá nhanh trên toàn bộ cơ sở hạ tầng và để cung cấp nhiều loại ứng dụng và phiên bản khác nhau, chỉ cần chuyển các lớp nhỏ.

Ngoài ra, sổ đăng ký và gắn thẻ hình ảnh được tạo sẵn trong Docker cung cấp cho chúng tôi các nguyên mẫu sẵn có để lập phiên bản và phân phối mã vào sản xuất.

Docker, giống như bất kỳ công nghệ tương tự nào khác, cung cấp cho chúng ta một số mức độ cách ly vùng chứa ngay từ đầu. Ví dụ: cách ly bộ nhớ - mỗi vùng chứa được đưa ra một giới hạn về việc sử dụng bộ nhớ máy, vượt quá giới hạn đó nó sẽ không tiêu thụ. Bạn cũng có thể cách ly các vùng chứa dựa trên mức sử dụng CPU. Tuy nhiên, đối với chúng tôi, cách nhiệt tiêu chuẩn là chưa đủ. Nhưng nhiều hơn về điều đó dưới đây.

Việc chạy trực tiếp các container trên máy chủ chỉ là một phần của vấn đề. Phần còn lại liên quan đến việc lưu trữ các container trên máy chủ. Bạn cần hiểu container nào có thể được đặt trên máy chủ nào. Đây không phải là một nhiệm vụ dễ dàng vì các container cần được đặt trên các máy chủ với mật độ dày đặc nhất có thể mà không làm giảm tốc độ của chúng. Việc bố trí như vậy cũng có thể khó khăn xét theo quan điểm khả năng chịu lỗi. Thông thường, chúng tôi muốn đặt các bản sao của cùng một dịch vụ trong các giá đỡ khác nhau hoặc thậm chí trong các phòng khác nhau của trung tâm dữ liệu, để nếu một giá hoặc phòng bị lỗi, chúng tôi sẽ không mất tất cả các bản sao dịch vụ ngay lập tức.

Phân phối vùng chứa theo cách thủ công không phải là một lựa chọn khi bạn có 8 nghìn máy chủ và 8-16 nghìn vùng chứa.

Ngoài ra, chúng tôi muốn mang lại cho các nhà phát triển sự độc lập hơn trong việc phân bổ nguồn lực để họ có thể tự lưu trữ các dịch vụ của mình trong quá trình sản xuất mà không cần sự trợ giúp của quản trị viên. Đồng thời, chúng tôi muốn duy trì quyền kiểm soát để một số dịch vụ nhỏ không tiêu tốn hết tài nguyên của trung tâm dữ liệu của chúng tôi.

Rõ ràng, chúng ta cần một lớp điều khiển có thể thực hiện việc này một cách tự động.

Vì vậy, chúng tôi đã đi đến một bức tranh đơn giản và dễ hiểu mà tất cả các kiến ​​​​trúc sư đều ngưỡng mộ: ba hình vuông.

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

chủ một đám mây là một cụm chuyển đổi dự phòng chịu trách nhiệm điều phối đám mây. Nhà phát triển gửi một bản kê khai tới bản chính, chứa tất cả thông tin cần thiết để lưu trữ dịch vụ. Dựa vào đó, chủ nhân sẽ đưa ra lệnh cho các tay sai được chọn (máy được thiết kế để chạy các thùng chứa). Các tay sai có tác nhân của chúng tôi, nhận lệnh, đưa ra lệnh cho Docker và Docker định cấu hình nhân linux để khởi chạy vùng chứa tương ứng. Ngoài việc thực thi các lệnh, tác nhân còn liên tục báo cáo cho chủ nhân về những thay đổi về trạng thái của cả máy minion và các thùng chứa đang chạy trên đó.

Phân bổ nguồn lực

Bây giờ chúng ta hãy xem xét vấn đề phân bổ tài nguyên phức tạp hơn cho nhiều tay sai.

Tài nguyên điện toán trong một đám mây là:

  • Lượng điện năng bộ xử lý tiêu thụ bởi một tác vụ cụ thể.
  • Dung lượng bộ nhớ có sẵn cho tác vụ.
  • Lưu lượng mạng. Mỗi tay sai có một giao diện mạng cụ thể với băng thông hạn chế, do đó không thể phân phối nhiệm vụ mà không tính đến lượng dữ liệu chúng truyền qua mạng.
  • Đĩa. Ngoài ra, rõ ràng, đối với không gian dành cho những tác vụ này, chúng tôi cũng phân bổ loại ổ đĩa: HDD hoặc SSD. Đĩa có thể phục vụ số lượng yêu cầu hữu hạn mỗi giây - IOPS. Do đó, đối với các tác vụ tạo ra nhiều IOPS hơn khả năng xử lý của một đĩa đơn, chúng tôi cũng phân bổ “trục chính” - tức là các thiết bị đĩa phải được dành riêng cho tác vụ.

Sau đó, đối với một số dịch vụ, chẳng hạn như bộ đệm người dùng, chúng tôi có thể ghi lại tài nguyên đã tiêu thụ theo cách này: 400 lõi xử lý, bộ nhớ 2,5 TB, lưu lượng 50 Gbit/s ở cả hai hướng, 6 TB dung lượng ổ cứng nằm trên 100 trục chính . Hoặc ở dạng quen thuộc hơn như thế này:

alloc:
    cpu: 400
    mem: 2500
    lan_in: 50g
    lan_out: 50g
    hdd:100x6T

Tài nguyên dịch vụ bộ đệm người dùng chỉ tiêu thụ một phần của tất cả tài nguyên có sẵn trong cơ sở hạ tầng sản xuất. Vì vậy, tôi muốn đảm bảo rằng đột nhiên, do lỗi của người vận hành hay không, bộ đệm của người dùng không tiêu tốn nhiều tài nguyên hơn mức được phân bổ cho nó. Tức là chúng ta phải hạn chế nguồn lực. Nhưng chúng ta có thể gắn hạn ngạch vào cái gì?

Hãy quay lại sơ đồ đã được đơn giản hóa rất nhiều của chúng ta về sự tương tác giữa các thành phần và vẽ lại nó với nhiều chi tiết hơn - như thế này:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Những gì bắt mắt:

  • Giao diện người dùng web và âm nhạc sử dụng các cụm riêng biệt của cùng một máy chủ ứng dụng.
  • Chúng ta có thể phân biệt các lớp logic mà các cụm này thuộc về: lớp mặt trước, bộ đệm, lớp quản lý và lưu trữ dữ liệu.
  • Giao diện người dùng không đồng nhất; nó bao gồm các hệ thống con chức năng khác nhau.
  • Bộ nhớ đệm cũng có thể nằm rải rác trên hệ thống con có dữ liệu được lưu vào bộ nhớ đệm.

Hãy vẽ lại bức tranh một lần nữa:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Ôi! Vâng, chúng tôi thấy một hệ thống phân cấp! Điều này có nghĩa là bạn có thể phân phối tài nguyên theo khối lớn hơn: chỉ định một nhà phát triển chịu trách nhiệm cho một nút của hệ thống phân cấp này tương ứng với hệ thống con chức năng (như “âm nhạc” trong hình) và đính kèm hạn ngạch cho cùng cấp độ của hệ thống phân cấp. Hệ thống phân cấp này cũng cho phép chúng tôi tổ chức các dịch vụ linh hoạt hơn để dễ quản lý. Ví dụ: chúng tôi chia tất cả các trang web, vì đây là một nhóm máy chủ rất lớn, thành nhiều nhóm nhỏ hơn, được hiển thị trong hình là nhóm1, nhóm2.

Bằng cách loại bỏ các dòng thừa, chúng ta có thể viết từng nút của hình ảnh ở dạng phẳng hơn: nhóm1.web.front, api.music.front, người dùng-cache.cache.

Đây là cách chúng ta đi đến khái niệm “hàng đợi phân cấp”. Nó có tên như "group1.web.front". Hạn ngạch về tài nguyên và quyền người dùng được gán cho nó. Chúng tôi sẽ cấp cho người từ DevOps quyền gửi dịch vụ đến hàng đợi và nhân viên đó có thể khởi chạy thứ gì đó trong hàng đợi và người từ OpsDev sẽ có quyền quản trị viên và bây giờ anh ta có thể quản lý hàng đợi, chỉ định người ở đó, trao quyền cho những người này, v.v. Các dịch vụ chạy trên hàng đợi này sẽ chạy trong hạn ngạch của hàng đợi. Nếu hạn ngạch tính toán của hàng đợi không đủ để thực thi tất cả các dịch vụ cùng một lúc thì chúng sẽ được thực thi tuần tự, do đó tự hình thành nên hàng đợi.

Chúng ta hãy xem xét kỹ hơn các dịch vụ. Một dịch vụ có tên đủ điều kiện, luôn bao gồm tên của hàng đợi. Khi đó front web service sẽ có tên ok-web.group1.web.front. Và dịch vụ máy chủ ứng dụng mà nó truy cập sẽ được gọi ok-app.group1.web.front. Mỗi dịch vụ có một bảng kê khai chỉ định tất cả thông tin cần thiết để bố trí trên các máy cụ thể: tác vụ này tiêu thụ bao nhiêu tài nguyên, cấu hình nào cần cho nó, cần có bao nhiêu bản sao, các thuộc tính để xử lý lỗi của dịch vụ này. Và sau khi dịch vụ được đặt trực tiếp trên máy, các phiên bản của nó sẽ xuất hiện. Chúng cũng được đặt tên rõ ràng - như số phiên bản và tên dịch vụ: 1.ok-web.group1.web.front, 2.ok-web.group1.web.front, …

Điều này rất thuận tiện: chỉ cần nhìn vào tên của container đang chạy, chúng ta có thể biết ngay rất nhiều điều.

Bây giờ chúng ta hãy xem xét kỹ hơn những gì các phiên bản này thực sự thực hiện: nhiệm vụ.

Lớp cách ly nhiệm vụ

Tất cả các nhiệm vụ trong OK (và có lẽ ở mọi nơi) có thể được chia thành các nhóm:

  • Nhiệm vụ có độ trễ ngắn - prod. Đối với các tác vụ và dịch vụ như vậy, độ trễ phản hồi (độ trễ) rất quan trọng, tốc độ xử lý của mỗi yêu cầu được hệ thống xử lý nhanh như thế nào. Ví dụ về các tác vụ: mặt trận web, bộ đệm, máy chủ ứng dụng, bộ lưu trữ OLTP, v.v.
  • Vấn đề tính toán - lô. Ở đây, tốc độ xử lý của từng yêu cầu cụ thể không quan trọng. Đối với họ, điều quan trọng là nhiệm vụ này sẽ thực hiện bao nhiêu phép tính trong một khoảng thời gian (thông lượng) nhất định. Đây sẽ là bất kỳ nhiệm vụ nào của MapReduce, Hadoop, học máy, thống kê.
  • Tác vụ nền - nhàn rỗi. Đối với những tác vụ như vậy, độ trễ cũng như thông lượng đều không quan trọng. Điều này bao gồm nhiều thử nghiệm, di chuyển, tính toán lại và chuyển đổi dữ liệu từ định dạng này sang định dạng khác. Một mặt, chúng tương tự như những cái được tính toán, mặt khác, việc chúng được hoàn thành nhanh như thế nào không thực sự quan trọng đối với chúng tôi.

Hãy xem các tác vụ như vậy tiêu tốn tài nguyên như thế nào, chẳng hạn như bộ xử lý trung tâm.

Nhiệm vụ có độ trễ ngắn. Một tác vụ như vậy sẽ có mô hình tiêu thụ CPU tương tự như sau:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Một yêu cầu từ người dùng được nhận để xử lý, tác vụ bắt đầu sử dụng tất cả các lõi CPU có sẵn, xử lý nó, trả về phản hồi, chờ yêu cầu tiếp theo và dừng lại. Yêu cầu tiếp theo đã đến - một lần nữa chúng tôi đã chọn mọi thứ ở đó, tính toán nó và đang chờ yêu cầu tiếp theo.

Để đảm bảo độ trễ tối thiểu cho một tác vụ như vậy, chúng ta phải tận dụng tối đa tài nguyên mà nó tiêu thụ và dự trữ số lượng lõi cần thiết trên minion (máy sẽ thực thi tác vụ). Khi đó công thức đặt trước cho bài toán của chúng ta sẽ như sau:

alloc: cpu = 4 (max)

và nếu chúng ta có một cỗ máy minion với 16 lõi, thì có thể đặt chính xác bốn nhiệm vụ như vậy vào nó. Chúng tôi đặc biệt lưu ý rằng mức tiêu thụ bộ xử lý trung bình của các tác vụ như vậy thường rất thấp - điều này là hiển nhiên, vì phần lớn thời gian tác vụ chờ yêu cầu và không làm gì cả.

Nhiệm vụ tính toán. Mẫu của chúng sẽ hơi khác một chút:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Mức tiêu thụ tài nguyên CPU trung bình cho các tác vụ như vậy là khá cao. Thông thường, chúng ta muốn một tác vụ tính toán hoàn thành trong một khoảng thời gian nhất định, vì vậy chúng ta cần dự trữ số lượng bộ xử lý tối thiểu cần thiết để toàn bộ phép tính được hoàn thành trong thời gian có thể chấp nhận được. Công thức đặt chỗ của nó sẽ như thế này:

alloc: cpu = [1,*)

“Hãy đặt nó lên một con lính có ít nhất một lõi còn trống, và càng nhiều thì nó sẽ nuốt chửng mọi thứ.”

Ở đây, hiệu quả sử dụng đã tốt hơn nhiều so với các tác vụ có độ trễ ngắn. Nhưng mức thu được sẽ lớn hơn nhiều nếu bạn kết hợp cả hai loại nhiệm vụ trên một máy minion và phân phối tài nguyên của nó khi đang di chuyển. Khi một tác vụ có độ trễ ngắn cần có bộ xử lý, nó sẽ nhận được tác vụ đó ngay lập tức và khi không cần tài nguyên nữa, chúng sẽ được chuyển sang tác vụ tính toán, tức là như thế này:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Nhưng làm thế nào để làm điều đó?

Trước tiên, hãy xem prod và phân bổ của nó: cpu = 4. Chúng ta cần dự trữ bốn lõi. Trong Docker chạy, việc này có thể được thực hiện theo hai cách:

  • Sử dụng tùy chọn --cpuset=1-4, tức là phân bổ bốn lõi cụ thể trên máy cho tác vụ.
  • Để sử dụng --cpuquota=400_000 --cpuperiod=100_000, chỉ định hạn ngạch cho thời gian của bộ xử lý, tức là chỉ ra rằng cứ sau 100 mili giây thời gian thực, tác vụ sẽ tiêu tốn không quá 400 mili giây thời gian của bộ xử lý. Bốn lõi giống nhau thu được.

Nhưng phương pháp nào trong số này là phù hợp?

cpuset trông khá hấp dẫn. Tác vụ có bốn lõi chuyên dụng, có nghĩa là bộ nhớ đệm của bộ xử lý sẽ hoạt động hiệu quả nhất có thể. Điều này cũng có một nhược điểm: chúng tôi sẽ phải đảm nhận nhiệm vụ phân phối các phép tính trên các lõi chưa được tải của máy thay vì HĐH và đây là một nhiệm vụ khá không hề nhỏ, đặc biệt nếu chúng tôi cố gắng đặt các tác vụ hàng loạt trên một hệ thống như vậy. máy móc. Các thử nghiệm đã chỉ ra rằng tùy chọn có hạn ngạch phù hợp hơn ở đây: bằng cách này, hệ điều hành có nhiều tự do hơn trong việc lựa chọn lõi để thực hiện tác vụ tại thời điểm hiện tại và thời gian xử lý được phân phối hiệu quả hơn.

Hãy cùng tìm hiểu cách đặt chỗ trong Docker dựa trên số lượng lõi tối thiểu. Hạn ngạch cho nhiệm vụ hàng loạt không còn được áp dụng nữa, vì không cần giới hạn mức tối đa, chỉ cần đảm bảo mức tối thiểu là đủ. Và ở đây tùy chọn này rất phù hợp docker run --cpushares.

Chúng tôi đồng ý rằng nếu một lô yêu cầu đảm bảo cho ít nhất một lõi thì chúng tôi chỉ ra --cpushares=1024và nếu có ít nhất hai lõi thì chúng tôi chỉ ra --cpushares=2048. Việc chia sẻ Cpu không can thiệp vào việc phân bổ thời gian của bộ xử lý theo bất kỳ cách nào, miễn là có đủ thời gian đó. Do đó, nếu sản phẩm hiện không sử dụng tất cả bốn lõi của nó thì không có gì hạn chế các tác vụ hàng loạt và họ có thể sử dụng thêm thời gian xử lý. Nhưng trong tình huống thiếu bộ xử lý, nếu prod đã tiêu thụ hết bốn lõi và đạt hạn mức, thời gian xử lý còn lại sẽ được chia theo tỷ lệ cho cpushares, tức là trong tình huống có ba lõi trống, một sẽ được chia được giao cho một nhiệm vụ có 1024 cpushares và hai nhiệm vụ còn lại sẽ được giao cho một nhiệm vụ có 2048 cpushares.

Nhưng sử dụng hạn ngạch và cổ phần thôi là chưa đủ. Chúng ta cần đảm bảo rằng tác vụ có độ trễ ngắn sẽ được ưu tiên hơn tác vụ hàng loạt khi phân bổ thời gian xử lý. Nếu không có sự ưu tiên như vậy, tác vụ hàng loạt sẽ chiếm toàn bộ thời gian của bộ xử lý tại thời điểm sản phẩm cần đến. Không có tùy chọn ưu tiên vùng chứa khi chạy Docker, nhưng các chính sách lập lịch CPU của Linux rất hữu ích. Bạn có thể đọc về chúng một cách chi tiết đây, và trong khuôn khổ bài viết này, chúng ta sẽ điểm qua chúng một cách ngắn gọn:

  • SCHED_OTHER
    Theo mặc định, tất cả các quy trình người dùng thông thường trên máy Linux đều nhận được.
  • SCHED_BATCH
    Được thiết kế cho các quy trình sử dụng nhiều tài nguyên. Khi đặt một tác vụ lên bộ xử lý, cái gọi là hình phạt kích hoạt sẽ được đưa ra: tác vụ đó ít có khả năng nhận tài nguyên bộ xử lý hơn nếu nó hiện đang được sử dụng bởi một tác vụ có SCHED_OTHER
  • SCHED_IDLE
    Quá trình nền có mức độ ưu tiên rất thấp, thậm chí thấp hơn mức Nice -19. Chúng tôi sử dụng thư viện nguồn mở của mình một-nio, để đặt chính sách cần thiết khi khởi động vùng chứa bằng cách gọi

one.nio.os.Proc.sched_setscheduler( pid, Proc.SCHED_IDLE )

Nhưng ngay cả khi bạn không lập trình bằng Java, bạn vẫn có thể thực hiện điều tương tự bằng lệnh chrt:

chrt -i 0 $pid

Hãy tóm tắt tất cả các mức cô lập của chúng tôi vào một bảng cho rõ ràng:

Lớp cách nhiệt
Ví dụ phân bổ
Tùy chọn chạy Docker
sched_setscheduler chrt*

Sản
CPU = 4
--cpuquota=400000 --cpuperiod=100000
SCHED_OTHER

Hàng loạt
CPU = [1, *)
--cpushares=1024
SCHED_BATCH

Nhàn rỗi
CPU= [2, *)
--cpushares=2048
SCHED_IDLE

*Nếu bạn đang thực hiện chrt từ bên trong vùng chứa, bạn có thể cần khả năng sys_nice, vì theo mặc định Docker sẽ loại bỏ khả năng này khi khởi động vùng chứa.

Nhưng các tác vụ không chỉ tiêu tốn bộ xử lý mà còn cả lưu lượng truy cập, điều này ảnh hưởng đến độ trễ của tác vụ mạng thậm chí còn nhiều hơn việc phân bổ tài nguyên bộ xử lý không chính xác. Vì vậy, tất nhiên chúng ta muốn có được bức tranh giống hệt nhau về giao thông. Nghĩa là, khi một tác vụ sản xuất gửi một số gói tới mạng, chúng tôi sẽ giới hạn tốc độ tối đa (công thức cấp phát: lan=[*,500mbps) ), mà sản phẩm có thể làm được điều này. Và đối với lô, chúng tôi chỉ đảm bảo thông lượng tối thiểu nhưng không giới hạn mức tối đa (công thức cấp phát: lan=[10Mbps,*) ) Trong trường hợp này, lưu lượng truy cập sản phẩm sẽ được ưu tiên hơn các tác vụ hàng loạt.
Ở đây Docker không có bất kỳ nguyên thủy nào mà chúng ta có thể sử dụng. Nhưng nó giúp ích cho chúng ta Kiểm soát lưu lượng Linux. Chúng tôi đã có thể đạt được kết quả mong muốn với sự giúp đỡ của kỷ luật Đường cong dịch vụ công bằng theo thứ bậc. Với sự trợ giúp của nó, chúng tôi phân biệt hai loại lưu lượng truy cập: sản phẩm có mức độ ưu tiên cao và lô/không hoạt động có mức độ ưu tiên thấp. Kết quả là cấu hình cho lưu lượng đi như sau:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

ở đây 1:0 là “qdisc gốc” của bộ môn hsfc; 1:1 - lớp con hsfc có tổng giới hạn băng thông là 8 Gbit/s, trong đó các lớp con của tất cả các vùng chứa được đặt; 1:2 - lớp con hsfc dùng chung cho tất cả các tác vụ theo lô và tác vụ nhàn rỗi có giới hạn "động", được thảo luận bên dưới. Các lớp con hsfc còn lại là các lớp dành riêng cho các vùng chứa sản phẩm hiện đang chạy với các giới hạn tương ứng với tệp kê khai của chúng - 450 và 400 Mbit/s. Mỗi lớp hsfc được gán một hàng đợi qdisc fq hoặc fq_codel, tùy thuộc vào phiên bản nhân Linux, để tránh mất gói trong quá trình bùng nổ lưu lượng.

Thông thường, các quy tắc tc chỉ ưu tiên lưu lượng truy cập đi. Nhưng chúng tôi cũng muốn ưu tiên lưu lượng truy cập đến - xét cho cùng, một số tác vụ hàng loạt có thể dễ dàng chọn toàn bộ kênh đến, chẳng hạn như nhận một loạt dữ liệu đầu vào lớn để ánh xạ&giảm. Đối với điều này, chúng tôi sử dụng mô-đun ifb, tạo giao diện ảo ifbX cho mỗi giao diện mạng và chuyển hướng lưu lượng truy cập đến từ giao diện sang lưu lượng đi trên ifbX. Hơn nữa, đối với ifbX, tất cả các nguyên tắc tương tự đều hoạt động để kiểm soát lưu lượng đi, trong đó cấu hình hsfc sẽ rất giống nhau:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Trong quá trình thử nghiệm, chúng tôi phát hiện ra rằng hsfc cho thấy kết quả tốt nhất khi loại 1:2 của lưu lượng truy cập không ưu tiên/không hoạt động bị giới hạn trên các máy minion không quá một làn đường trống nhất định. Mặt khác, lưu lượng truy cập không ưu tiên có tác động quá lớn đến độ trễ của các tác vụ sản xuất. miniond xác định lượng băng thông trống hiện tại mỗi giây, đo mức tiêu thụ lưu lượng trung bình của tất cả các tác vụ sản xuất của một minion nhất định Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki và trừ nó khỏi băng thông giao diện mạng Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki với một lề nhỏ, tức là

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Các băng tần được xác định độc lập cho lưu lượng truy cập vào và ra. Và theo các giá trị mới, miniond sẽ cấu hình lại giới hạn lớp không ưu tiên 1:2.

Vì vậy, chúng tôi đã triển khai cả ba lớp cách ly: prod, batch và Idle. Các lớp này ảnh hưởng lớn đến đặc tính hiệu suất của nhiệm vụ. Do đó, chúng tôi quyết định đặt thuộc tính này ở đầu hệ thống phân cấp, để khi nhìn vào tên của hàng đợi phân cấp, sẽ ngay lập tức hiểu rõ chúng tôi đang giải quyết vấn đề gì:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Tất cả bạn bè của chúng tôi web и Âm nhạc các mặt trận sau đó được đặt trong hệ thống phân cấp dưới sản phẩm. Ví dụ: theo đợt, hãy đặt dịch vụ danh mục âm nhạc, định kỳ biên soạn danh mục các bản nhạc từ một tập hợp tệp mp3 được tải lên Odnoklassniki. Một ví dụ về dịch vụ không hoạt động sẽ là máy biến âm nhạc, giúp bình thường hóa mức âm lượng nhạc.

Sau khi loại bỏ các dòng bổ sung, chúng ta có thể viết tên dịch vụ của mình phẳng hơn bằng cách thêm lớp cách ly tác vụ vào cuối tên dịch vụ đầy đủ: web.front.prod, danh mục.music.batch, máy biến áp.music.idle.

Và bây giờ, nhìn vào tên của dịch vụ, chúng ta không chỉ hiểu chức năng của nó mà còn cả lớp cách ly của nó, nghĩa là mức độ quan trọng của nó, v.v.

Mọi thứ đều tuyệt vời, nhưng có một sự thật cay đắng. Không thể tách biệt hoàn toàn các tác vụ đang chạy trên một máy.

Những gì chúng tôi đã đạt được: nếu tiêu thụ nhiều hàng loạt chỉ Tài nguyên CPU thì bộ lập lịch CPU Linux tích hợp sẽ thực hiện rất tốt công việc của nó và thực tế không có tác động nào đến tác vụ sản xuất. Nhưng nếu tác vụ hàng loạt này bắt đầu hoạt động tích cực với bộ nhớ, thì ảnh hưởng lẫn nhau đã xuất hiện. Điều này xảy ra do tác vụ sản xuất đã bị “xóa sạch” khỏi bộ nhớ đệm của bộ xử lý - kết quả là bộ nhớ đệm bị thiếu tăng lên và bộ xử lý xử lý tác vụ sản xuất chậm hơn. Một tác vụ hàng loạt như vậy có thể tăng độ trễ của vùng chứa sản phẩm thông thường của chúng tôi lên 10%.

Việc cô lập lưu lượng thậm chí còn khó khăn hơn do các card mạng hiện đại có hàng đợi gói bên trong. Nếu gói từ tác vụ bó đến đó trước thì gói đó sẽ là gói đầu tiên được truyền qua cáp và không thể làm gì được.

Ngoài ra, cho đến nay chúng tôi chỉ giải quyết được vấn đề ưu tiên lưu lượng TCP: phương pháp hsfc không hoạt động đối với UDP. Và ngay cả trong trường hợp lưu lượng TCP, nếu tác vụ hàng loạt tạo ra nhiều lưu lượng truy cập, điều này cũng làm tăng độ trễ của tác vụ sản xuất khoảng 10%.

khả năng chịu lỗi

Một trong những mục tiêu khi phát triển một đám mây là cải thiện khả năng chịu lỗi của Odnoklassniki. Vì vậy, tiếp theo tôi muốn xem xét chi tiết hơn các kịch bản hư hỏng và tai nạn có thể xảy ra. Hãy bắt đầu với một tình huống đơn giản - lỗi container.

Bản thân vùng chứa có thể bị lỗi theo nhiều cách. Đây có thể là một loại thử nghiệm, lỗi hoặc lỗi nào đó trong tệp kê khai, do đó tác vụ sản xuất bắt đầu tiêu tốn nhiều tài nguyên hơn mức được chỉ định trong tệp kê khai. Chúng tôi đã gặp một trường hợp: một nhà phát triển đã triển khai một thuật toán phức tạp, làm lại nó nhiều lần, suy nghĩ quá nhiều và trở nên bối rối đến mức cuối cùng vấn đề đã đi vào một vòng lặp rất không tầm thường. Và vì tác vụ sản xuất có mức độ ưu tiên cao hơn tất cả các tác vụ khác trên cùng một tay sai nên nó bắt đầu tiêu tốn tất cả tài nguyên bộ xử lý có sẵn. Trong tình huống này, sự cô lập, hay đúng hơn là hạn ngạch thời gian của CPU, đã cứu được một ngày. Nếu một nhiệm vụ được phân bổ hạn ngạch, nhiệm vụ đó sẽ không tiêu tốn nhiều hơn. Do đó, các tác vụ hàng loạt và các tác vụ sản xuất khác chạy trên cùng một máy không nhận thấy điều gì.

Vấn đề thứ hai có thể xảy ra là container bị rơi. Và ở đây các chính sách khởi động lại đã cứu chúng tôi, mọi người đều biết đến chúng, bản thân Docker đã làm rất tốt. Hầu hết tất cả các tác vụ sản xuất đều có chính sách luôn khởi động lại. Đôi khi chúng tôi sử dụng on_failure cho các tác vụ hàng loạt hoặc để gỡ lỗi các vùng chứa sản phẩm.

Bạn có thể làm gì nếu không có toàn bộ quân lính?

Rõ ràng, hãy chạy vùng chứa trên một máy khác. Phần thú vị ở đây là những gì xảy ra với (các) địa chỉ IP được gán cho vùng chứa.

Chúng ta có thể chỉ định các vùng chứa cùng địa chỉ IP với các máy minion mà các vùng chứa này chạy trên đó. Sau đó, khi vùng chứa được khởi chạy trên một máy khác, địa chỉ IP của nó sẽ thay đổi và tất cả khách hàng phải hiểu rằng vùng chứa đã được di chuyển và bây giờ họ cần đi đến một địa chỉ khác, địa chỉ này yêu cầu dịch vụ Khám phá dịch vụ riêng.

Khám phá dịch vụ rất thuận tiện. Có rất nhiều giải pháp trên thị trường với mức độ chấp nhận lỗi khác nhau để tổ chức đăng ký dịch vụ. Thông thường, các giải pháp như vậy triển khai logic cân bằng tải, lưu trữ cấu hình bổ sung dưới dạng lưu trữ KV, v.v.
Tuy nhiên, chúng tôi muốn tránh sự cần thiết phải triển khai một sổ đăng ký riêng vì điều này có nghĩa là giới thiệu một hệ thống quan trọng được tất cả các dịch vụ trong sản xuất sử dụng. Điều này có nghĩa rằng đây là một điểm có thể dẫn đến thất bại và bạn cần phải chọn hoặc phát triển một giải pháp có khả năng chịu lỗi cao, điều này rõ ràng là rất khó khăn, tốn thời gian và tốn kém.

Và một nhược điểm lớn nữa: để cơ sở hạ tầng cũ của chúng tôi hoạt động được với cơ sở hạ tầng mới, chúng tôi sẽ phải viết lại hoàn toàn tất cả các tác vụ để sử dụng một số loại hệ thống Khám phá Dịch vụ. Có RẤT NHIỀU công việc và ở một số nơi, điều đó gần như không thể thực hiện được đối với các thiết bị cấp thấp hoạt động ở cấp nhân hệ điều hành hoặc trực tiếp với phần cứng. Việc triển khai chức năng này bằng cách sử dụng các mẫu giải pháp đã được thiết lập, chẳng hạn như xe phụ có nghĩa là ở một số nơi sẽ có tải bổ sung, ở những nơi khác - sự phức tạp của hoạt động và các tình huống lỗi bổ sung. Chúng tôi không muốn làm phức tạp mọi thứ nên chúng tôi quyết định sử dụng Khám phá dịch vụ là tùy chọn.

Trong một đám mây, IP tuân theo vùng chứa, tức là mỗi phiên bản tác vụ có địa chỉ IP riêng. Địa chỉ này là “tĩnh”: nó được gán cho từng phiên bản khi dịch vụ lần đầu tiên được gửi lên đám mây. Nếu một dịch vụ có số lượng phiên bản khác nhau trong suốt vòng đời của nó thì cuối cùng, dịch vụ đó sẽ được chỉ định số lượng địa chỉ IP bằng số lượng phiên bản tối đa.

Sau đó, các địa chỉ này không thay đổi: chúng được chỉ định một lần và tiếp tục tồn tại trong suốt vòng đời của dịch vụ trong quá trình sản xuất. Địa chỉ IP theo sau các container trên mạng. Nếu thùng chứa được chuyển cho một tay sai khác thì địa chỉ sẽ theo sau nó.

Do đó, việc ánh xạ tên dịch vụ vào danh sách địa chỉ IP của nó rất hiếm khi thay đổi. Nếu bạn nhìn lại tên của các phiên bản dịch vụ mà chúng tôi đã đề cập ở đầu bài viết (1.ok-web.group1.web.front.prod, 2.ok-web.group1.web.front.prod, …), chúng ta sẽ nhận thấy rằng chúng giống với FQDN được sử dụng trong DNS. Đúng vậy, để ánh xạ tên của các phiên bản dịch vụ tới địa chỉ IP của chúng, chúng tôi sử dụng giao thức DNS. Hơn nữa, DNS này trả về tất cả các địa chỉ IP dành riêng của tất cả các vùng chứa - cả đang chạy và đã dừng (giả sử ba bản sao được sử dụng và chúng tôi có năm địa chỉ được đặt trước ở đó - cả năm địa chỉ sẽ được trả về). Khách hàng, sau khi nhận được thông tin này, sẽ cố gắng thiết lập kết nối với tất cả năm bản sao - và do đó xác định những bản sao đang hoạt động. Tùy chọn xác định tính khả dụng này đáng tin cậy hơn nhiều; nó không liên quan đến DNS hoặc Khám phá dịch vụ, có nghĩa là không có vấn đề khó giải quyết nào trong việc đảm bảo tính liên quan của thông tin và khả năng chịu lỗi của các hệ thống này. Hơn nữa, trong các dịch vụ quan trọng mà hoạt động của toàn bộ cổng phụ thuộc vào, chúng ta hoàn toàn không thể sử dụng DNS mà chỉ cần nhập địa chỉ IP vào cấu hình.

Việc triển khai chuyển IP như vậy sau các vùng chứa có thể không hề đơn giản - và chúng ta sẽ xem cách nó hoạt động với ví dụ sau:

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Giả sử chủ nhân một đám mây ra lệnh cho tay sai M1 chạy 1.ok-web.group1.web.front.prod với địa chỉ 1.1.1.1. Hoạt động trên một tay sai BIRD, quảng cáo địa chỉ này đến các máy chủ đặc biệt phản xạ tuyến đường. Cái sau có phiên BGP với phần cứng mạng, trong đó tuyến địa chỉ 1.1.1.1 trên M1 được dịch. M1 định tuyến các gói bên trong vùng chứa bằng Linux. Có ba máy chủ phản ánh tuyến đường, vì đây là một phần rất quan trọng của cơ sở hạ tầng một đám mây - nếu không có chúng, mạng trong một đám mây sẽ không hoạt động. Chúng tôi đặt chúng trong các giá đỡ khác nhau, nếu có thể, đặt ở các phòng khác nhau của trung tâm dữ liệu, để giảm khả năng cả ba bị hỏng cùng một lúc.

Bây giờ hãy giả sử rằng kết nối giữa chủ một đám mây và tay sai M1 bị mất. Bậc thầy một đám mây bây giờ sẽ hành động dựa trên giả định rằng M1 đã hoàn toàn thất bại. Tức là nó sẽ ra lệnh cho minion M2 phóng web.group1.web.front.prod có cùng địa chỉ 1.1.1.1. Bây giờ chúng tôi có hai tuyến xung đột trên mạng cho 1.1.1.1: trên M1 và trên M2. Để giải quyết những xung đột như vậy, chúng tôi sử dụng Bộ phân biệt đối xử đa lối ra, được chỉ định trong thông báo BGP. Đây là con số thể hiện độ nặng của tuyến đường được quảng cáo. Trong số các tuyến xung đột, tuyến có giá trị MED thấp hơn sẽ được chọn. Bản gốc một đám mây hỗ trợ MED như một phần không thể thiếu của địa chỉ IP vùng chứa. Lần đầu tiên, địa chỉ được ghi với MED đủ lớn = 1. Trong trường hợp chuyển container khẩn cấp như vậy, chủ sẽ giảm MED và M000 sẽ nhận được lệnh quảng cáo địa chỉ 000 với MED = 2. Phiên bản chạy trên M1.1.1.1 sẽ vẫn ở mức trong trường hợp này là không có kết nối và số phận xa hơn của anh ta khiến chúng ta không quan tâm nhiều cho đến khi kết nối với phiên bản chính được khôi phục, khi đó anh ta sẽ bị dừng lại như một lỗi cũ.

tai nạn

Tất cả các hệ thống quản lý trung tâm dữ liệu luôn xử lý các lỗi nhỏ ở mức chấp nhận được. Tràn container là tiêu chuẩn ở hầu hết mọi nơi.

Hãy xem cách chúng tôi xử lý trường hợp khẩn cấp, chẳng hạn như mất điện ở một hoặc nhiều phòng của trung tâm dữ liệu.

Tai nạn có ý nghĩa gì đối với hệ thống quản lý trung tâm dữ liệu? Trước hết, đây là sự cố lớn xảy ra một lần của nhiều máy và hệ thống điều khiển cần phải di chuyển nhiều container cùng lúc. Nhưng nếu thảm họa có quy mô rất lớn thì có thể xảy ra trường hợp không thể phân bổ lại mọi nhiệm vụ cho tay sai khác, do dung lượng tài nguyên của trung tâm dữ liệu giảm xuống dưới 100% tải.

Tai nạn thường đi kèm với sự thất bại của lớp điều khiển. Điều này có thể xảy ra do thiết bị của nó bị lỗi, nhưng thường xuyên hơn là do các sự cố không được kiểm tra và bản thân lớp điều khiển bị rơi do tải tăng lên.

Bạn có thể làm gì về tất cả điều này?

Di chuyển hàng loạt có nghĩa là có một số lượng lớn các hoạt động, di chuyển và triển khai diễn ra trong cơ sở hạ tầng. Mỗi lần di chuyển có thể mất một khoảng thời gian cần thiết để phân phối và giải nén hình ảnh vùng chứa cho tay sai, khởi chạy và khởi tạo vùng chứa, v.v. Do đó, điều mong muốn là các nhiệm vụ quan trọng hơn sẽ được khởi chạy trước những nhiệm vụ ít quan trọng hơn.

Chúng ta hãy xem lại hệ thống phân cấp của các dịch vụ mà chúng ta quen thuộc và cố gắng quyết định tác vụ nào chúng ta muốn chạy trước.

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Tất nhiên, đây là những quy trình liên quan trực tiếp đến việc xử lý yêu cầu của người dùng, tức là sản phẩm. Chúng tôi chỉ ra điều này với ưu tiên vị trí - một số có thể được gán cho hàng đợi. Nếu hàng đợi có mức độ ưu tiên cao hơn thì các dịch vụ của nó sẽ được đặt trước.

Trên sản phẩm, chúng tôi chỉ định mức độ ưu tiên cao hơn, 0; theo đợt - thấp hơn một chút, 100; khi không hoạt động - thậm chí thấp hơn, 200. Mức độ ưu tiên được áp dụng theo thứ bậc. Tất cả các nhiệm vụ thấp hơn trong hệ thống phân cấp sẽ có mức độ ưu tiên tương ứng. Nếu chúng tôi muốn các bộ nhớ đệm bên trong sản phẩm được khởi chạy trước các giao diện người dùng thì chúng tôi sẽ chỉ định mức độ ưu tiên cho cache = 0 và cho các hàng đợi con phía trước = 1. Ví dụ: nếu chúng tôi muốn cổng chính được khởi chạy từ các giao diện người dùng trước và chỉ giao diện âm nhạc sau đó, chúng ta có thể chỉ định mức độ ưu tiên thấp hơn cho cái sau - 10.

Vấn đề tiếp theo là thiếu nguồn lực. Vì vậy, một lượng lớn thiết bị, toàn bộ hội trường của trung tâm dữ liệu đã không hoạt động và chúng tôi đã khởi chạy lại rất nhiều dịch vụ đến mức hiện tại không có đủ tài nguyên cho tất cả mọi người. Bạn cần quyết định nên hy sinh những nhiệm vụ nào để duy trì hoạt động của các dịch vụ quan trọng chính.

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Không giống như ưu tiên vị trí, chúng tôi không thể hy sinh bừa bãi tất cả các nhiệm vụ hàng loạt; một số nhiệm vụ trong số đó rất quan trọng đối với hoạt động của cổng. Vì vậy, chúng tôi đã nhấn mạnh riêng ưu tiên ưu tiên nhiệm vụ. Khi được đặt, một nhiệm vụ có mức độ ưu tiên cao hơn có thể được ưu tiên trước, tức là dừng lại, một nhiệm vụ có mức độ ưu tiên thấp hơn nếu không còn tay sai rảnh rỗi nào nữa. Trong trường hợp này, một nhiệm vụ có mức độ ưu tiên thấp có thể sẽ không được đặt, tức là sẽ không còn một tay sai phù hợp cho nó với đủ tài nguyên miễn phí.

Trong hệ thống phân cấp của chúng tôi, rất đơn giản để chỉ định mức độ ưu tiên ưu tiên sao cho các tác vụ sản phẩm và lô ưu tiên hoặc dừng các tác vụ nhàn rỗi chứ không phải lẫn nhau, bằng cách chỉ định mức độ ưu tiên cho các tác vụ không hoạt động bằng 200. Cũng giống như trong trường hợp ưu tiên vị trí, chúng tôi có thể sử dụng hệ thống phân cấp của chúng tôi để mô tả các quy tắc phức tạp hơn. Ví dụ: hãy chỉ ra rằng chúng tôi hy sinh chức năng âm nhạc nếu chúng tôi không có đủ tài nguyên cho cổng web chính, đặt mức độ ưu tiên cho các nút tương ứng thấp hơn: 10.

Toàn bộ vụ tai nạn ở DC

Tại sao toàn bộ trung tâm dữ liệu có thể thất bại? Yếu tố. Là một bài viết tốt cơn bão ảnh hưởng đến hoạt động của trung tâm dữ liệu. Các phần tử có thể được coi là những người vô gia cư đã từng đốt quang học trong ống góp và trung tâm dữ liệu hoàn toàn mất liên lạc với các địa điểm khác. Nguyên nhân thất bại cũng có thể do yếu tố con người: người vận hành sẽ ra lệnh khiến toàn bộ trung tâm dữ liệu sẽ sụp đổ. Điều này có thể xảy ra do một lỗi lớn. Nhìn chung, việc các trung tâm dữ liệu sụp đổ không phải là hiếm. Điều này xảy ra với chúng tôi vài tháng một lần.

Và đây là những gì chúng tôi làm để ngăn chặn bất kỳ ai tweet #alive.

Chiến lược đầu tiên là sự cô lập. Mỗi phiên bản một đám mây đều được cách ly và chỉ có thể quản lý máy trong một trung tâm dữ liệu. Nghĩa là, việc mất một đám mây do lỗi hoặc do người vận hành lệnh không chính xác là mất chỉ một trung tâm dữ liệu. Chúng tôi đã sẵn sàng cho việc này: chúng tôi có chính sách dự phòng trong đó các bản sao của ứng dụng và dữ liệu được đặt ở tất cả các trung tâm dữ liệu. Chúng tôi sử dụng cơ sở dữ liệu có khả năng chịu lỗi và kiểm tra lỗi định kỳ.
Kể từ hôm nay, chúng tôi có bốn trung tâm dữ liệu, điều đó có nghĩa là bốn trường hợp riêng biệt, hoàn toàn biệt lập của một đám mây.

Cách tiếp cận này không chỉ bảo vệ khỏi lỗi vật lý mà còn có thể bảo vệ khỏi lỗi của người vận hành.

Những gì khác có thể được thực hiện với yếu tố con người? Khi người điều hành đưa ra cho đám mây một số lệnh lạ hoặc có khả năng nguy hiểm, anh ta có thể bất ngờ được yêu cầu giải quyết một vấn đề nhỏ để xem anh ta suy nghĩ tốt đến mức nào. Ví dụ: nếu đây là một kiểu dừng hàng loạt của nhiều bản sao hoặc chỉ là một lệnh lạ - giảm số lượng bản sao hoặc thay đổi tên của hình ảnh chứ không chỉ số phiên bản trong tệp kê khai mới.

Một đám mây - hệ điều hành cấp trung tâm dữ liệu ở Odnoklassniki

Kết quả

Các tính năng đặc biệt của một đám mây:

  • Sơ đồ đặt tên theo cấp bậc và trực quan cho các dịch vụ và vùng chứa, điều này cho phép bạn nhanh chóng tìm ra nhiệm vụ là gì, nó liên quan đến cái gì, nó hoạt động như thế nào và ai chịu trách nhiệm về nó.
  • Chúng tôi áp dụng kỹ thuật kết hợp sản phẩm và lônhiệm vụ trên tay sai để nâng cao hiệu quả chia sẻ máy. Thay vì cpuset, chúng tôi sử dụng hạn ngạch CPU, chia sẻ, chính sách lập lịch CPU và QoS Linux.
  • Không thể tách biệt hoàn toàn các container chạy trên cùng một máy nhưng ảnh hưởng lẫn nhau của chúng vẫn nằm trong khoảng 20%.
  • Việc tổ chức các dịch vụ thành một hệ thống phân cấp giúp khắc phục thảm họa tự động bằng cách sử dụng ưu tiên vị trí và quyền ưu tiên.

Câu hỏi thường gặp

Tại sao chúng ta không áp dụng giải pháp làm sẵn?

  • Các lớp cách ly nhiệm vụ khác nhau yêu cầu logic khác nhau khi đặt lên tay sai. Nếu các nhiệm vụ sản xuất có thể được đặt bằng cách đơn giản là dự trữ tài nguyên, thì các nhiệm vụ hàng loạt và nhàn rỗi phải được đặt, theo dõi việc sử dụng tài nguyên thực tế trên máy minion.
  • Cần phải tính đến các tài nguyên được sử dụng bởi các nhiệm vụ, chẳng hạn như:
    • băng thông mạng;
    • các loại và “trục xoay” của đĩa.
  • Nhu cầu chỉ ra mức độ ưu tiên của các dịch vụ trong quá trình ứng phó khẩn cấp, quyền và hạn ngạch của các lệnh đối với tài nguyên, được giải quyết bằng cách sử dụng hàng đợi phân cấp trong một đám mây.
  • Cần phải có con người đặt tên cho container để giảm thời gian ứng phó với tai nạn, sự cố
  • Không thể triển khai rộng rãi một lần Khám phá dịch vụ; nhu cầu tồn tại lâu dài với các tác vụ được lưu trữ trên máy chủ phần cứng - điều được giải quyết bằng các địa chỉ IP “tĩnh” theo sau các vùng chứa và do đó, nhu cầu tích hợp duy nhất với cơ sở hạ tầng mạng lớn.

Tất cả các chức năng này sẽ yêu cầu sửa đổi đáng kể các giải pháp hiện có cho phù hợp với chúng tôi và sau khi đánh giá khối lượng công việc, chúng tôi nhận ra rằng chúng tôi có thể phát triển giải pháp của riêng mình với chi phí lao động xấp xỉ nhau. Nhưng giải pháp của bạn sẽ dễ vận hành và phát triển hơn nhiều - nó không chứa những phần trừu tượng không cần thiết hỗ trợ chức năng mà chúng ta không cần.

Gửi tới những ai đã đọc những dòng cuối cùng, xin cảm ơn sự kiên nhẫn và quan tâm của các bạn!

Nguồn: www.habr.com

Thêm một lời nhận xét