2010-06-07 38 views
7

Tôi có một ứng dụng mà toàn bộ cơ sở dữ liệu được thực hiện trong bộ nhớ bằng cách sử dụng một bản đồ stl cho mỗi bảng trong cơ sở dữ liệu.Cách tối ưu hóa phân trang cho lớn trong cơ sở dữ liệu bộ nhớ

Mỗi mục trong sơ đồ stl là một đối tượng phức tạp có tham chiếu đến các mục khác trong các bản đồ stl khác.

Ứng dụng hoạt động với một lượng lớn dữ liệu, do đó, nó sử dụng hơn 500 MByte RAM. Khách hàng có thể liên hệ với ứng dụng và nhận phiên bản được lọc của toàn bộ cơ sở dữ liệu. Điều này được thực hiện bằng cách chạy qua toàn bộ cơ sở dữ liệu và tìm các mục có liên quan cho khách hàng.

Khi ứng dụng đã chạy trong một giờ hoặc lâu hơn, Windows 2003 SP2 sẽ bắt đầu trang ra các phần của RAM cho ứng dụng (Mặc dù có RAM 16 GB trên máy).

Sau khi ứng dụng đã được phân trang một phần thì đăng nhập của khách hàng mất một thời gian dài (10 phút) vì bây giờ nó tạo ra lỗi trang cho từng tra cứu con trỏ trong bản đồ. Nếu chạy máy khách đăng nhập lần thứ hai ngay sau đó thì nó nhanh (vài giây) vì tất cả bộ nhớ giờ đã trở lại trong RAM.

Tôi có thể thấy rằng có thể yêu cầu Windows khóa bộ nhớ trong RAM, nhưng điều này thường chỉ được đề xuất cho trình điều khiển thiết bị và chỉ dành cho bộ nhớ "nhỏ".

Tôi đoán một giải pháp mans nghèo có thể là lặp qua toàn bộ cơ sở dữ liệu bộ nhớ, và do đó cho Windows biết chúng tôi vẫn quan tâm đến việc giữ datamodel trong RAM.

Tôi đoán một giải pháp người nghèo khác có thể là vô hiệu hóa tệp trang hoàn toàn trên Windows.

Tôi đoán giải pháp tốn kém sẽ là cơ sở dữ liệu SQL, sau đó viết lại toàn bộ ứng dụng để sử dụng lớp cơ sở dữ liệu. Sau đó, hy vọng hệ thống cơ sở dữ liệu sẽ thực hiện có nghĩa là để truy cập nhanh.

Có các giải pháp thanh lịch nào khác không?

+0

Ứng dụng chạy dưới dạng dịch vụ Windows nhưng vẫn có cửa sổ bảng điều khiển (Sử dụng AllocConsole). Tự hỏi nếu Windows phản ứng với cửa sổ giao diện điều khiển này được giảm thiểu, và sau đó quyết định cắt bộ làm việc. –

+0

Cũng nhận thấy rằng nhiều bộ đệm làm việc được phân bổ bằng cách sử dụng mới hoặc malloc nhưng không sử dụng kích thước chunk đồng nhất (Đây là một ứng dụng cũ). Bằng cách điều chỉnh kích thước phân bổ có thể chia cho 1024, sau đó nó giảm một nửa các byte ảo cho ứng dụng. –

+0

Bây giờ đã sử dụng ProcDump để đăng ký dấu vết ngăn xếp khi nó đã rất bận rộn. Nó tiết lộ rằng nó đã dành rất nhiều thời gian cho nhiều hoạt động mới/malloc lớn. Bây giờ đã thực hiện tái sử dụng bộ đệm tốt hơn, nhưng tôi vẫn còn bối rối tại sao đăng nhập máy khách đầu tiên cần thời gian, và lần thứ hai nó nhanh. –

Trả lời

5

Điều này âm thanh như rò rỉ bộ nhớ hoặc một vấn đề phân mảnh nghiêm trọng. Dường như với tôi rằng bước đầu tiên sẽ là tìm ra nguyên nhân gây ra 500 Mb dữ liệu để sử dụng 16 GB RAM và vẫn muốn nhiều hơn nữa.

Chỉnh sửa: Windows có tông đơ đặt làm việc tích cực cố gắng loại bỏ dữ liệu không sử dụng. Ý tưởng cơ bản là nó đi qua và đánh dấu các trang là có sẵn, nhưng để lại dữ liệu trong chúng (và trình quản lý bộ nhớ ảo biết dữ liệu nào nằm trong chúng). Tuy nhiên, nếu bạn cố gắng truy cập vào bộ nhớ đó trước khi nó được cấp phát cho các mục đích khác, nó sẽ được đánh dấu là đang được sử dụng một lần nữa, điều này thường sẽ ngăn không cho nó bị phân trang.

Nếu bạn thực sự nghĩ đây là nguồn gốc của sự cố, bạn có thể gián tiếp kiểm soát tông đơ đặt làm việc bằng cách gọi SetProcessWorkingSetSize. Ít nhất là trong kinh nghiệm của tôi, điều này chỉ hiếm khi được sử dụng nhiều, nhưng bạn có thể ở trong một trong những tình huống bất thường khi nó thực sự hữu ích.

+0

Tôi đồng ý - nghe có vẻ như bị rò rỉ với tôi. Bạn đã thử sử dụng Valgrind chưa? –

+0

Tôi không thể tìm thấy nơi anh ấy nói anh ấy chỉ có 500 MB dữ liệu sử dụng RAM 16 GB. Mặt khác, tôi cũng không hiểu tại sao OP mentoin 500 MB RAM một cách rõ ràng. Dù sao, tôi đồng ý với ý tưởng rò rỉ bộ nhớ. – PeterK

+0

@PeterK: tốt, anh ấy nói "hơn 500MByte", mà tôi cho là có nghĩa là chỉ hơi hơn 500 MByte. Trong mọi trường hợp, có vẻ như nó đủ nhanh để bắt đầu, nhưng cuối cùng sử dụng đủ bộ nhớ để bắt đầu đập ... –

0

---- Sửa

Với snakefoot giải thích, vấn đề được trao đổi ra bộ nhớ mà không được sử dụng cho một thời gian dài hơn và do này không có dữ liệu trong bộ nhớ khi cần thiết.Điều này tương tự như thế này:

Can I tell Windows not to swap out a particular processes’ memory?

và chức năng VirtualLock nên làm công việc của mình:

http://msdn.microsoft.com/en-us/library/aa366895(VS.85).aspx

---- câu trả lời trước

Trước hết bạn cần phải phân biệt giữa bộ nhớ bị rò rỉ và bộ nhớ cần vấn đề.

Nếu bạn bị rò rỉ bộ nhớ thì sẽ là nỗ lực lớn hơn để chuyển đổi toàn bộ ứng dụng sang SQL hơn là gỡ lỗi ứng dụng.

SQL không thể nhanh hơn khi được thiết kế tốt, cơ sở dữ liệu trong bộ nhớ cụ thể trong miền và nếu bạn có lỗi, rất có thể bạn sẽ có các phiên bản khác nhau trong phiên bản SQL.

Nếu đây là vấn đề về bộ nhớ, thì bạn sẽ cần phải chuyển sang SQL và điều này nghe có vẻ như là một khoảnh khắc tốt.

+0

Tôi không nghĩ rằng có một vấn đề rò rỉ bộ nhớ, vì ứng dụng không sử dụng nhiều RAM hơn theo thời gian. Nó chỉ không liên lạc tất cả bộ nhớ được cấp phát liên tục, do đó, trình quản lý bộ nhớ Windows 2003 cho rằng bạn có thể xóa bộ nhớ. Bộ quản lý bộ nhớ Windows 2003 trang ra bộ nhớ khi có nhiều bộ nhớ trong máy. –

+0

Tôi đồng ý snakefoot, trong bộ nhớ lý thuyết chỉ nên được nhân đôi * cho pagefile cho đến khi nó thực sự cần phải được ép ra. Nhưng dường như nó có thể được phân bổ lại nhiều trước khi nó cần. – strainer

+0

Không chắc chắn tôi muốn hành vi của Virtual Lock, vì nó ngăn Windows không bao giờ phân trang ứng dụng ngay cả khi bộ nhớ là cần thiết cho các tình huống quan trọng. Tôi thà prefere một giải pháp mà người ta có thể nói với Windows không được tích cực như vậy về ứng dụng của tôi. –

2

Như @Jerry Coffin cho biết, thực sự có vẻ như vấn đề thực tế của bạn là rò rỉ bộ nhớ. Sửa lỗi đó.

Nhưng đối với hồ sơ, không có "giải pháp mans nghèo" nào của bạn sẽ hoạt động. Ở tất cả.

Windows sẽ xóa một số dữ liệu của bạn vì không có chỗ cho nó trong RAM. Lặp qua toàn bộ cơ sở dữ liệu bộ nhớ sẽ tải trong mỗi byte của mô hình dữ liệu, có ... điều này sẽ khiến các phần khác của nó được phân trang. Cuối cùng, bạn sẽ tạo ra rất nhiều lỗi trang, và sự khác biệt duy nhất ở cuối sẽ là các phần của cấu trúc dữ liệu được phân trang.

Tắt tệp trang? Có, nếu bạn nghĩ rằng một vụ tai nạn cứng là tốt hơn so với hiệu suất thấp. Windows không có dữ liệu trang vì nó thú vị. Nó làm điều đó để xử lý các tình huống mà nếu không nó sẽ hết bộ nhớ. Nếu bạn vô hiệu hóa pagefile, ứng dụng sẽ chỉ sụp đổ khi nó sẽ trang ra dữ liệu.

Nếu tập dữ liệu của bạn thực sự lớn đến mức không vừa trong bộ nhớ, thì tôi không thấy lý do tại sao cơ sở dữ liệu SQL đặc biệt "đắt". Không giống như giải pháp hiện tại của bạn, cơ sở dữ liệu được tối ưu hóa cho mục đích này. Chúng có nghĩa là xử lý các tập dữ liệu quá lớn để phù hợp với bộ nhớ, và để làm điều này một cách hiệu quả.

Có vẻ như bạn bị rò rỉ bộ nhớ. Sửa chữa đó sẽ là giải pháp thanh lịch, hiệu quả và chính xác.

Nếu bạn không thể làm điều đó, sau đó, hoặc

  • ném thêm RAM vào vấn đề (ứng dụng kết thúc sử dụng 16GB? Ném 32 hoặc 64GB vào nó sau đó), hoặc
  • chuyển sang một định dạng được tối ưu hóa để truy cập đĩa hiệu quả (Cơ sở dữ liệu SQL có thể)
+0

Một lần nữa ứng dụng chỉ sử dụng RAM 500 MByte khi sử dụng Trình quản lý tác vụ. Vấn đề là cách thuật toán phân trang Windows đang hoán đổi ứng dụng khi có đủ RAM. –

+0

@snakefoot: không. Windows không làm điều đó. Và Task Manager không phải là cách đáng tin cậy để xác định mức sử dụng bộ nhớ. – jalf

+1

Bạn đã bao giờ có một máy tính Windows XP, đã bị bỏ lại một mình trong vài giờ, và sau đó bạn bắt đầu sử dụng nó. Vài phút đầu tiên mọi thứ khá chậm chạp bởi vì người quản lý bộ nhớ đã phân trang hầu hết bộ nhớ. Tôi muốn khuyến khích Windows giữ ứng dụng của tôi trong bộ nhớ. –

0

Chúng tôi có một vấn đề tương tự và giải pháp chúng tôi chọn là phân bổ mọi thứ trong khối bộ nhớ dùng chung. AFAIK, Windows không trang này ra. Tuy nhiên, bằng cách sử dụng stl-map ở đây không phải là cho trái tim mờ nhạt và vượt quá những gì chúng tôi yêu cầu.

Chúng tôi đang sử dụng Boost Shared Memory để thực hiện việc này cho chúng tôi và nó hoạt động tốt.Thực hiện theo các ví dụ chặt chẽ và bạn sẽ được thiết lập và chạy một cách nhanh chóng. Boost cũng có Boost.MultiIndex sẽ thực hiện rất nhiều thứ bạn muốn.

Để có giải pháp sql miễn phí, bạn đã xem Sqlite chưa? Họ có một tùy chọn để chạy như một cơ sở dữ liệu trong bộ nhớ.

Chúc may mắn, có vẻ như là một ứng dụng thú vị.

+0

Trên thực tế, lợi ích của việc không phải ánh xạ tới một lớp cơ sở dữ liệu thực sự mang đến nhiều tự do. Chúng tôi chỉ tuần tự hóa thành XML, khi cần sự kiên trì. Sử dụng XML cũng giúp dễ dàng tích hợp với các ứng dụng khác vì chúng ta có thể sử dụng bảng định kiểu trong quá trình nhập/xuất. –

+0

@snakefoot - Tôi hoàn toàn có thể đồng ý với điểm trên db. Tôi đã đề xuất SQLite chỉ vì nó đã được dễ dàng để làm cho nó trong bộ nhớ db. –

0

Tôi có một ứng dụng mà toàn bộ cơ sở dữ liệu được thực hiện trong bộ nhớ sử dụng một STL-bản đồ cho mỗi bảng trong cơ sở dữ liệu .

Đó là sự bắt đầu của kết thúc: STL's std :: map cực kỳ thiếu bộ nhớ. Tương tự áp dụng cho std :: list. Mỗi phần tử sẽ được phân bổ riêng biệt gây ra lãng phí bộ nhớ khá nghiêm trọng. Tôi thường sử dụng std :: vector + sort() + find() thay vì std :: map trong các ứng dụng có thể (nhiều tìm kiếm hơn sửa đổi) và tôi biết việc sử dụng bộ nhớ trước có thể trở thành vấn đề.

Khi ứng dụng đã được chạy cho một giờ hoặc lâu hơn, sau đó Windows 2003 SP2 bắt đầu trang ra các bộ phận của RAM cho các ứng dụng (Cho dù có 16 Gbyte RAM trên máy tính này).

Khó nói mà không biết cách viết đơn của bạn. Windows có tính năng để tải xuống từ bộ nhớ RAM bất kỳ bộ nhớ của các ứng dụng nhàn rỗi có thể được dỡ xuống. Nhưng điều đó thường ảnh hưởng đến các tập tin được ánh xạ bộ nhớ và giống nhau.

Nếu không, tôi thực sự khuyên bạn nên đọc lên Windows memory management documentation. Nó không phải là rất dễ hiểu, nhưng Windows có tất cả các loại và các loại bộ nhớ có sẵn cho các ứng dụng. Tôi không bao giờ có may mắn với nó, nhưng có lẽ trong ứng dụng của bạn bằng cách sử dụng tùy chỉnh std :: allocator sẽ làm việc.

+0

Vấn đề sẽ là viết một bộ cấp phát STL cho các loại bộ nhớ khác. Cùng với thực tế là bộ nhớ không phân trang là một nguồn lực hạn chế. Tôi chỉ muốn khuyến khích Windows giữ ứng dụng của tôi trong bộ nhớ thay vì phân trang nó ra. –

+0

"Cùng với thực tế là bộ nhớ không phân trang là một nguồn lực hạn chế." Vâng, nếu bạn biết chính xác những gì các ứng dụng sẽ chạy trên máy chủ và những yêu cầu bộ nhớ của họ, sau đó nó là hoàn toàn OK cũng sử dụng bộ nhớ không paged. Bằng cách đó, một hệ điều hành lấy trộm từ RAM vật lý thường được coi là xấu. Nhưng nếu nhiệm vụ yêu cầu dung lượng lưu trữ trong RAM để đảm bảo truy cập nhanh, thì có rất ít sự lựa chọn. – Dummy00001

0

Tôi có thể tin rằng đó là lỗi của hành vi pagefile không hoàn thiện - tôi đã chạy máy tính xách tay của tôi chủ yếu là với pagefile tắt kể từ nt4.0. Theo kinh nghiệm của tôi, ít nhất là lên đến XP Pro, Windows đột nhập hoán đổi các trang chỉ để cung cấp lợi ích đáng ngờ khi có phần mở rộng thực sự chậm đến không gian làm việc tối đa.

Yêu cầu trao đổi lợi ích nào với đĩa cứng là đạt được với 16 Gigabity RAM thực có sẵn? Nếu công việc của bạn lớn đến mức cần nhiều bộ nhớ ảo hơn +10 Gigs, thì một khi hoán đổi là các quy trình bắt buộc thực tế sẽ mất nhiều thời gian hơn, lâu hơn hàng nghìn lần để hoàn thành. Trên Windows, bộ nhớ cache của hệ thống tập tin không thể thay đổi dường như đối nghịch với các mối quan hệ.

Bây giờ khi tôi (rất) có dịp hết bộ công việc trên máy tính xách tay XP của tôi, không có kẹt xe, ứng dụng tội lỗi chỉ gặp sự cố. Một tiện ích để tạm dừng các quá trình xử lý bộ nhớ trước thời gian đó và làm cho một cảnh báo sẽ tốt đẹp, nhưng không có điều như vậy chỉ là một sự vi phạm, một vụ tai nạn, và đôi khi explorer.exe đi xuống quá.

Pagefiles - những người cần em '

+0

Vâng pagefile và alogoritm phân trang được phát minh tại thời điểm mà các máy tính chỉ có RAM 16 MByte, rất nhiều ứng dụng phụ thuộc vào hành vi này và có thể sẽ phá vỡ nếu chúng thay đổi nó. Tôi tin rằng Microsoft đã thay đổi mọi thứ với Windows 2008, vì vậy nó thực sự cố gắng tối đa hóa việc sử dụng bộ nhớ. Nhưng ngay bây giờ chúng tôi đang sử dụng Windows 2003 SP2. –

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