đồng bộ hóa các tệp lớn FreeBSD


6

Tôi đang có một thời gian khó khăn để có được đầu của tôi xung quanh này.

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

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

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

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

Có cách nào tôi có thể làm điều gì đó tương tự với hiệu quả của fsync mà không bị cài đặt tập tin trong suốt thời gian không?

Trên thực tế, vấn đề 'A' (mà tôi nghĩ rằng 'B' này 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 được ghi vào đĩa để bộ nhớ có thể được giải phóng nhanh chóng nếu cần thì, là, bị, ở. Đơn giản chỉ cần sử dụng NO_SYNC là không tốt vì những thay đổi sẽ xảy ra cùng một lúc, gây ra tình trạng này. Không có lựa chọn madvise nào khác có vẻ giúp cả. Đó là, nếu tôi không đồng bộ hóa thì các trang dường như dính xung quanh cho đến khi tôi hết bộ nhớ, nơi chúng sẽ đột nhiên bắt đầu hoán đổi (mặc dù chỉ 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 lớn trên FreeBSD?


GIẢI PHÁP:

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

Câu trả lời:


1

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

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

Từ BSD 4.4 trở đi Bạn có thể theo dõi phân trang và lưu trữ bộ đệm với tòa nhà mincore().

Vì vậy, bạn phải fflush sau mỗi vài lần 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

Cảm ơn các liên kết. Tôi nghĩ rằng câu hỏi của tôi được hỏi tốt hơn với lần chỉnh sửa thứ hai của tôi - tôi khá vui khi toàn bộ tệp được lưu vào bộ đệm, đó thực chất là những gì tôi muốn - vấn đề là nếu tất cả được lưu vào bộ đệm thì ở một giai đoạn nào đó nó cần được ghi vào và khi điều này xảy ra, tập tin sẽ bị khóa trong toàn bộ thời gian. Các tập tin vẫn nên có sẵn để đọc bất cứ lúc nào. Rửa sau mỗi lần ghi 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

1

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

Các cơ chế để thực hiện đ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 gia đình 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ó cuộc thăm dò và / dev / cuộc thăm dò.

Có các thư viện đa nền tảng, ẩn các chi tiết triển khai HĐH và cung cấp cho bạn API di động. Nếu bạn cần tính di động, hãy tìm Trình giám sát thay đổi tệp hoặc tập hợp con hiện đại hơn của nó được gọi là gamin (được chuyển trong / usr / cổng / 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
Tôi nghĩ rằng bạn có thể đã hiểu nhầm mục đích của tôi trong cuộc bỏ phiếu - đó chỉ là để cho thấy rằng không có gì khác có thể mở / đọc tệp trong khi nó đang được đồng bộ hóa. Điều tôi muốn là cho phép các quá trình khác (có thể không do tôi kiểm soát) 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 sử dụng kqueue / kevent để theo dõi thay đổi tập tin, vv trong các lĩnh vực khác.
Haru

0

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

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


1
Có thể tránh các đợt xả định kỳ 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 được đồng bộ hóa vào đĩa. Khi điều đó xảy ra, nó sẽ thực hiện tất cả trong một lần và khóa tệp trong suốt 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ố tình đồng bộ hóa rất thường xuyên để tệp không bị khóa trong bao lâu - thì ứng dụng bị giới hạn bởi tốc độ đĩa ngay cả khi có nhiều bộ nhớ khả dụng.
Haru

Bạn có thể cần ổ đĩa SSD nếu đây thực sự là vấn đề bạn gặp phải. Về cơ bản, từ những gì bạn đã nói, không có giải pháp thực sự nào cho sự chờ đợi. Bây giờ bạn chỉ ra rằng đồng bộ hóa định kỳ của bạn đã làm chậm quá trình vào tốc độ I / O của đĩa, điều luôn xảy ra 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 os độc quyền trên tập tin khi đồng bộ hóa. Để chỉ ra rằng đĩa io không phải là một vấn đề - hãy tưởng tượng có 2 tệp được ghép 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 tin. Đồng bộ hóa tệp khác vào đĩa - người dùng vẫn có thể truy cập 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, 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

1
Cập nhật - Tôi đã phát hiện ra sự cố chỉ thực sự khi mở (hoặc mmaping) hoặc tệp trong khi nó đượ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 bị treo nếu gọi 'đọc' / 'pread'. Tôi đoán bất kỳ cuộc gọi hệ thống nào liên quan đến tệp.
Haru
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.