Điều này giống như một câu hỏi dài vì tất cả ngữ cảnh. Có 2 câu hỏi bên trong tiểu thuyết bên dưới. Cảm ơn bạn đã dành thời gian để đọc điều này và cung cấp hỗ trợ.Bộ nhớ ánh xạ MappedByteBuffer hoặc ByteBuffer trực tiếp để thực hiện DB?
Tình hình
Tôi đang làm việc trên một kho dữ liệu thực hiện khả năng mở rộng có thể hỗ trợ làm việc với các tập tin dữ liệu từ một vài KB đến một TB hoặc nhiều hơn trong kích thước trên một hệ thống 32-bit hoặc 64-bit.
Kho dữ liệu sử dụng thiết kế Sao chép trên ghi; luôn bổ sung dữ liệu mới hoặc sửa đổi vào cuối tệp dữ liệu và không bao giờ thực hiện chỉnh sửa tại chỗ cho dữ liệu hiện có.
Hệ thống có thể lưu trữ 1 hoặc nhiều cơ sở dữ liệu; mỗi đại diện bởi một tập tin trên đĩa.
Chi tiết triển khai không quan trọng; chi tiết quan trọng duy nhất là tôi cần phải liên tục thêm vào tệp và phát triển nó từ KB, thành MB, sang GB thành TB trong khi đồng thời ngẫu nhiên bỏ qua tệp để đọc hoạt động để trả lời yêu cầu của khách hàng.
First-Suy nghĩ
Thoạt nhìn tôi biết tôi muốn sử dụng tập tin bộ nhớ ánh xạ vì vậy tôi có thể đẩy gánh nặng quản lý có hiệu quả trong bộ nhớ trạng thái của dữ liệu vào hệ điều hành máy chủ và ngoài ma cua toi. Sau đó, tất cả các mã của tôi cần phải lo lắng về là serializing các hoạt động phụ thêm vào tập tin on-write, và cho phép bất kỳ số lượng độc giả đồng thời tìm kiếm trong tập tin để trả lời các yêu cầu.
Thiết kế
Bởi vì dữ liệu tập tin cá nhân có thể phát triển vượt quá giới hạn 2GB một MappedByteBuffer, tôi hy vọng rằng thiết kế của tôi sẽ phải bao gồm một lớp trừu tượng mà phải mất một ghi bù đắp và chuyển đổi nó thành một bù đắp bên trong phân khúc 2GB cụ thể.
Cho đến nay rất tốt ...
vấn đề
Đây là nơi tôi bắt đầu để có được treo lên và nghĩ rằng sẽ có một thiết kế khác nhau (đề xuất dưới đây) có thể là cách tốt hơn để làm điều này.
Từ đọc qua 20 câu hỏi liên quan đến bộ nhớ "được ánh xạ" ở đây trên SO, có vẻ như các cuộc gọi mmap nhạy cảm với việc chạy bộ nhớ liền kề khi được cấp phát. Vì vậy, ví dụ, trên hệ điều hành máy chủ 32 bit nếu tôi cố gắng chèn một tệp 2GB, do phân mảnh bộ nhớ, cơ hội của tôi mỏng nên ánh xạ sẽ thành công và thay vào đó tôi nên sử dụng một thứ gì đó giống như một chuỗi 128MB ánh xạ để kéo toàn bộ Khi tôi nghĩ về thiết kế đó, thậm chí nói sử dụng kích thước 1024MB mmap, cho một DBMS lưu trữ một vài cơ sở dữ liệu khổng lồ được biểu diễn bằng các tệp 1TB nói, bây giờ tôi có hàng ngàn của vùng bộ nhớ ánh xạ trong bộ nhớ và trong thử nghiệm của riêng tôi trên Windows 7 cố gắng tạo vài trăm mmaps trên một tệp nhiều GB, tôi không chỉ chạy vào ngoại lệ, tôi thực sự có JVM để segfault mỗi khi tôi cố gắng phân bổ quá nhiều và trong một trường hợp nhận được video trong máy tính Windows 7 của tôi để cắt bỏ và khởi tạo lại với một cửa sổ bật lên lỗi hệ điều hành mà tôi chưa bao giờ thấy trước đây.
Bất kể đối số "bạn sẽ không bao giờ xử lý các tệp lớn" hoặc "đây là ví dụ giả tạo", thực tế là tôi có thể mã hóa thứ gì đó giống như vậy với các loại tác dụng phụ đó đặt báo thức nội bộ của tôi cảnh giác cao và được coi là một phương án thay thế (bên dưới). BESIDES vấn đề đó, sự hiểu biết của tôi về các tập tin ánh xạ bộ nhớ là tôi phải tạo lại ánh xạ mỗi lần tệp được phát triển, vì vậy trong trường hợp tệp này chỉ nối thêm trong thiết kế, nó liên tục theo nghĩa đen. phát triển.
Tôi có thể chống lại điều này ở mức độ nào đó bằng cách phát triển tệp theo khối (8MB mỗi lần) và chỉ tạo lại ánh xạ mỗi 8MB, nhưng cần phải liên tục tạo lại các ánh xạ này. không rõ ràng unmap feature supported in Java.
Câu hỏi # 1 trong tổng số 2
Với tất cả các phát hiện của tôi đến thời điểm này, tôi sẽ bỏ tập tin bộ nhớ ánh xạ như một giải pháp tốt cho chủ yếu đọc nặng giải pháp hay read-only giải pháp, nhưng không các giải pháp ghi nặng cho nhu cầu tái tạo bản đồ liên tục. Sau đó tôi nhìn xung quanh xung quanh tôi với các giải pháp như MongoDB bao gồm các tập tin ánh xạ bộ nhớ khắp nơi và tôi cảm thấy mình thiếu một số thành phần cốt lõi ở đây (tôi biết nó allocs trong một cái gì đó giống như 2GB extents tại một thời gian, vì vậy tôi tưởng tượng họ đang làm việc xung quanh chi phí bản đồ lại với logic này VÀ giúp duy trì tuần tự chạy trên đĩa). Tại thời điểm này tôi không biết vấn đề là Java thiếu một hoạt động unmap làm cho điều này trở nên nguy hiểm và không phù hợp với việc sử dụng của tôi hoặc nếu hiểu biết của tôi không đúng và ai đó có thể chỉ cho tôi miền Bắc.
Thiết kế Alternative
Một thiết kế để thay thế cho bộ nhớ ánh xạ một đề xuất ở trên mà tôi sẽ đi với nếu sự hiểu biết của tôi về mmap là đúng là như sau:
Xác định a direct ByteBuffer có kích thước cấu hình hợp lý (2, 4, 8, 16, 32, 64, 128KB) giúp dễ dàng tương thích với bất kỳ nền tảng máy chủ nào (không cần phải lo lắng về bản thân DBMS gây ra tình huống đập) và sử dụng FileChannel gốc, thực hiện specific-offset reads của tệp 1 đệm-dung lượng-chunk tại một thời điểm, hoàn toàn gửi đi bộ nhớ-ánh xạ các tập tin ở tất cả.
Nhược điểm là bây giờ mã của tôi phải lo lắng về những thứ như "tôi đã đọc đủ từ tệp để tải bản ghi đầy đủ chưa?"
Một mặt khác là tôi không tận dụng được logic bộ nhớ ảo của hệ điều hành, cho phép nó tự động lưu dữ liệu "nóng" trong bộ nhớ cho tôi; thay vào đó, tôi chỉ phải hy vọng bộ nhớ cache của tệp được sử dụng bởi hệ điều hành đủ lớn để làm điều gì đó hữu ích cho tôi ở đây.
Câu hỏi # 2 của 2
Tôi đã hy vọng để có được một xác nhận sự hiểu biết của tôi về tất cả điều này. Ví dụ, có thể bộ nhớ cache của tệp là tuyệt vời, trong cả hai trường hợp (bộ nhớ ánh xạ hoặc đọc trực tiếp), hệ điều hành chủ sẽ giữ càng nhiều dữ liệu nóng càng tốt và hiệu suất của tệp lớn không đáng kể.
Hoặc có thể sự hiểu biết của tôi về các yêu cầu nhạy cảm đối với tệp ánh xạ bộ nhớ (bộ nhớ tiếp giáp) không chính xác và tôi có thể bỏ qua tất cả những điều đó.
Nếu bạn đã đạt được một số hiểu biết kể từ khi đặt câu hỏi của bạn, xin vui lòng gửi cho họ như một câu trả lời. Rất nhiều người đọc câu hỏi này và họ có thể sử dụng cái nhìn sâu sắc. Có rất nhiều lỗi "sẽ không sửa" xung quanh việc lấy mẫu, như http://bugs.sun.com/view_bug.do?bug_id=6893654 (mặc dù JVM segfault và trình điều khiển đồ họa bị lỗi thậm chí còn tồi tệ hơn!) Thật thú vị cách đơn giản , tính năng bản địa thanh lịch trở nên phức tạp và xấu xí trong thế giới được quản lý. –
@AleksandrDubinsky bạn chính xác đúng (về thanh lịch trở nên không phù hợp) - phát hiện cuối cùng của tôi là các tệp mmap'ed không thể được tạo nhanh chóng mà không đưa ra sự bất ổn đáng kể vào hệ thống (Tôi không biết liệu tôi có làm rõ trong chuỗi này hay không) Tôi đã quản lý màn hình xanh của máy tính Windows của mình). Chi tiết này làm cho tôi muốn dính vào asyncfilechannel sử dụng cho tập tin I/O và tránh mmap tất cả cùng nhau, mặc dù peter (dưới đây) đã có thành công đáng kể trong Chronicle. –
@AleksandrDubinsky Khi tôi có thể mang cả máy ảo và máy của tôi đến đầu gối bằng cách sử dụng các tệp mmapped rõ ràng "mis-use", tôi đã thực hiện với việc đi xuống đường dẫn đó. Chúng rất tao nhã và có hiệu suất tuyệt vời, nhưng từ đọc nhiều hơn tôi đã làm trên AsyncFileChannel có vẻ như bạn có thể nhận được khá gần với cùng một hiệu suất (cho phép hệ điều hành sử dụng FS và bộ điều khiển đĩa và I/O để tối ưu hóa yêu cầu). Nếu bạn thực sự muốn đi xuống con đường mmap, Peter là chuyên gia ở đây. –