Câu hỏi đồng bộ các tệp lớn FreeBSD


Tôi đang gặp khó khăn trong việc ôm đầu.

Thiết lập thử nghiệm của tôi có một kịch bản shell liên tục gọi 'ls -la' trên một tập tin 1G và in ra thời gian kể từ lần cuối cùng nó chạy. Sau đó tôi chạy một chương trình để sửa đổi các phần của tập tin và đồng bộ nó vào đĩa.

Cho dù tôi gọi fsync hay hệ thống không đồng bộ, hoặc thậm chí nếu tôi sử dụng pwrite để viết các phần khác nhau (vẫn kiểm tra bit đó), khi đồng bộ xảy ra 'ls -la' sẽ đóng băng cho toàn bộ thời gian đồng bộ - trong khoảng 7-40 giây (tùy thuộc vào độ lệch của các sửa đổi).

Nếu tôi sử dụng msync để đồng bộ các khối cùng một lúc, hoặc cố gắng fsync thường xuyên hơn khi tôi viết, thời lượng nhận được lớn hơn nhiều (có thể là 10x, nhưng thậm chí lâu hơn tùy thuộc vào mức độ thường xuyên tôi thực hiện). Các msync ở trên chỉ viết tại 16KB / Giao dịch, ngay cả khi các trang được tuần tự.

Tôi đã đọc ở đâu đó rằng OpenBSD thực hiện 'một phần tập tin ghi' hoặc một cái gì đó. Tôi không thể nhớ nổi bây giờ.

Có anyway tôi có thể làm một cái gì đó tương tự với hiệu quả của fsync mà không có các tập tin khóa bị khóa xuống cho toàn bộ thời gian?

Trên thực tế, vấn đề 'A' (mà tôi nghĩ 'B' là giải pháp), chỉ đơn giản là làm việc với các tệp lớn và 'khuyến khích' chúng để ghi vào đĩa để bộ nhớ có thể được giải phóng nhanh chóng nếu cần được. Chỉ cần bỏ NO_SYNC là không tốt vì những thay đổi sẽ xảy ra cùng lúc, gây ra tình huống này. Không ai trong số các tùy chọn madvise khác dường như giúp đỡ một trong hai. Tức là, nếu tôi không đồng bộ thì các trang dường như vẫn ở xung quanh cho đến khi tôi hết bộ nhớ, nơi chúng sẽ đột ngột bắt đầu hoán đổi (mặc dù chỉ ở mức 16KB / Giao dịch và MB / s rất thấp).

Làm thế nào trên trái đất để bạn làm việc với các tập tin lớn trên FreeBSD?


DUNG DỊCH:

Tôi thấy rằng bằng cách điều chỉnh khối msync của tôi và sử dụng MS_ASYNC thay vì MS_SYNC trong cuộc gọi msync tôi có thể nhận được hiệu suất tôi muốn trong khi vẫn cho phép các quy trình khác mở và đọc / đọc tệp.


6
2017-10-16 00:48


gốc




Các câu trả lời:


FreeBSD sẽ sử dụng bộ nhớ miễn phí cho bộ nhớ đệm I / O, cũng như các UNIX khác. Trên một hệ thống có nhiều bộ nhớ miễn phí và ít người dùng, các tệp thực sự lớn có thể được sử dụng hoàn toàn trong bộ nhớ. Vì vậy, có vẻ như nhiều bộ nhớ hơn được sử dụng.

close() (fclose() ) và fsync (fflush() )  là hệ thống duy nhất gọi là lực hệ điều hành để ghi bộ nhớ cache. Điều này chỉ đúng nếu không có quy trình nào khác mở tệp. freeBSD không có fdatasync mà chỉ ghi dữ liệu đã lưu vào bộ nhớ cache, chứ không phải siêu dữ liệu vào đĩa vật lý.

Từ BSD 4.4 trên Bạn có thể theo dõi phân trang và lưu trữ tệp bằng mincore() syscall.

Vì vậy, bạn phải fflush sau mỗi vài viết.

Chơi với parms bộ nhớ đệm đĩa:

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/configtuning-disk.html

1
2017-10-16 01:02



Cảm ơn các liên kết. Tôi nghĩ câu hỏi của tôi được yêu cầu tốt hơn với bản chỉnh sửa thứ hai - tôi khá vui vì toàn bộ tệp được lưu vào bộ nhớ cache, đó là những gì tôi muốn - vấn đề là nếu tất cả được lưu trong bộ nhớ cache thì ở giai đoạn nào đó cần phải ghi đĩa, và khi điều này xảy ra tập tin bị khóa cho toàn bộ thời gian. Tệp sẽ vẫn có sẵn để đọc bất kỳ lúc nào. Đỏ bừng sau mỗi lần viết có nghĩa là ứng dụng bị giới hạn bởi đĩa, ngay cả khi có nhiều bộ nhớ khả dụng. - Haru


Bạn đang giải quyết vấn đề của mình (theo dõi trạng thái của tệp) hoàn toàn sai. Thay vì định kỳ kiểm tra lại trạng thái của tệp (và chạy vào các vấn đề đồng thời I / O), chương trình của bạn chỉ cần yêu cầu hạt nhân được thông báo, khi một tệp cụ thể (hoặc tập hợp các tệp) thay đổi.

Cơ chế để làm điều này tồn tại trên tất cả các Unix hiện đại, nhưng, thật không may, chúng không giống nhau ...

Trên họ Unix của BSD, điều này được thực hiện với kqueue / kevent. Trên Linux có inotify. Trên Solaris có bình chọn và / dev / poll.

Có các thư viện đa nền tảng, ẩn các chi tiết triển khai hệ điều hành và cung cấp cho bạn API di động. Nếu bạn cần tính di động, hãy tìm File Alterations Monitor hoặc tập hợp con hiện đại hơn được gọi là gamin (được chuyển vào / usr / ports / devel / gamin). Nếu ứng dụng của bạn chỉ dành cho BSD (Miễn phí), bạn có thể sử dụng trực tiếp kqueue / kevent.


1
2017-10-19 16:09



Tôi nghĩ rằng bạn có thể đã hiểu lầm mục đích của tôi cho việc bỏ phiếu - nó chỉ là để cho thấy rằng không có gì khác có thể mở / đọc các tập tin trong khi nó đang được sync'd. Những gì tôi muốn là cho phép các quá trình khác (có thể không được kiểm soát bởi tôi) để có thể mở và đọc dữ liệu trong khi nó đang được đồng bộ hóa. Tôi có thể làm điều đó ngay bây giờ với msync bằng MS_ASYNC. Nhưng cảm ơn bạn - Tôi làm cho việc sử dụng kqueue / kevent để theo dõi các thay đổi tập tin, vv trong các lĩnh vực khác. - Haru


http://www.unix.com/man-page/FreeBSD/4/syncer/

Giải thích rõ ràng vấn đề của bạn. Bộ đồng bộ xóa bộ đệm bẩn (bộ đệm được cập nhật) thành đĩa định kỳ. Đó là những gì bạn muốn tránh. Xem sysctl có thể làm gì cho vấn đề của bạn.


0
2017-10-17 02:48



Các flushes định kỳ có thể tránh được bằng cách ánh xạ với NO_SYNC. Vấn đề là ở một số giai đoạn dữ liệu sẽ cần phải được sync'd vào đĩa. Khi điều đó xảy ra, nó thực hiện tất cả trong một lần và khóa tệp trong thời gian đồng bộ hóa. Trong trường hợp các tệp lớn, điều này có thể dễ dàng là một vài phút. Nếu tôi cố ý đồng bộ hóa rất thường xuyên để tập tin không bị khóa trong thời gian dài - thì ứng dụng bị giới hạn bởi tốc độ đĩa ngay cả khi có nhiều bộ nhớ. - Haru
Bạn có thể cần ổ SSD nếu điều này thực sự là vấn đề bạn làm cho nó ra được. Về cơ bản, từ những gì bạn đã nói có IS không có giải pháp thực sự để chờ đợi. Bây giờ bạn chỉ ra rằng đồng bộ định kỳ của bạn làm chậm quá trình chuyển sang tốc độ I / O đĩa, điều luôn luôn là trường hợp trong thế giới máy tính. Câu trả lời là I / O đĩa nhanh hơn, không có câu trả lời nào khác. - jim mcnamara
Vấn đề là khóa độc quyền của os trên tệp khi đồng bộ hóa. Để hiển thị rằng đĩa io không phải là một vấn đề - hãy tưởng tượng có 2 tệp mmaped giống hệt nhau. Viết dữ liệu cho cả hai. Có tất cả các lần đọc xảy ra trên một tệp. Đồng bộ hóa tệp khác vào đĩa - người dùng vẫn có thể truy cập vào tệp không đồng bộ hóa vì nó không được đồng bộ hóa. Khi lần đầu tiên được đồng bộ hóa, hãy trao đổi các con trỏ xung quanh và xóa tệp tạm thời. Ứng dụng chạy ở tốc độ bộ nhớ bất kể đồng bộ hóa. Nhược điểm - phức tạp và sử dụng bộ nhớ 2x! - Haru
Cập nhật - Tôi đã phát hiện ra vấn đề thực sự chỉ khi mở (hoặc mmaping) hoặc tệp trong khi nó đang được đồng bộ hóa - nó không ảnh hưởng đến khả năng đọc ánh xạ nếu tệp đã được mở và ánh xạ. Tuy nhiên đây vẫn là một vấn đề đối với tôi. (Cũng treo nếu gọi 'đọc' / 'pread'. Tôi đoán bất kỳ cuộc gọi hệ thống liên quan đến tập tin. - Haru