Chúng ta đang xếp hàng và tuần tự hóa đúng cách?


13

Chúng tôi xử lý tin nhắn thông qua nhiều dịch vụ khác nhau (một tin nhắn sẽ chạm vào 9 dịch vụ trước khi hoàn thành, mỗi dịch vụ thực hiện một chức năng liên quan đến IO cụ thể). Ngay bây giờ chúng tôi có sự kết hợp giữa trường hợp xấu nhất (tuần tự hóa hợp đồng dữ liệu XML) và trường hợp tốt nhất (MSMQ trong bộ nhớ) để thực hiện.

Bản chất của tin nhắn có nghĩa là dữ liệu tuần tự của chúng tôi kết thúc khoảng 12-15 kilobyte và chúng tôi xử lý khoảng 4 triệu tin nhắn mỗi tuần. Các tin nhắn liên tục trong MSMQ quá chậm đối với chúng tôi và khi dữ liệu tăng lên, chúng tôi cảm thấy áp lực từ các tệp ánh xạ bộ nhớ của MSMQ. Máy chủ đang ở mức 16GB sử dụng bộ nhớ và đang phát triển, chỉ để xếp hàng. Hiệu suất cũng bị giảm khi sử dụng bộ nhớ cao, vì máy bắt đầu hoán đổi. Chúng tôi đã thực hiện hành vi tự dọn dẹp MSMQ.

Tôi cảm thấy như có một phần chúng ta đang làm sai ở đây. Tôi đã thử sử dụng RavenDB để duy trì các tin nhắn và chỉ xếp hàng một mã định danh, nhưng hiệu suất ở đó rất chậm (tối đa 1000 tin nhắn mỗi phút). Tôi không chắc đó có phải là kết quả của việc sử dụng phiên bản phát triển hay không, nhưng chúng tôi chắc chắn cần thông lượng cao hơn [1]. Khái niệm này hoạt động rất tốt trong lý thuyết nhưng hiệu suất không theo nhiệm vụ.

Mẫu sử dụng có một dịch vụ hoạt động như một bộ định tuyến, tất cả đều đọc. Các dịch vụ khác sẽ đính kèm thông tin dựa trên móc bên thứ 3 của họ và chuyển tiếp trở lại bộ định tuyến. Hầu hết các đối tượng được chạm 9-12 lần, mặc dù khoảng 10% bị buộc phải lặp đi lặp lại trong hệ thống này trong một thời gian cho đến khi các bên thứ 3 phản hồi thích hợp. Các dịch vụ ngay bây giờ giải thích cho điều này và có hành vi ngủ thích hợp, vì chúng tôi sử dụng lĩnh vực ưu tiên của tin nhắn vì lý do này.

Vì vậy, câu hỏi của tôi, một ngăn xếp lý tưởng cho thông điệp truyền giữa các máy rời rạc nhưng trong môi trường C # / Windows là gì? Tôi thường bắt đầu với BinaryFormatter thay vì tuần tự hóa XML, nhưng đó là một lỗ thỏ nếu cách tốt hơn là giảm tải tuần tự hóa vào kho lưu trữ tài liệu. Do đó, câu hỏi của tôi.

[1]: Bản chất kinh doanh của chúng tôi có nghĩa là chúng tôi xử lý tin nhắn càng sớm, chúng tôi càng kiếm được nhiều tiền. Chúng tôi đã chứng minh bằng thực nghiệm rằng việc xử lý một tin nhắn vào cuối tuần có nghĩa là chúng tôi ít có khả năng kiếm được số tiền đó. Mặc dù hiệu suất của "1000 mỗi phút" nghe có vẻ nhanh, nhưng chúng tôi thực sự cần con số đó lên tới 10k / phút. Chỉ vì tôi đưa ra số trong tin nhắn mỗi tuần không có nghĩa là chúng tôi có cả tuần để xử lý những tin nhắn đó.

=============== chỉnh sửa:

Thông tin thêm

Dựa trên các ý kiến, tôi sẽ thêm một số làm rõ:

  • Tôi không chắc chắn việc xê-ri hóa là nút cổ chai của chúng tôi. Tôi đã chấm điểm cho ứng dụng và trong khi tuần tự hóa xuất hiện trong biểu đồ nhiệt, nó chỉ chịu trách nhiệm cho khoảng 2,5-3% mức sử dụng CPU của dịch vụ.

  • Tôi chủ yếu quan tâm đến sự lâu dài của các thông điệp của chúng tôi và việc lạm dụng MSMQ tiềm ẩn. Chúng tôi đang sử dụng các tin nhắn không giao dịch, không liên tục để chúng tôi có thể tiếp tục thực hiện hàng đợi và tôi thực sự muốn có ít nhất các tin nhắn liên tục để chúng tồn tại khi khởi động lại.

  • Thêm RAM là một biện pháp ngăn chặn. Máy đã đi từ 4GB -> 16GB RAM và càng ngày càng khó để hạ nó xuống để tiếp tục bổ sung thêm.

  • Do mô hình định tuyến sao của ứng dụng, một nửa thời gian một đối tượng được bật lên sau đó được đẩy vào hàng đợi, nó hoàn toàn không thay đổi. Điều này cho vay một lần nữa (IMO) để lưu trữ nó trong một số loại lưu trữ khóa-giá trị ở nơi khác và chỉ cần chuyển định danh thư.

  • Mẫu định tuyến sao là không thể thiếu đối với ứng dụng và sẽ không thay đổi. Chúng tôi không thể ứng dụng rết nó vì mọi phần trên đường vận hành không đồng bộ (theo kiểu bỏ phiếu) và chúng tôi muốn tập trung hành vi thử lại ở một nơi.

  • Logic ứng dụng được viết bằng C #, các đối tượng là các POCO bất biến, môi trường triển khai mục tiêu là Windows Server 2012 và chúng tôi được phép đứng lên các máy bổ sung nếu một phần mềm cụ thể chỉ được hỗ trợ trong Linux.

  • Mục tiêu của tôi là duy trì thông lượng hiện tại trong khi giảm dung lượng bộ nhớ và tăng khả năng chịu lỗi với số vốn tối thiểu.


Nhận xét đã được làm sạch vì các điểm liên quan được đưa vào câu hỏi.
ChrisF

Sẽ là hợp lý khi giải quyết vấn đề cấp bách nhất trước khi lo lắng về việc hoán đổi các hệ thống con xếp hàng (mặc dù điều đó vẫn có thể đáng làm sau cùng). Thực tế là bộ nhớ đang phát triển ngoài tầm kiểm soát cho thấy vẫn còn rò rỉ ở đâu đó. Những gì (nếu có) hồ sơ bộ nhớ đã được thực hiện?
Dan Lyons

@DanLyons: sự tăng trưởng bộ nhớ duy nhất là trong MSMQ. Không ai thực sự nói về nó, nhưng dường như là do các tin nhắn không liên tục được ánh xạ bộ nhớ. Vì chúng tôi tuần tự hóa rất nhiều dữ liệu, nó sẽ giữ một lượng bộ nhớ đáng kể được phân bổ. Bộ nhớ (cuối cùng) được lấy lại khi các tin nhắn được tiêu thụ và dọn dẹp nội bộ của MSMQ chạy.
Bryan Boettcher

Câu trả lời:


1

Dưới đây là một số điểm chuẩn hàng đợi mà bạn có thể quan tâm. MSMQ sẽ có khả năng xử lý 10K tin nhắn mỗi giây. Nó có thể là một vấn đề cấu hình hoặc có lẽ khách hàng không theo kịp việc đọc hàng đợi? Cũng lưu ý rằng ZeroMQ nhanh đến mức nào trong các điểm chuẩn đó (khoảng 100 nghìn tin nhắn mỗi giây), nó không cung cấp tùy chọn bền bỉ nhưng nó sẽ đưa bạn đến nơi bạn muốn trở thành người khôn ngoan.


4

Chúng tôi đã có một tình huống hơi giống nhau vài năm trước, với một hệ thống tin nhắn xếp hàng (dấu vân tay âm thanh trong trường hợp của chúng tôi). Chúng tôi đánh giá cao sự bền bỉ của các gói dữ liệu bị mê hoặc, nhưng chúng tôi phát hiện ra rằng việc thu hút mọi thứ vào đĩa và tiêu thụ hàng đợi từ đĩa rất tốn kém.

Nếu chúng tôi chuyển sang hàng đợi dựa trên bộ nhớ, hiệu suất là đặc biệt, nhưng chúng tôi đã gặp vấn đề lớn. Thỉnh thoảng, người tiêu dùng của hàng đợi trở nên không có sẵn trong một khoảng thời gian đáng kể (các yếu tố người tiêu dùng và nhà sản xuất trong trường hợp của chúng tôi được kết nối qua mạng WAN), do đó, hàng đợi của nhà sản xuất sẽ phát triển đến mức không thể quản lý được và giống như trường hợp của bạn, một khi mức tiêu thụ bộ nhớ rất cao, việc đập bộ nhớ quá mức trong quá trình tráo đổi đã khiến hệ thống thu thập dữ liệu hoàn chỉnh.

Chúng tôi đã thiết kế một hàng đợi mà chúng tôi đặt tên VMQueue (đối với Hàng đợi bộ nhớ ảo, một cái tên rất tệ khi xem lại). Ý tưởng của hàng đợi này là nếu quy trình tiêu dùng đang chạy ngang bằng, nói cách khác, xử lý đủ nhanh để có thể giữ số lượng phần tử bị mê hoặc dưới một mức nhất định, về cơ bản nó có cùng hiệu năng của bộ nhớ- xếp hàng dựa. Tuy nhiên, khi người tiêu dùng chậm lại hoặc không có sẵn và hàng đợi của nhà sản xuất tăng lên một kích thước nhất định, thì hàng đợi sẽ bắt đầu tự động phân trang các phần tử đến và đi từ đĩa (sử dụngBinaryFormatterbằng cách tuần tự hóa bằng cách này). Quá trình này giữ cho việc sử dụng bộ nhớ được kiểm soát hoàn toàn và quá trình phân trang diễn ra nhanh hoặc ít nhất là nhanh hơn nhiều so với việc hoán đổi bộ nhớ ảo xảy ra trong quá trình tải bộ nhớ nặng. Khi người tiêu dùng quản lý để thoát hàng đợi dưới ngưỡng, nó sẽ tiếp tục hoạt động như một hàng đợi dựa trên bộ nhớ thuần túy

Nếu hệ thống gặp sự cố hoặc khởi động lại, thì hàng đợi có thể khôi phục tất cả các phần tử phân trang được lưu trữ vào đĩa, nó sẽ chỉ mất các phần tử vẫn được giữ trong bộ nhớ trước khi gặp sự cố. Nếu bạn có thể đủ khả năng để mất một số lượng hạn chế các gói trong khi gặp sự cố hoặc khởi động lại, hàng đợi này có thể hữu ích.

Nếu bạn quan tâm, tôi có thể chia sẻ VMQueuemã nguồn lớp để bạn có thể chơi xung quanh nó. Hàng đợi sẽ chấp nhận bất kỳ lớp nào được đánh dấu là Nối tiếp. Khi tạo hàng đợi, bạn thiết lập kích thước của trang theo số phần tử. Giao diện lớp gần giống với lớp Queue tiêu chuẩn. Tuy nhiên, mã này rất cũ, (.net 1.1) vì vậy không có giao diện chung nào tồn tại một cách đáng tiếc.

Tôi biết rằng việc chuyển từ công nghệ MSMQ đã được chứng minh là một sự đánh cược rất lớn, tuy nhiên hàng đợi này đã hoạt động đáng tin cậy trong gần 6 năm và đã cho phép chúng tôi tồn tại và phục hồi sau các tình huống mà máy sản xuất đã ngoại tuyến trong vài tuần! Xin vui lòng cho tôi biết nếu bạn quan tâm. :)


1

Hệ thống HP ProLiant ML350G5 nhận được 82 nghìn giao dịch mỗi phút - tức là nó có hơn 8 lần thông lượng "10k / phút" mà bạn đã đề cập.

Hiệu suất: 82.774 tpmC

Ngoài ra, thành thật mà nói, tôi vừa mới sử dụng RAM 64 hoặc thậm chí 128 GB - RAM rất rẻ. Greensasta chỉ ra sự khác biệt giữa "ném RAM vào nó" và "lấy một anh chàng thông minh ở MIT để tối ưu hóa nó" và RAM thắng.

Ông đã kết thúc với một máy SQL Server được trang bị 64 GB RAM và một số máy đầu cuối chạy các trang ASP.NET ... Trang web, swaptree.com, xử lý thành viên hiện tại của hơn 400.000 người dùng (tăng nhanh) không có khó khăn ...

Lưu ý "máy đã hết 16 GB RAM" là quá đủ, với một bài viết chỉ ra một máy chủ đang xử lý 400 nghìn người dùng trên 64 GB RAM.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.