2013-02-12 46 views
9

Tôi có một ứng dụng muốn tiếp tục mở nhiều tệp: định kỳ nó nhận được yêu cầu của khách hàng nói "thêm một số dữ liệu vào tệp X" và sẽ là lý tưởng để tệp đó được mở và phần tiêu đề của tệp đã là phân tích cú pháp, để viết này nhanh. Tuy nhiên, việc mở nhiều tệp này là không tốt cho hệ điều hành và có thể trở thành không thể nếu nhu cầu lưu trữ dữ liệu của chúng tôi tăng lên.Làm cách nào để xử lý tệp bộ nhớ cache?

Vì vậy, tôi muốn có chức năng "cấp cho tôi tệp này, mở nếu nó không được lưu vào bộ nhớ cache" và một số quy trình để tự động đóng các tệp chưa được viết tới, ví dụ: năm phút. Đối với trường hợp cụ thể của bộ nhớ đệm xử lý được viết bằng các đoạn ngắn, điều này có thể là đủ, nhưng điều này có vẻ như là một vấn đề chung đủ để có chức năng như "cung cấp cho tôi đối tượng có tên X, từ bộ nhớ cache nếu có thể "và" Bây giờ tôi đã xong với đối tượng X, do đó, hãy làm cho nó đủ điều kiện để trục xuất năm phút kể từ bây giờ ".

core.cache vẻ như nó có thể phù hợp cho mục đích này, nhưng documentation là khá thiếu và source không cung cấp manh mối cụ thể về làm thế nào để sử dụng nó. TTLCache của nó trông đầy hứa hẹn, nhưng cũng như là không rõ cách sử dụng nó dựa vào việc thu gom rác thải để loại bỏ các vật phẩm, vì vậy tôi không thể đóng tài nguyên một cách rõ ràng khi tôi sẵn sàng hết hạn.

Tôi có thể tự mình cuộn, nhưng có một số điểm phức tạp và tôi chắc chắn mình sẽ nhận được một số điều sai lầm, vì vậy tôi hy vọng một người nào đó có thể chỉ cho tôi thực hiện chức năng này . Mã của tôi là trong clojure, nhưng tất nhiên bằng cách sử dụng một thư viện java sẽ là hoàn toàn tốt nếu đó là nơi thực hiện tốt nhất có thể được tìm thấy.

Trả lời

5

Khám phá Guava's cache implementation.

  • Bạn có thể cung cấp một Callable (hoặc một CacheLoader) với phương pháp get cho "nếu xử lý được lưu trữ, gửi lại, nếu không mở, bộ nhớ cache và gửi lại" ngữ nghĩa
  • Bạn có thể cấu hình đuổi theo thời gian như vậy như expireAfterAccess
  • Bạn có thể đăng ký một RemovalListener để đóng xử lý trên loại bỏ

Sửa đổi các ví dụ mã từ ổi liên kết Trang nhẹ, sử dụng CacheLoader:

LoadingCache<Key, Handle> graphs = CacheBuilder.newBuilder() 
    .maximumSize(100) // sensible value for open handles? 
    .expireAfterAccess(5, TimeUnit.MINUTES) 
    .removalListener(removalListener) 
    .build(
     new CacheLoader<Key, Handle>() { 
     public Handle load(Key key) throws AnyException { 
      return openHandle(key); 
     } 
     }); 

RemovalListener<Key, Handle> removalListener = 
    new RemovalListener<Key, Handle>() { 
    public void onRemoval(RemovalNotification<Key, Handle> removal) { 
     Handle h = removal.getValue(); 
     h.close(); // tear down properly 
    } 
    }; 

* DISCLAIMER * tôi đã không sử dụng bộ nhớ cache bản thân mình theo cách này, đảm bảo bạn kiểm tra điều này một cách hợp lý.

+0

Điều này có vẻ khá phù hợp, cảm ơn! Điều duy nhất tôi lo lắng là có thể nhận được một mục từ bộ nhớ cache và treo nó lâu hơn thời gian hết hạn, chủ động sử dụng nó tất cả cùng. Nếu mã hết hạn làm rơi mục, điều đó trở nên nguy hiểm. Bạn có biết một cách để "kiểm tra một đối tượng ra" của bộ nhớ cache sao cho nó không bị rách cho đến khi nó được kiểm tra lại không? – amalloy

+0

Hm, tôi nghĩ nó phụ thuộc. Nó có thể xảy ra mà bạn liên tục ghi vào một tập tin cho> = 5 phút? Cache có được truy cập từ một yêu cầu tại một thời điểm không? Hãy chắc chắn rằng bạn kiểm tra tài liệu ở đây: Eviction không xảy ra tự động khi hết hạn, nhưng trong khi đọc/ghi từ/vào Cache. Có lẽ đó là tốt (nếu bạn có một yêu cầu có thể viết trong một thời gian dài, sau đó nó sẽ không bị rách nát), có thể xấu bởi vì có nhiều hơn một yêu cầu tại thời điểm hoặc bạn muốn dọn dẹp xử lý trước đó/trong nền ... –

+0

Xem tại đây: http://code.google.com/p/guava-libraries/wiki/CachesExplained#When_Does_Cleanup_Happen? –

0

Hệ điều hành có một số giới hạn: Is there a limit on number of open files in Windows

SortedMap< Date, File > cache = new TreeMap<>(); 
cache.put(new Date(), file); 
Timer timer = new Timer(true); 
timer.scheduleAtFixedRate(task, 60*1000L, 60*1000L); 

Để tẩy cache: loại bỏ đầu tiên nếu nó tuổi> 5 phút, lặp lại cho đến khi tuổi đầu tiên> 5 phút.

Các vấn đề liên quan