Điểm:3

hệ thống tập tin "đúng lúc" sử dụng inotifywait và mkfifo

lá cờ ru

Tôi đang viết một số phần mềm trung gian tổng thể - về cơ bản, tôi có một số mã cũ cần mở 100.000 tệp chỉ để đọc, hy vọng tất cả chúng sẽ nằm trong một thư mục. Nó không bao giờ viết. Nó là đa xử lý nên nó có thể cố gắng mở ~30 tệp cùng một lúc. Theo cách cũ, tôi sẽ phải thực sự sao chép các tệp vào thư mục đó (hoặc sử dụng các liên kết, NFS, v.v.). Đáng chú ý là tôi không có khả năng thay đổi mã cũ này - nó chỉ là mã nhị phân.

Tôi có một số mã mới, ưa thích có thể truy xuất một tệp gần như ngay lập tức. Tôi muốn liên kết những thứ này lại với nhau, vì vậy khi mã cũ cố gắng mở tệp, nó thực sự đang chạy mã mới trong thời gian thực.

Vì vậy, tôi đã nghĩ đến mkfifo và inotifywait. Thay vì một thư mục gồm 100.000 tệp, tôi có thể tạo một thư mục gồm 100.000 đường ống được đặt tên. Càng xa càng tốt. Mã kế thừa sẽ mở các tệp mà không biết rằng chúng thực sự được đặt tên là các đường dẫn. Vấn đề là, tôi không biết mã kế thừa sẽ mở các tệp theo thứ tự nào (tốt, phải không?). Vì vậy, tôi muốn KÍCH HOẠT đường ống có tên VIẾT (từ mã mới ưa thích của tôi) khi mã kế thừa được đưa vào để đọc. Tôi không thể tạo ra 100.000 lượt viết và chặn tất cả chúng. Vì vậy, tôi nghĩ này - inotifywait có ý nghĩa. Mỗi khi di sản mở đường ống, nó sẽ kích hoạt một sự kiện đã đọc, sau đó có thể sử dụng sự kiện này để sinh ra trình ghi đường ống trong nền. Vấn đề là.. inotifywait không kích hoạt sự kiện đọc cho đến SAU KHI người viết đã được sinh ra!

Bất kỳ ý tưởng làm thế nào để giải quyết điều này? Về cơ bản - tôi muốn chặn một tệp đang mở, chặn trong vài trăm mili giây trong khi tôi truy xuất nội dung của tệp, sau đó trả lại nội dung đó. Lý tưởng nhất là tôi không phải tạo một hệ thống tệp FUSE tùy chỉnh để thực hiện việc này.. nó chỉ là một tệp chỉ đọc được mở. Vấn đề là điều này cần chạy nhanh và song song.. và tôi không biết tệp nào sẽ được mở theo thứ tự nào. Phải là một cách nhanh chóng và bẩn thỉu!

Cảm ơn trước cho thời gian của tất cả mọi người.

CHỈNH SỬA - để biết thêm chi tiết. Về cơ bản, tôi có một số mã kế thừa muốn tải một thư mục chứa đầy các tệp PNG. Tôi muốn các tệp PNG đó thực sự đến từ một máy chủ web trả về các tệp DICOM. Điều này yêu cầu một số chuyển đổi xấu, v.v. Mã tải PNG kế thừa rất không linh hoạt.. nó muốn những thứ này là các tệp. Vì vậy, về cơ bản, tôi muốn chặn fopen của mã tải PNG và chạy bốn dòng mã giả bash sau trước. Các $URL_FOR_DICOM dưới đây có thể được bắt nguồn từ $LADY_LOADED.png tên tập tin.

wget -q -O $LAZY_LOADED.dcm $URL_FOR_DICOM
dcmj2pnm --write-png $LAZY_LOADED.dcm $LAZY_LOADED.png
rm $LAZY_LOADED.dcm
chuyển đổi $LAZY_LOADED.png -thay đổi kích thước 1024x1024^ -trung tâm trọng lực -phạm vi 1024x1024 $LAZY_LOADED.png

Vì vậy, khi trình tải PNG cố gắng tải $LAZY_LOADED.png (thực ra là một FIFO), nó sẽ được phổ biến bằng cách sử dụng ở trên, lý tưởng nhất là được kích hoạt bằng inotify. Tôi không thể làm điều này trước vì tập dữ liệu rất lớn - như gần 0,5PB.. vì vậy tôi không thể có bản sao thứ hai xung quanh, tôi cần nó được tải nhanh chóng từ máy chủ web.

CHỈNH SỬA 2- khi thử ifnotifywait trên một ống dẫn có tên, nó sẽ chặn BẤT KỲ sự kiện nào (bao gồm mở, truy cập, đọc.. v.v.) cho đến khi ống dẫn có tên được mở để viết VÀ đọc... (nghĩa là không có cách nào để phát hiện trình đọc đã sẵn sàng).. .ý tưởng? Một người dùng khác gặp vấn đề tương tự đây không có giải pháp :(

Điểm:3
lá cờ ca

Nếu bạn cần nó "nhanh và song song", vui lòng cố gắng hết sức để không phát minh lại bánh xe: hệ thống tệp trong nhân và bộ đệm trang là đặc biệt được điều chỉnh rất nhanh, nhiều nhanh hơn "hệ thống tệp trong không gian người dùng" tùy chỉnh của bạn.

Bạn có nhiều lựa chọn tốt hơn:

  • sao chép tệp ở một vị trí tạm thời;
  • thậm chí tốt hơn, thay vì sao chép chúng, hãy sử dụng các liên kết mềm hoặc cứng;
  • xuất chúng qua giá đỡ NFS chỉ đọc

Cuối cùng, xin lưu ý rằng inotify là một nỗ lực tốt nhất framework để phân phối các sự kiện tệp. Thông báo tải nặng có thể bị mất, đặc biệt nếu sử dụng ràng buộc ngôn ngữ cấp cao (ví dụ: python).

CHỈNH SỬA: vì vậy bạn muốn chặn các lần đọc để chuyển đổi tệp nhanh chóng.Khi đọc từ một đường ống trống, mã kế thừa của bạn sẽ bị chặn, vì vậy inotifywait sẽ chỉ hiển thị sự kiện ĐỌC sau khi bạn đã viết nội dung nào đó vào cùng một đường ống. Để tránh sự cố, bạn nên cố gắng lắng nghe các sự kiện MỞ (thay vì ĐỌC). Một tùy chọn khác là sử dụng LD_PRELOAD để thay thế tòa nhà chọc trời open() cổ điển bằng một phiên bản tùy chỉnh sẽ chuyển đổi tệp theo yêu cầu.

lá cờ ru
Cảm ơn bạn đã trả lời siêu nhanh - vấn đề tôi gặp phải là ..nguồn không phải là tập tin. Nguồn là một dịch vụ web trả về hình ảnh cần được chuyển đổi, thay đổi kích thước và cắt xén. Không có cách nào tôi có đủ không gian để sao chép mọi thứ (300 terabyte trong thực tế) .. vì vậy cần phải được thực hiện "đúng lúc". Lý tưởng nhất là tôi chỉ có thể liên kết sym tới thư mục nguồn của dịch vụ web .. nhưng .. chúng nằm trên một máy khác và cũng ở định dạng nhị phân độc quyền của nhà cung cấp mà dịch vụ web chỉ có thể truy cập được. Bất kỳ ý tưởng nào ??
lá cờ ru
Đã thêm một số thông tin ở trên trong câu hỏi chính - cảm ơn bạn một lần nữa
shodanshok avatar
lá cờ ca
@mohotmoz Tôi đã chỉnh sửa câu trả lời của mình để thêm chi tiết.
lá cờ ru
cảm ơn nhiều! vì vậy khi tôi thử lắng nghe TẤT CẢ các sự kiện.. không có gì xuất hiện cho đến khi tôi mở đường ống ở đầu bên kia. khi tôi chỉ thử MỞ sự kiện .. vẫn không hoạt động : ( không có gì cho đến khi tôi mở đường ống ở đầu bên kia và bắt đầu viết. Một người khác đã gặp sự cố này: https://stackoverflow.com/questions/67639932/how-can-i-use-inotify-to-tell-when-a-named-pipe-is-opened
shodanshok avatar
lá cờ ca
@mohotmoz tốt, vì vậy có vẻ như inotify không hoạt động trên một đường ống không được kết nối - đó là một kết quả hợp lý. Nếu vậy và giả sử bạn không thể sửa đổi mã kế thừa, bạn cần mở (và tiếp tục mở) đầu ống của mình hoặc nạp chồng hàm open() qua LD_PRELOAD
Nonny Moose avatar
lá cờ gb
Bạn đã trình bày ý tưởng LD_PRELOAD giống như một suy nghĩ lại, nhưng nó có thể là cách để đi đến đây. Chắc chắn dễ dàng hơn nhiều so với việc cố gắng sao chép đúng lúc.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.