Hãy cẩn thận: có thể không chính xác dưới đây. Tôi đã học được rất nhiều thứ này khi tôi đi cùng, vì vậy hãy mang nó với một nhúm muối. Việc này khá dài, nhưng bạn chỉ cần đọc các tham số mà chúng tôi đang chơi, sau đó bỏ qua phần Kết luận ở cuối.
Có một số lớp mà bạn có thể lo lắng về hiệu suất ghi SQLite:
Chúng tôi nhìn vào những cái được tô đậm. Các thông số cụ thể là
- Đĩa ghi bộ đệm. Các đĩa hiện đại có bộ đệm RAM được sử dụng để tối ưu hóa ghi đĩa đối với đĩa quay. Khi bật tính năng này, dữ liệu có thể được ghi trong các khối không theo thứ tự, vì vậy nếu xảy ra sự cố, bạn có thể kết thúc bằng một tệp được ghi một phần. Kiểm tra cài đặt với hdparm -W / dev / ... và cài đặt nó với hdparm -W1 / dev / ... (để bật và -W0 để tắt).
- rào cản = (0 | 1). Rất nhiều bình luận trực tuyến nói rằng "nếu bạn chạy với rào cản = 0, thì không kích hoạt bộ đệm ghi đĩa". Bạn có thể tìm thấy một cuộc thảo luận về các rào cản tại http://lwn.net/Articles/283161/
- dữ liệu = (tạp chí | đặt hàng | viết lại). Hãy xem http://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.html để biết mô tả về các tùy chọn này.
- cam kết = N. Yêu cầu ext3 đồng bộ hóa tất cả dữ liệu và siêu dữ liệu mỗi N giây (mặc định 5).
- SQLite pragma đồng bộ = ON | TẮT. Khi BẬT, SQLite sẽ đảm bảo rằng một giao dịch được "ghi vào đĩa" trước khi tiếp tục. Tắt điều này về cơ bản làm cho các cài đặt khác phần lớn không liên quan.
- SQLite pragma cache_size. Kiểm soát dung lượng bộ nhớ SQLite sẽ sử dụng cho bộ nhớ cache trong bộ nhớ. Tôi đã thử hai kích thước: một trong đó toàn bộ DB sẽ phù hợp với bộ đệm và một trong đó bộ đệm là một nửa kích thước DB tối đa.
Đọc thêm về các tùy chọn ext3 trong tài liệu ext3 .
Tôi đã chạy thử nghiệm hiệu suất trên một số kết hợp của các tham số này. ID là một số kịch bản, được đề cập dưới đây.
Tôi đã bắt đầu bằng cách chạy với cấu hình mặc định trên máy của mình theo kịch bản 1. Kịch bản 2 là thứ tôi cho là "an toàn nhất", và sau đó thử các kết hợp khác nhau, khi thích hợp / được nhắc. Điều này có lẽ dễ hiểu nhất với bản đồ mà tôi đã sử dụng:
Tôi đã viết một tập lệnh thử nghiệm chạy rất nhiều giao dịch, với các phần chèn, cập nhật và xóa, tất cả trên các bảng chỉ có INTEGER, chỉ có văn bản (với cột id) hoặc hỗn hợp. Tôi đã chạy nó một số lần trên mỗi cấu hình ở trên:
Hai kịch bản dưới cùng là # 6 và # 17, có "pragma syncous = off", không ngạc nhiên khi chúng là nhanh nhất. Cụm ba tiếp theo là # 7, # 11 và # 19. Ba cái này được tô màu xanh lam trên "bản đồ cấu hình" ở trên. Về cơ bản, cấu hình là bộ đệm ghi trên đĩa, rào cản = 0 và dữ liệu được đặt thành một cái gì đó không phải là 'tạp chí'. Thay đổi cam kết giữa 5 giây (# 7) và 60 giây (# 11) dường như tạo ra sự khác biệt nhỏ. Trong các thử nghiệm này dường như không có nhiều sự khác biệt giữa data = order và data = writBack, điều đó làm tôi ngạc nhiên.
Các thử nghiệm cập nhật hỗn hợp là đỉnh trung bình. Có một loạt các kịch bản chậm hơn rõ ràng trong bài kiểm tra này. Đây là tất cả những người có dữ liệu = tạp chí . Mặt khác, không có nhiều giữa các kịch bản khác.
Tôi đã có một bài kiểm tra thời gian khác, đó là một sự pha trộn không đồng nhất của các phần chèn, cập nhật và xóa trên các kết hợp loại khác nhau. Việc này mất nhiều thời gian hơn, đó là lý do tại sao tôi không đưa nó vào cốt truyện trên:
Ở đây bạn có thể thấy rằng cấu hình writBack (# 19) chậm hơn một chút so với cấu hình được đặt hàng (# 7 và # 11). Tôi dự kiến thời gian viết sẽ nhanh hơn một chút, nhưng có lẽ nó phụ thuộc vào kiểu viết của bạn hoặc có thể tôi chưa đọc đủ trên ext3 :-)
Các kịch bản khác nhau đã phần nào đại diện cho các hoạt động được thực hiện bởi ứng dụng của chúng tôi. Sau khi chọn một danh sách ngắn các kịch bản, chúng tôi đã chạy thử nghiệm thời gian với một số bộ thử nghiệm tự động của chúng tôi. Họ đã phù hợp với kết quả ở trên.
Phần kết luận
- Các cam kết tham số dường như làm cho sự khác biệt nhỏ, vì vậy chúng tôi rời khỏi rằng tại 5s.
- Chúng tôi sẽ sử dụng bộ đệm ghi trên đĩa, rào cản = 0 và dữ liệu = đã ra lệnh . Tôi đã đọc một số điều trên mạng nghĩ rằng đây là một thiết lập tồi và những thứ khác dường như nghĩ rằng đây sẽ là mặc định trong rất nhiều tình huống. Tôi đoán quan trọng nhất là bạn đưa ra quyết định sáng suốt, biết bạn đang đánh đổi điều gì.
- Chúng tôi sẽ không sử dụng pragma đồng bộ trong SQLite.
- Đặt pragma SQLite cache_size để DB phù hợp với hiệu năng của bộ nhớ được cải thiện trên một số hoạt động, như chúng tôi mong đợi.
- Cấu hình trên có nghĩa là chúng ta sẽ mạo hiểm hơn một chút. Chúng tôi sẽ sử dụng API sao lưu SQLite để giảm thiểu nguy cơ lỗi ổ đĩa khi ghi một phần: chụp ảnh nhanh mỗi N phút và giữ M cuối cùng. Tôi đã kiểm tra API này trong khi chạy thử nghiệm hiệu suất và nó giúp chúng tôi tự tin đi theo hướng này.
- Nếu chúng tôi vẫn muốn nhiều hơn, chúng tôi có thể xem xét việc nghiền ngẫm với kernel, nhưng chúng tôi đã cải thiện mọi thứ đủ mà không cần đến đó.
Cảm ơn @Huygens cho các mẹo và gợi ý khác nhau.