2012-06-09 52 views
7

Tôi đang phát triển tiện ích dòng lệnh Python có khả năng liên quan đến các truy vấn khá lớn đối với một tập hợp các tệp. Đó là danh sách truy vấn hợp lý (nghĩ các cột DB được lập chỉ mục) Để cải thiện hiệu suất trong quá trình, tôi có thể tạo danh sách được sắp xếp/cấu trúc, bản đồ và cây một lần và nhấn nhiều lần, thay vì nhấn vào hệ thống tệp mỗi lần.Tạo bộ nhớ cache trong bộ nhớ còn tồn tại giữa các lần thực hiện

Tuy nhiên, các bộ nhớ cache này bị mất khi quá trình kết thúc và cần được xây dựng lại mỗi khi tập lệnh chạy, làm tăng đáng kể thời gian chạy chương trình của tôi. Tôi muốn xác định cách tốt nhất để chia sẻ dữ liệu này giữa nhiều lần thực hiện lệnh của tôi, có thể là đồng thời, cái khác, hoặc với sự chậm trễ đáng kể giữa các lần thực thi.

Yêu cầu:

  • Phải nhanh chóng - bất kỳ loại chế biến cho mỗi thực hiện nên được giảm thiểu, điều này bao gồm đĩa IO và xây dựng đối tượng.
  • Phải là hệ điều hành bất khả tri (hoặc ít nhất có thể kết nối với các hành vi cơ bản tương tự trên Unix/Windows, nhiều khả năng).
  • Phải cho phép một cách hợp lý phức tạp truy vấn/lọc - Tôi không nghĩ rằng một bản đồ chính/giá trị sẽ đủ tốt
  • Liệu không cần phải được up-to-date - (viết tắt) dữ liệu cũ là hoàn toàn tốt đẹp, đây chỉ là một bộ nhớ cache, dữ liệu thực tế được ghi vào đĩa riêng biệt.
  • Không thể sử dụng quy trình daemon nặng, như MySQL hoặc MemCached - Tôi muốn giảm thiểu chi phí lắp đặt và yêu cầu mỗi người dùng cài đặt các dịch vụ này quá nhiều.

Preferences:

  • tôi muốn tránh bất kỳ quá trình daemon loại dài chạy ở tất cả, nếu có thể.
  • Trong khi tôi muốn có thể cập nhật bộ nhớ cache nhanh chóng, việc xây dựng lại toàn bộ bộ nhớ cache khi cập nhật không phải là kết thúc của thế giới, việc đọc nhanh quan trọng hơn viết nhanh.

Trong thế giới tưởng tượng lý tưởng của mình, tôi có thể trực tiếp giữ các đối tượng Python xung quanh giữa các lần thực hiện, giống như các chủ đề Java (như yêu cầu Tomcat) chia sẻ các đối tượng lưu trữ dữ liệu singleton, nhưng tôi nhận ra rằng có thể không thực hiện được . Gần hơn tôi có thể nhận được rằng mặc dù, thì tốt hơn.

Các ứng cử viên:

  • SQLite trong bộ nhớ

    SQLite trên riêng của nó dường như không đủ nhanh đối với trường hợp sử dụng của tôi, kể từ khi nó được hỗ trợ bởi đĩa và do đó sẽ phải đọc từ tập tin trên mỗi lần thực hiện. Có lẽ đây không phải là xấu như nó có vẻ, nhưng có vẻ như cần thiết để lưu trữ cơ sở dữ liệu liên tục trong bộ nhớ. SQLite cho phép DBs là use memory as storage nhưng các DB này bị hủy khi thoát chương trình và không thể chia sẻ giữa các phiên bản.

  • cơ sở dữ liệu tập tin phẳng nạp vào bộ nhớ với mmap

    Trên cuối đối diện của quang phổ, tôi có thể viết các cache vào đĩa, sau đó tải chúng vào bộ nhớ với mmap, có thể chia sẻ không gian bộ nhớ giống nhau giữa hành riêng . Nó không rõ ràng với tôi những gì xảy ra với mmap nếu tất cả các quy trình thoát ra tuy nhiên. Sẽ ổn nếu như mmap cuối cùng bị xóa khỏi bộ nhớ, nhưng tôi muốn nó dính xung quanh một chút (30 giây? Một vài phút?) Để người dùng có thể chạy các lệnh này đến lệnh khác và bộ nhớ đệm có thể được sử dụng lại. This example dường như ngụ ý rằng có cần phải có một xử lý mở mmap, nhưng tôi đã không tìm thấy bất kỳ mô tả chính xác khi bộ nhớ ánh xạ các tập tin được giảm xuống từ bộ nhớ và cần phải được nạp lại từ đĩa.

    Tôi nghĩ rằng tôi có thể thực hiện điều này, nếu các đối tượng mmap dính xung quanh sau khi thoát, nhưng nó cảm thấy mức độ rất thấp, và tôi tưởng tượng ai đó đã có một giải pháp thanh lịch hơn được triển khai. Tôi ghét phải bắt đầu xây dựng điều này chỉ để nhận ra tôi đã xây dựng lại SQLite. Mặt khác, nó cảm thấy như nó sẽ rất nhanh, và tôi có thể làm cho tối ưu hóa cho trường hợp sử dụng cụ thể của tôi.

  • Share Python đối tượng giữa các quá trình sử dụng chế biến

    gói

    Các Processing chỉ "Objects can be shared between processes using ... shared memory". Nhìn qua phần còn lại của tài liệu, tôi không thấy bất kỳ đề cập nào khác về hành vi này, nhưng điều đó nghe có vẻ là rất đầy hứa hẹn. Bất cứ ai có thể hướng dẫn tôi để biết thêm thông tin?

  • Lưu trữ dữ liệu trên một đĩa RAM

    mối quan tâm của tôi ở đây là khả năng hệ điều hành cụ thể, nhưng tôi có thể create a RAM disk và sau đó chỉ cần đọc/ghi vào nó như tôi hài lòng (SQLite?). Gói fs.memoryfs có vẻ như là một giải pháp thay thế đầy hứa hẹn để làm việc với nhiều hệ điều hành, nhưng các nhận xét hàm ý một số giới hạn công bằng.

là cách hiệu quả để lưu trữ đối tượng Python, vì vậy nó có thể có lợi thế về tốc độ so với bất kỳ loại lưu trữ dữ liệu thủ công nào. Tôi có thể móc dưa vào bất kỳ tùy chọn nào ở trên không? Điều đó có tốt hơn các tệp phẳng hoặc SQLite không?

Tôi biết có rất nhiều câu hỏi liên quan đến điều này, nhưng tôi đã làm một chút công bằng đào và không thể tìm thấy bất cứ điều gì trực tiếp giải quyết câu hỏi của tôi liên quan đến nhiều thực thi dòng lệnh.

Tôi hoàn toàn thừa nhận, tôi có thể đang suy nghĩ quá mức về điều này. Tôi chỉ cố gắng để có được một cảm giác cho các lựa chọn của tôi, và nếu họ đang có giá trị hay không.

Cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn!

+4

Tôi sẽ không đi đến kết luận như thế này quá nhanh: "SQLite của chính nó không đủ nhanh cho trường hợp sử dụng của tôi, vì nó được hỗ trợ bởi đĩa và do đó sẽ phải đọc từ tệp trên mỗi lần thực hiện." Bạn chỉ biết nếu nó sẽ đủ nhanh nếu bạn thử nó. Hơn nữa, hệ điều hành sẽ làm bộ nhớ đệm anyway. –

+0

Redis hoặc Memcached cũng có thể là giải pháp khả thi. –

+0

Tại sao * không * sử dụng quy trình chạy dài?Usecase này là chính xác những gì Redis và Memcached giải quyết, với lợi thế nhất mà bạn có thể giữ bộ nhớ cache của bạn trên khởi động lại chương trình của riêng bạn. –

Trả lời

5

Tôi chỉ cần thực hiện the simplest thing that might possibly work. ... mà trong trường hợp của bạn có thể sẽ chỉ được đổ vào một tập tin dưa. Nếu bạn tìm thấy nó không đủ nhanh, hãy thử một cái gì đó liên quan nhiều hơn (như memcached hoặc SQLite). Donald Knuth nói "Tối ưu hóa sớm là gốc rễ của mọi điều ác"!

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