Hiện tại tôi đang thử nghiệm với một máy chủ web Haskell nhỏ được viết bằng Snap để tải và cung cấp cho khách hàng nhiều dữ liệu. Và tôi có một thời gian rất, rất khó kiểm soát quá trình máy chủ. Tại những thời điểm ngẫu nhiên, quá trình sử dụng rất nhiều CPU trong vài giây đến vài phút và trở nên vô trách nhiệm đối với các yêu cầu của khách hàng. Đôi khi sử dụng bộ nhớ tăng đột biến (và đôi khi giảm) hàng trăm megabyte trong vài giây.Làm thế nào để có được quyền kiểm soát của một đống 5GB trong Haskell?
Hy vọng rằng ai đó có nhiều kinh nghiệm hơn với các quy trình Haskell chạy dài sử dụng nhiều bộ nhớ và có thể cho tôi một số gợi ý để làm cho mọi thứ ổn định hơn. Tôi đã gỡ lỗi điều này trong nhiều ngày và tôi bắt đầu có một chút tuyệt vọng ở đây.
Một cái nhìn tổng quan nhỏ của thiết lập của tôi:
On khởi động máy chủ tôi đọc khoảng 5 GB dữ liệu vào một (lồng) cấu trúc Data.Map-giống nhau lớn trong bộ nhớ. Bản đồ lồng nhau là giá trị nghiêm ngặt và tất cả các giá trị bên trong bản đồ là các kiểu dữ liệu với tất cả các trường của chúng được thực hiện nghiêm ngặt. Tôi đã dành rất nhiều thời gian để đảm bảo không có những khối không được đánh giá. Việc nhập (tùy thuộc vào tải hệ thống của tôi) mất khoảng 5-30 phút. Điều kỳ lạ là sự biến động trong các lần chạy liên tiếp là lớn hơn tôi mong đợi, nhưng đó là một vấn đề khác.
Cấu trúc dữ liệu lớn tồn tại bên trong 'TVar' được chia sẻ bởi tất cả các luồng máy khách được tạo bởi máy chủ Snap. Khách hàng có thể yêu cầu các phần tùy ý của dữ liệu bằng cách sử dụng một ngôn ngữ truy vấn nhỏ. Lượng yêu cầu dữ liệu thường nhỏ (tối đa 300kb hoặc hơn) và chỉ chạm vào một phần nhỏ của cấu trúc dữ liệu. Tất cả các yêu cầu chỉ đọc được thực hiện bằng cách sử dụng 'readTVarIO', vì vậy chúng không yêu cầu bất kỳ giao dịch STM nào.
Máy chủ được bắt đầu bằng các cờ sau: + RTS -N -I0 -qg -qb. Điều này khởi động máy chủ ở chế độ đa luồng, vô hiệu hóa thời gian nhàn rỗi và GC song song. Điều này dường như đẩy nhanh quá trình.
Máy chủ chủ yếu chạy mà không gặp bất kỳ sự cố nào. Tuy nhiên, hiện tại, mọi yêu cầu của khách hàng đều hết thời gian chờ và CPU tăng lên 100% (hoặc thậm chí trên 100%) và tiếp tục thực hiện việc này trong một thời gian dài. Trong khi đó máy chủ không trả lời yêu cầu nữa.
Có vài lý do tôi có thể nghĩ rằng có thể gây ra việc sử dụng CPU:
Yêu cầu chỉ mất rất nhiều thời gian vì có rất nhiều công việc phải làm. Điều này là hơi khó xảy ra bởi vì đôi khi nó xảy ra cho các yêu cầu đã được chứng minh là rất nhanh trong các lần chạy trước đó (với tốc độ nhanh, tôi có nghĩa là 20-80ms hoặc hơn).
Vẫn còn một số khối không được đánh giá cần phải được tính trước khi dữ liệu có thể được xử lý và gửi cho khách hàng. Điều này cũng không chắc chắn, với lý do tương tự như điểm trước đó.
Làm cách nào đó thu thập rác thải vào và bắt đầu quét toàn bộ vùng 5 GB của tôi. Tôi có thể tưởng tượng điều này có thể mất rất nhiều thời gian.
Vấn đề là tôi không biết làm cách nào để tìm hiểu chính xác những gì đang diễn ra và phải làm gì. Bởi vì quá trình nhập mất quá nhiều thời gian nên không hiển thị cho tôi bất kỳ điều gì hữu ích. Dường như không có cách nào để bật và tắt điều kiện từ profiler trong mã.
Cá nhân tôi nghi ngờ GC là vấn đề ở đây.Tôi đang sử dụng GHC7 mà dường như có rất nhiều tùy chọn để tinh chỉnh cách thức hoạt động của GC.
Bạn khuyên bạn nên sử dụng cài đặt GC nào khi sử dụng đống lớn với dữ liệu chung rất ổn định?
Hmmm .. thú vị .. bao nhiêu RAM hộp có trên đó bạn đang chạy ứng dụng máy chủ này – Ankur
Có tổng cộng 8GB RAM trên máy của tôi. Điều đó là đủ. –
Vâng .. có vẻ như là đủ để tránh lỗi trang – Ankur