Cụm Elaticsearch 200 TB+

Cụm Elaticsearch 200 TB+

Nhiều người đấu tranh với Elaticsearch. Nhưng điều gì sẽ xảy ra khi bạn muốn sử dụng nó để lưu trữ nhật ký “với khối lượng đặc biệt lớn”? Và việc trải nghiệm sự thất bại của bất kỳ trung tâm dữ liệu nào cũng không gây đau đớn phải không? Bạn nên tạo ra loại kiến ​​trúc nào và bạn sẽ gặp phải những cạm bẫy nào?

Tại Odnoklassniki, chúng tôi đã quyết định sử dụng elaticsearch để giải quyết vấn đề quản lý nhật ký và bây giờ chúng tôi chia sẻ kinh nghiệm của mình với Habr: cả về kiến ​​trúc lẫn những cạm bẫy.

Tôi là Pyotr Zaitsev, tôi làm quản trị viên hệ thống tại Odnoklassniki. Trước đó mình cũng là admin, làm việc với Manticore Search, Sphinx search, Elaticsearch. Có lẽ, nếu một ...tìm kiếm khác xuất hiện, có lẽ tôi cũng sẽ làm việc với nó. Tôi cũng tham gia vào một số dự án nguồn mở trên cơ sở tự nguyện.

Khi đến Odnoklassniki, tôi đã liều lĩnh nói trong cuộc phỏng vấn rằng tôi có thể làm việc với Elaticsearch. Sau khi tôi đã hiểu rõ và hoàn thành một số nhiệm vụ đơn giản, tôi được giao nhiệm vụ lớn là cải cách hệ thống quản lý nhật ký tồn tại vào thời điểm đó.

Yêu cầu

Các yêu cầu hệ thống được xây dựng như sau:

  • Graylog sẽ được sử dụng làm giao diện người dùng. Vì công ty đã có kinh nghiệm sử dụng sản phẩm này nên các lập trình viên và người thử nghiệm đều biết, nó quen thuộc và tiện lợi với họ.
  • Khối lượng dữ liệu: trung bình 50-80 nghìn tin nhắn mỗi giây, nhưng nếu có sự cố xảy ra thì lưu lượng không bị giới hạn bởi bất cứ điều gì, có thể là 2-3 triệu dòng mỗi giây
  • Sau khi thảo luận với khách hàng về các yêu cầu về tốc độ xử lý truy vấn tìm kiếm, chúng tôi nhận ra rằng mô hình điển hình của việc sử dụng hệ thống như vậy là: mọi người đang tìm kiếm nhật ký ứng dụng của họ trong hai ngày qua và không muốn đợi lâu hơn một thứ hai cho kết quả của một truy vấn được xây dựng.
  • Các quản trị viên nhấn mạnh rằng hệ thống có thể dễ dàng mở rộng nếu cần thiết mà không yêu cầu họ phải nghiên cứu sâu về cách thức hoạt động của nó.
  • Vì vậy, nhiệm vụ bảo trì duy nhất mà các hệ thống này yêu cầu định kỳ là thay đổi một số phần cứng.
  • Ngoài ra, Odnoklassniki còn có truyền thống kỹ thuật xuất sắc: bất kỳ dịch vụ nào chúng tôi triển khai đều phải tồn tại khi trung tâm dữ liệu gặp sự cố (đột ngột, không có kế hoạch và hoàn toàn bất kỳ lúc nào).

Yêu cầu cuối cùng trong việc thực hiện dự án này khiến chúng tôi tốn kém nhất, điều này tôi sẽ nói chi tiết hơn.

thứ tư

Chúng tôi làm việc ở bốn trung tâm dữ liệu, trong khi các nút dữ liệu Elaticsearch chỉ có thể được đặt ở ba trung tâm (vì một số lý do phi kỹ thuật).

Bốn trung tâm dữ liệu này chứa khoảng 18 nghìn nguồn nhật ký khác nhau - phần cứng, bộ chứa, máy ảo.

Tính năng quan trọng: cụm bắt đầu trong vùng chứa podman không phải trên máy vật lý mà trên sản phẩm đám mây riêng một đám mây. Các container được đảm bảo 2 lõi, tương tự 2.0GHz v4, có khả năng tái chế các lõi còn lại nếu chúng không hoạt động.

Nói cách khác:

Cụm Elaticsearch 200 TB+

Tôpô

Ban đầu tôi thấy dạng chung của giải pháp như sau:

  • 3-4 VIP đứng sau bản ghi A của miền Graylog, đây là địa chỉ mà nhật ký được gửi đến.
  • mỗi VIP là một bộ cân bằng LVS.
  • Sau đó, nhật ký sẽ chuyển đến pin Graylog, một số dữ liệu ở định dạng GELF, một số ở định dạng nhật ký hệ thống.
  • Sau đó, tất cả những điều này được viết thành từng đợt lớn cho một nhóm điều phối viên Elaticsearch.
  • Và họ lần lượt gửi yêu cầu ghi và đọc đến các nút dữ liệu có liên quan.

Cụm Elaticsearch 200 TB+

Thuật ngữ

Có lẽ không phải ai cũng hiểu thuật ngữ này một cách chi tiết nên tôi muốn tìm hiểu kỹ hơn một chút.

Elaticsearch có một số loại nút - nút chính, nút điều phối, nút dữ liệu. Có hai loại khác để chuyển đổi nhật ký khác nhau và liên lạc giữa các cụm khác nhau, nhưng chúng tôi chỉ sử dụng những loại được liệt kê.

Bậc thầy
Nó ping tất cả các nút có trong cụm, duy trì bản đồ cụm cập nhật và phân phối nó giữa các nút, xử lý logic sự kiện và thực hiện nhiều loại quản lý toàn cụm khác nhau.

Điều phối viên
Thực hiện một nhiệm vụ duy nhất: chấp nhận yêu cầu đọc hoặc ghi từ khách hàng và định tuyến lưu lượng truy cập này. Trong trường hợp có yêu cầu ghi, rất có thể, nó sẽ hỏi chủ nhân nên đặt phân đoạn nào của chỉ mục liên quan và sẽ chuyển hướng yêu cầu thêm.

Nút dữ liệu
Lưu trữ dữ liệu, thực hiện các truy vấn tìm kiếm đến từ bên ngoài và thực hiện các thao tác trên các phân đoạn nằm trên đó.

greylog
Đây giống như sự kết hợp giữa Kibana với Logstash trong ngăn xếp ELK. Graylog kết hợp cả giao diện người dùng và quy trình xử lý nhật ký. Dưới vỏ bọc, Graylog điều hành Kafka và Zookeeper, cung cấp kết nối với Graylog dưới dạng một cụm. Graylog có thể lưu trữ nhật ký (Kafka) trong trường hợp Elaticsearch không khả dụng và lặp lại các yêu cầu đọc và ghi không thành công, nhóm và đánh dấu nhật ký theo quy tắc được chỉ định. Giống như Logstash, Graylog có chức năng sửa đổi các hàng trước khi ghi chúng vào Elaticsearch.

Ngoài ra, Graylog còn có một dịch vụ khám phá tích hợp cho phép, dựa trên một nút Elaticsearch có sẵn, lấy toàn bộ bản đồ cụm và lọc nó theo một thẻ cụ thể, giúp có thể chuyển yêu cầu đến các vùng chứa cụ thể.

Nhìn bề ngoài nó trông giống như thế này:

Cụm Elaticsearch 200 TB+

Đây là ảnh chụp màn hình từ một trường hợp cụ thể. Ở đây chúng tôi xây dựng biểu đồ dựa trên truy vấn tìm kiếm và hiển thị các hàng có liên quan.

Chỉ số

Quay trở lại kiến ​​trúc hệ thống, tôi muốn tìm hiểu chi tiết hơn về cách chúng tôi xây dựng mô hình chỉ mục để tất cả đều hoạt động chính xác.

Trong sơ đồ trên, đây là cấp độ thấp nhất: Nút dữ liệu Elaticsearch.

Chỉ mục là một thực thể ảo lớn được tạo thành từ các phân đoạn Elaticsearch. Bản thân mỗi phân đoạn không gì khác hơn là một chỉ mục Lucene. Và mỗi chỉ mục Lucene lần lượt bao gồm một hoặc nhiều phân đoạn.

Cụm Elaticsearch 200 TB+

Khi thiết kế, chúng tôi nhận thấy rằng để đáp ứng yêu cầu về tốc độ đọc trên một lượng lớn dữ liệu, chúng tôi cần phải “trải” dữ liệu này một cách đồng đều trên các nút dữ liệu.

Điều này dẫn đến thực tế là số lượng phân đoạn trên mỗi chỉ mục (có bản sao) phải hoàn toàn bằng số lượng nút dữ liệu. Thứ nhất, để đảm bảo hệ số sao chép bằng hai (nghĩa là chúng ta có thể mất một nửa cụm). Và thứ hai, để xử lý các yêu cầu đọc và ghi trên ít nhất một nửa cụm.

Đầu tiên chúng tôi xác định thời gian lưu trữ là 30 ngày.

Việc phân phối các phân đoạn có thể được biểu diễn bằng đồ họa như sau:

Cụm Elaticsearch 200 TB+

Toàn bộ hình chữ nhật màu xám đậm là một chỉ mục. Hình vuông màu đỏ bên trái trong đó là phân đoạn chính, phân đoạn đầu tiên trong chỉ mục. Và hình vuông màu xanh là một mảnh bản sao. Chúng được đặt tại các trung tâm dữ liệu khác nhau.

Khi chúng tôi thêm một phân đoạn khác, phân đoạn đó sẽ chuyển đến trung tâm dữ liệu thứ ba. Và cuối cùng, chúng ta có được cấu trúc này, giúp có thể mất DC mà không làm mất tính nhất quán của dữ liệu:

Cụm Elaticsearch 200 TB+

Xoay các chỉ mục, tức là Khi tạo một chỉ mục mới và xóa chỉ mục cũ nhất, chúng tôi tính thời gian bằng 48 giờ (theo mô hình sử dụng chỉ mục: 48 giờ qua được tìm kiếm thường xuyên nhất).

Khoảng thời gian xoay chỉ số này là do các lý do sau:

Khi một yêu cầu tìm kiếm đến một nút dữ liệu cụ thể, từ quan điểm hiệu suất, sẽ có lợi hơn khi một phân đoạn được truy vấn, nếu kích thước của nó tương đương với kích thước hông của nút. Điều này cho phép bạn giữ phần “nóng” của chỉ mục trong một đống và truy cập nhanh vào nó. Khi có nhiều “phần nóng” thì tốc độ tìm kiếm chỉ mục sẽ giảm sút.

Khi một nút bắt đầu thực hiện truy vấn tìm kiếm trên một phân đoạn, nó sẽ phân bổ một số luồng bằng số lõi siêu phân luồng của máy vật lý. Nếu một truy vấn tìm kiếm ảnh hưởng đến một số lượng lớn phân đoạn thì số lượng chuỗi sẽ tăng theo tỷ lệ. Điều này có tác động tiêu cực đến tốc độ tìm kiếm và ảnh hưởng tiêu cực đến việc lập chỉ mục dữ liệu mới.

Để cung cấp độ trễ tìm kiếm cần thiết, chúng tôi quyết định sử dụng ổ SSD. Để xử lý nhanh các yêu cầu, các máy lưu trữ các vùng chứa này phải có ít nhất 56 lõi. Con số 56 được chọn làm giá trị đủ điều kiện để xác định số lượng luồng mà Elaticsearch sẽ tạo ra trong quá trình hoạt động. Trong Elasitcsearch, nhiều tham số nhóm luồng phụ thuộc trực tiếp vào số lượng lõi có sẵn, từ đó ảnh hưởng trực tiếp đến số lượng nút cần thiết trong cụm theo nguyên tắc “ít lõi hơn - nhiều nút hơn”.

Kết quả là, chúng tôi nhận thấy rằng trung bình một phân đoạn nặng khoảng 20 gigabyte và có 1 phân đoạn cho mỗi chỉ mục. Theo đó, nếu chúng ta xoay chúng 360 giờ một lần thì chúng ta có 48 cái. Mỗi chỉ mục chứa dữ liệu trong 15 ngày.

Mạch ghi và đọc dữ liệu

Hãy cùng tìm hiểu cách dữ liệu được ghi lại trong hệ thống này.

Giả sử một số yêu cầu được gửi từ Graylog đến điều phối viên. Ví dụ: chúng tôi muốn lập chỉ mục 2-3 nghìn hàng.

Điều phối viên, sau khi nhận được yêu cầu từ Graylog, đặt câu hỏi với chủ nhân: “Trong yêu cầu lập chỉ mục, chúng tôi đã chỉ định cụ thể một chỉ mục, nhưng không chỉ định phân đoạn nào để viết nó.”

Master trả lời: “Ghi thông tin này vào phân đoạn số 71”, sau đó nó được gửi trực tiếp đến nút dữ liệu liên quan, nơi chứa phân đoạn chính số 71.

Sau đó, nhật ký giao dịch được sao chép sang phân đoạn bản sao, nằm ở một trung tâm dữ liệu khác.

Cụm Elaticsearch 200 TB+

Một yêu cầu tìm kiếm được gửi từ Graylog tới điều phối viên. Điều phối viên chuyển hướng nó theo chỉ mục, trong khi Elaticsearch phân phối các yêu cầu giữa phân đoạn chính và phân đoạn bản sao bằng cách sử dụng nguyên tắc quay vòng.

Cụm Elaticsearch 200 TB+

180 nút phản hồi không đồng đều và trong khi chúng phản hồi, điều phối viên đang tích lũy thông tin đã bị các nút dữ liệu nhanh hơn “nhổ ra”. Sau đó, khi tất cả thông tin đã đến hoặc yêu cầu đã hết thời gian chờ, nó sẽ cung cấp mọi thứ trực tiếp cho khách hàng.

Toàn bộ hệ thống này xử lý các truy vấn tìm kiếm trung bình trong 48 giờ qua trong 300-400 mili giây, ngoại trừ các truy vấn có ký tự đại diện ở đầu.

Hoa với Elaticsearch: Thiết lập Java

Cụm Elaticsearch 200 TB+

Để làm cho tất cả hoạt động theo cách chúng tôi mong muốn ban đầu, chúng tôi đã dành một thời gian rất dài để gỡ lỗi nhiều thứ trong cụm.

Phần đầu tiên của các vấn đề được phát hiện có liên quan đến cách Java được cấu hình sẵn theo mặc định trong Elaticsearch.

Vấn đề một
Chúng tôi đã thấy một số lượng rất lớn báo cáo rằng ở cấp độ Lucene, khi các tác vụ nền đang chạy, việc hợp nhất phân đoạn Lucene không thành công và có lỗi. Đồng thời, nhật ký cho thấy rõ đây là lỗi OutOfMemoryError. Từ xa, chúng tôi thấy rằng hông đã thoát ra ngoài và không rõ tại sao ca phẫu thuật này lại thất bại.

Hóa ra sự hợp nhất chỉ số Lucene xảy ra bên ngoài hông. Và các container bị hạn chế khá nghiêm ngặt về tài nguyên tiêu thụ. Chỉ heap mới có thể vừa với các tài nguyên này (giá trị heap.size xấp xỉ bằng RAM) và một số thao tác ngoài heap bị lỗi cấp phát bộ nhớ nếu vì lý do nào đó mà chúng không vừa với ~500 MB còn lại trước giới hạn.

Cách khắc phục khá đơn giản: dung lượng RAM có sẵn cho vùng chứa đã tăng lên, sau đó chúng tôi quên mất rằng mình thậm chí còn gặp phải những vấn đề như vậy.

Vấn đề thứ hai
4-5 ngày sau khi ra mắt cụm, chúng tôi nhận thấy rằng các nút dữ liệu bắt đầu rời khỏi cụm theo định kỳ và đi vào cụm sau 10-20 giây.

Khi chúng tôi bắt đầu tìm hiểu, hóa ra bộ nhớ ngoài heap này trong Elaticsearch không được kiểm soát theo bất kỳ cách nào. Khi cung cấp thêm bộ nhớ cho vùng chứa, chúng tôi có thể lấp đầy vùng đệm trực tiếp bằng nhiều thông tin khác nhau và thông tin đó chỉ bị xóa sau khi GC rõ ràng được khởi chạy từ Elaticsearch.

Trong một số trường hợp, thao tác này mất khá nhiều thời gian và trong thời gian này, cụm đã đánh dấu nút này là đã thoát. Vấn đề này được mô tả tốt đây.

Giải pháp như sau: chúng tôi đã hạn chế khả năng của Java trong việc sử dụng phần lớn bộ nhớ bên ngoài vùng nhớ heap cho các hoạt động này. Chúng tôi đã giới hạn ở mức 16 gigabyte (-XX:MaxDirectMemorySize=16g), đảm bảo rằng GC rõ ràng được gọi thường xuyên hơn và được xử lý nhanh hơn nhiều, do đó không còn gây mất ổn định cho cụm nữa.

Vấn đề thứ ba
Nếu bạn nghĩ rằng vấn đề “các nút rời khỏi cụm vào thời điểm không mong đợi nhất” đã kết thúc thì bạn đã nhầm.

Khi chúng tôi định cấu hình công việc với các chỉ mục, chúng tôi đã chọn mmapfs để giảm thời gian tìm kiếm trên những mảnh tươi với sự phân chia lớn. Đây thực sự là một sai lầm, vì khi sử dụng mmapfs, tệp được ánh xạ vào RAM và sau đó chúng tôi làm việc với tệp được ánh xạ. Bởi vì điều này, hóa ra là khi GC cố gắng dừng các luồng trong ứng dụng, chúng tôi sẽ đi đến điểm an toàn trong một thời gian rất dài và trên đường tới đó, ứng dụng sẽ ngừng đáp ứng các yêu cầu của chủ nhân về việc liệu nó có còn hoạt động hay không . Theo đó, chủ tin rằng nút đó không còn tồn tại trong cụm. Sau đó, sau 5-10 giây, trình thu gom rác hoạt động, nút hoạt động trở lại, đi vào cụm trở lại và bắt đầu khởi tạo các phân đoạn. Tất cả đều có cảm giác rất giống “tác phẩm mà chúng tôi xứng đáng được nhận” và không phù hợp với bất cứ điều gì nghiêm túc.

Để loại bỏ hành vi này, trước tiên chúng tôi chuyển sang niof tiêu chuẩn và sau đó, khi chúng tôi di chuyển từ phiên bản thứ năm của Elastic sang phiên bản thứ sáu, chúng tôi đã thử hybridfs, nhưng vấn đề này không được tái hiện. Bạn có thể đọc thêm về các loại lưu trữ đây.

Vấn đề bốn
Sau đó, có một vấn đề rất thú vị khác mà chúng tôi đã giải quyết trong thời gian kỷ lục. Chúng tôi đã bắt được nó trong 2-3 tháng vì hình mẫu của nó hoàn toàn không thể hiểu được.

Đôi khi các điều phối viên của chúng tôi đến Full GC, thường là sau bữa trưa và không bao giờ quay trở lại từ đó. Đồng thời, khi ghi lại độ trễ của GC, nó trông như thế này: mọi thứ đang diễn ra tốt đẹp, tốt, tốt, và rồi đột nhiên mọi thứ trở nên rất tồi tệ.

Lúc đầu, chúng tôi nghĩ rằng chúng tôi có một người dùng độc ác đang đưa ra một loại yêu cầu nào đó khiến điều phối viên thoát khỏi chế độ làm việc. Chúng tôi đã ghi lại các yêu cầu trong một thời gian rất dài, cố gắng tìm hiểu chuyện gì đang xảy ra.

Kết quả là, tại thời điểm người dùng đưa ra một yêu cầu lớn và gửi đến một điều phối viên Elaticsearch cụ thể, một số nút sẽ phản hồi lâu hơn các nút khác.

Và trong khi điều phối viên đang chờ phản hồi từ tất cả các nút, anh ta sẽ tích lũy các kết quả được gửi từ các nút đã phản hồi. Đối với GC, điều này có nghĩa là kiểu sử dụng heap của chúng tôi thay đổi rất nhanh. Và GC mà chúng tôi sử dụng không thể giải quyết được nhiệm vụ này.

Cách khắc phục duy nhất mà chúng tôi tìm thấy để thay đổi hành vi của cụm trong tình huống này là di chuyển sang JDK13 và sử dụng trình thu gom rác Shenandoah. Điều này đã giải quyết được vấn đề, các điều phối viên của chúng tôi đã ngừng rơi.

Đây là nơi các vấn đề với Java kết thúc và các vấn đề về băng thông bắt đầu.

"Quả mọng" với Elaticsearch: thông lượng

Cụm Elaticsearch 200 TB+

Các vấn đề về thông lượng có nghĩa là cụm của chúng tôi hoạt động ổn định, nhưng ở mức cao nhất về số lượng tài liệu được lập chỉ mục và trong quá trình thao tác, hiệu suất không đủ.

Triệu chứng đầu tiên gặp phải: trong một số “vụ nổ” trong quá trình sản xuất, khi một số lượng rất lớn nhật ký được tạo đột ngột, lỗi lập chỉ mục es_rejected_execution bắt đầu nhấp nháy thường xuyên trong Graylog.

Điều này là do thread_pool.write.queue trên một nút dữ liệu, cho đến thời điểm Elaticsearch có thể xử lý yêu cầu lập chỉ mục và tải thông tin lên phân đoạn trên đĩa, theo mặc định chỉ có thể lưu vào bộ nhớ đệm 200 yêu cầu. Và trong Tài liệu Elaticsearch Rất ít người nói về thông số này. Chỉ số lượng chủ đề tối đa và kích thước mặc định được chỉ định.

Tất nhiên, chúng tôi đã điều chỉnh giá trị này và phát hiện ra những điều sau: cụ thể, trong thiết lập của chúng tôi, có tới 300 yêu cầu được lưu vào bộ nhớ đệm khá tốt và giá trị cao hơn sẽ dẫn đến thực tế là chúng tôi lại chuyển sang Full GC.

Ngoài ra, vì đây là những loạt tin nhắn đến trong một yêu cầu nên cần phải điều chỉnh Graylog để nó không viết thường xuyên và theo từng đợt nhỏ mà theo từng đợt lớn hoặc 3 giây một lần nếu đợt vẫn chưa hoàn thành. Trong trường hợp này, hóa ra thông tin mà chúng tôi viết trong Elaticsearch sẽ có sẵn không phải sau hai giây mà là năm giây (điều này khá phù hợp với chúng tôi), mà là số lần truy cập phải được thực hiện để vượt qua một lượng lớn đống thông tin bị giảm đi.

Điều này đặc biệt quan trọng trong những thời điểm khi thứ gì đó gặp sự cố ở đâu đó và báo cáo dữ dội về nó, để không nhận được một Elastic hoàn toàn bị spam và sau một thời gian - các nút Graylog không thể hoạt động do bộ đệm bị tắc.

Ngoài ra, khi chúng tôi gặp phải những vụ nổ tương tự trong quá trình sản xuất, chúng tôi đã nhận được khiếu nại từ các lập trình viên và người thử nghiệm: vào thời điểm họ thực sự cần những nhật ký này, họ đã được cung cấp rất chậm.

Họ bắt đầu tìm ra nó. Một mặt, rõ ràng là về cơ bản, cả truy vấn tìm kiếm và truy vấn lập chỉ mục đều được xử lý trên cùng một máy vật lý và bằng cách này hay cách khác sẽ có những hạn chế nhất định.

Nhưng điều này có thể bị phá vỡ một phần do trong phiên bản thứ sáu của Elaticsearch, một thuật toán đã xuất hiện cho phép bạn phân phối các truy vấn giữa các nút dữ liệu có liên quan không theo nguyên tắc quay vòng ngẫu nhiên (vùng chứa lập chỉ mục và giữ dữ liệu chính- phân đoạn có thể rất bận, sẽ không có cách nào để phản hồi nhanh chóng), nhưng để chuyển tiếp yêu cầu này đến vùng chứa ít tải hơn có phân đoạn bản sao, điều này sẽ phản hồi nhanh hơn nhiều. Nói cách khác, chúng ta đã đạt được use_adaptive_replica_selection: true.

Hình ảnh đọc bắt đầu trông như thế này:

Cụm Elaticsearch 200 TB+

Việc chuyển đổi sang thuật toán này giúp cải thiện đáng kể thời gian truy vấn trong những thời điểm chúng tôi phải ghi một lượng lớn nhật ký.

Cuối cùng, vấn đề chính là việc dỡ bỏ trung tâm dữ liệu một cách dễ dàng.

Những gì chúng tôi muốn từ cụm ngay sau khi mất kết nối với một DC:

  • Nếu chúng ta có một máy chủ hiện tại trong trung tâm dữ liệu bị lỗi thì nó sẽ được chọn lại và chuyển vai trò sang một nút khác trong một DC khác.
  • Master sẽ nhanh chóng loại bỏ tất cả các nút không thể truy cập khỏi cụm.
  • Dựa vào những phân đoạn còn lại, anh ấy sẽ hiểu: trong trung tâm dữ liệu bị mất, chúng tôi có những phân đoạn chính như vậy, anh ấy sẽ nhanh chóng quảng bá các phân đoạn bản sao bổ sung trong các trung tâm dữ liệu còn lại và chúng tôi sẽ tiếp tục lập chỉ mục dữ liệu.
  • Do đó, thông lượng ghi và đọc của cụm sẽ giảm dần, nhưng nhìn chung mọi thứ sẽ hoạt động, tuy chậm nhưng ổn định.

Hóa ra, chúng tôi muốn một cái gì đó như thế này:

Cụm Elaticsearch 200 TB+

Và chúng tôi đã nhận được những điều sau đây:

Cụm Elaticsearch 200 TB+

Chuyện đã xảy ra như thế nào?

Khi trung tâm dữ liệu sụp đổ, chủ nhân của chúng tôi trở thành nút cổ chai.

Tại sao?

Thực tế là chủ có một TaskBatcher, chịu trách nhiệm phân phối một số nhiệm vụ và sự kiện nhất định trong cụm. Bất kỳ nút nào thoát ra, bất kỳ quảng bá phân đoạn nào từ bản sao lên chính, bất kỳ tác vụ nào để tạo phân đoạn ở đâu đó - tất cả điều này trước tiên sẽ đến TaskBatcher, nơi nó được xử lý tuần tự và trong một luồng.

Vào thời điểm một trung tâm dữ liệu bị thu hồi, hóa ra tất cả các nút dữ liệu trong các trung tâm dữ liệu còn tồn tại đều coi nhiệm vụ của mình là phải thông báo cho chủ nhân “chúng tôi đã mất các phân đoạn này và các nút dữ liệu như vậy”.

Đồng thời, các nút dữ liệu còn sống sót đã gửi tất cả thông tin này đến chủ hiện tại và cố gắng chờ xác nhận rằng chủ nhân đã chấp nhận nó. Họ không chờ đợi điều này, vì người chủ nhận nhiệm vụ nhanh hơn mức anh ta có thể trả lời. Các nút đã hết thời gian chờ đợi các yêu cầu lặp lại và chủ nhân tại thời điểm này thậm chí không cố gắng trả lời chúng mà hoàn toàn tập trung vào nhiệm vụ sắp xếp các yêu cầu theo mức độ ưu tiên.

Ở dạng thiết bị đầu cuối, hóa ra các nút dữ liệu đã spam bản gốc đến mức nó chuyển sang GC đầy đủ. Sau đó, vai trò chính của chúng tôi chuyển sang một số nút tiếp theo, điều tương tự cũng xảy ra với nó và kết quả là cụm hoàn toàn sụp đổ.

Chúng tôi đã thực hiện các phép đo và trước phiên bản 6.4.0, khi lỗi này đã được khắc phục, chúng tôi chỉ có thể xuất đồng thời 10 nút dữ liệu trong tổng số 360 nút để tắt hoàn toàn cụm.

Nó trông giống như thế này:

Cụm Elaticsearch 200 TB+

Sau phiên bản 6.4.0, lỗi khủng khiếp này đã được sửa, các nút dữ liệu đã ngừng giết bản gốc. Nhưng điều đó không làm cho anh ấy “thông minh hơn”. Cụ thể: khi chúng tôi xuất ra 2, 3 hoặc 10 nút dữ liệu (bất kỳ số nào khác ngoài một), nút chủ sẽ nhận được một số thông báo đầu tiên cho biết nút A đã rời đi và cố gắng thông báo cho nút B, nút C về điều này, nút D.

Và hiện tại, điều này chỉ có thể được giải quyết bằng cách đặt thời gian chờ cho những nỗ lực nói với ai đó về điều gì đó, tương đương khoảng 20-30 giây và do đó kiểm soát tốc độ di chuyển của trung tâm dữ liệu ra khỏi cụm.

Về nguyên tắc, điều này phù hợp với các yêu cầu ban đầu được đưa ra cho sản phẩm cuối cùng như một phần của dự án, nhưng theo quan điểm “khoa học thuần túy” thì đây là một lỗi. Nhân tiện, lỗi này đã được các nhà phát triển sửa thành công trong phiên bản 7.2.

Hơn nữa, khi một nút dữ liệu nào đó bị hỏng, hóa ra việc phổ biến thông tin về lối ra của nó còn quan trọng hơn việc thông báo cho toàn bộ cụm rằng có các phân đoạn chính như vậy trên đó (để quảng bá phân đoạn bản sao trong dữ liệu khác). trung tâm ở phần chính và thông tin có thể được viết trên đó).

Do đó, khi mọi thứ đã hết, các nút dữ liệu được phát hành sẽ không ngay lập tức bị đánh dấu là cũ. Theo đó, chúng tôi buộc phải đợi cho đến khi tất cả các ping đã hết thời gian đối với các nút dữ liệu được phát hành và chỉ sau đó, cụm của chúng tôi mới bắt đầu cho chúng tôi biết rằng ở đó, ở đó và ở đó chúng tôi cần tiếp tục ghi lại thông tin. Bạn có thể đọc thêm về điều này đây.

Như vậy, thao tác rút trung tâm dữ liệu hiện nay chúng ta mất khoảng 5 phút trong giờ cao điểm. Đối với một bức tượng khổng lồ to lớn và vụng về như vậy thì đây là một kết quả khá tốt.

Kết quả là chúng tôi đã đi đến quyết định sau:

  • Chúng tôi có 360 nút dữ liệu với đĩa 700 gigabyte.
  • 60 điều phối viên để định tuyến lưu lượng truy cập thông qua các nút dữ liệu tương tự.
  • 40 máy chủ mà chúng tôi đã để lại như một loại di sản kể từ các phiên bản trước 6.4.0 - để tồn tại sau khi trung tâm dữ liệu bị thu hồi, chúng tôi đã chuẩn bị tinh thần để mất một số máy để đảm bảo có đủ số lượng máy chủ ngay cả trong tình huống xấu nhất
  • Bất kỳ nỗ lực nào để kết hợp các vai trò trên một vùng chứa đều dẫn đến thực tế là sớm hay muộn nút này sẽ bị hỏng khi tải.
  • Toàn bộ cụm sử dụng heap.size là 31 gigabyte: mọi nỗ lực giảm kích thước đều dẫn đến việc tiêu diệt một số nút trong các truy vấn tìm kiếm nặng bằng ký tự đại diện hàng đầu hoặc nhận được bộ ngắt mạch trong chính Elaticsearch.
  • Ngoài ra, để đảm bảo hiệu suất tìm kiếm, chúng tôi đã cố gắng giữ số lượng đối tượng trong cụm càng ít càng tốt để xử lý càng ít sự kiện càng tốt trong nút cổ chai mà chúng tôi có trong bản gốc.

Cuối cùng về giám sát

Để đảm bảo rằng tất cả điều này hoạt động như dự định, chúng tôi giám sát những điều sau:

  • Mỗi nút dữ liệu báo cáo cho đám mây của chúng tôi rằng nó tồn tại và có những phân đoạn như vậy trên đó. Khi chúng tôi dập tắt thứ gì đó ở đâu đó, cụm sẽ báo cáo sau 2-3 giây rằng ở trung tâm A, chúng tôi đã dập tắt các nút 2, 3 và 4 - điều này có nghĩa là ở các trung tâm dữ liệu khác, trong mọi trường hợp, chúng tôi không thể dập tắt các nút mà trên đó chỉ có một phân đoạn bên trái.
  • Biết được bản chất hành vi của chủ nhân, chúng tôi xem xét rất kỹ số lượng nhiệm vụ đang chờ xử lý. Bởi vì ngay cả một nhiệm vụ bị mắc kẹt, nếu nó không hết thời gian, về mặt lý thuyết, trong một số tình huống khẩn cấp có thể trở thành lý do tại sao, chẳng hạn như việc quảng cáo phân đoạn bản sao trong phần chính không hoạt động, đó là lý do tại sao việc lập chỉ mục sẽ ngừng hoạt động.
  • Chúng tôi cũng xem xét rất kỹ sự chậm trễ của bộ thu gom rác vì chúng tôi đã gặp khó khăn lớn với vấn đề này trong quá trình tối ưu hóa.
  • Từ chối theo chuỗi để hiểu trước nút cổ chai ở đâu.
  • Vâng, các số liệu tiêu chuẩn như heap, RAM và I/O.

Khi xây dựng giám sát, bạn phải tính đến các tính năng của Thread Pool trong Elaticsearch. Tài liệu Elaticsearch mô tả các tùy chọn cấu hình và các giá trị mặc định để tìm kiếm và lập chỉ mục, nhưng hoàn toàn không nói gì về thread_pool.management. Các luồng này xử lý, đặc biệt là các truy vấn như _cat/shards và các truy vấn tương tự khác, thuận tiện sử dụng khi viết giám sát. Cụm càng lớn thì càng có nhiều yêu cầu như vậy được thực thi trên một đơn vị thời gian và thread_pool.management đã nói ở trên không những không được trình bày trong tài liệu chính thức mà còn bị giới hạn theo mặc định ở 5 luồng, được xử lý rất nhanh sau đó giám sát nào ngừng hoạt động chính xác.

Điều tôi muốn nói để kết luận: chúng tôi đã làm được! Chúng tôi có thể cung cấp cho các lập trình viên và nhà phát triển của mình một công cụ mà trong hầu hết mọi tình huống, có thể cung cấp thông tin nhanh chóng và đáng tin cậy về những gì đang diễn ra trong quá trình sản xuất.

Đúng, nó hóa ra khá phức tạp, nhưng tuy nhiên, chúng tôi đã cố gắng đáp ứng mong muốn của mình vào các sản phẩm hiện có mà chúng tôi không phải tự vá và viết lại.

Cụm Elaticsearch 200 TB+

Nguồn: www.habr.com

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