- पिछले 1 साल में SQLite का उपयोग करके Rails application को high-performance और stable तरीके से चलाने की गहरी समझ बनाने की कोशिश की गई है
- इस प्रक्रिया में कई सबक मिले, और उन्हें साझा करने का उद्देश्य है
- समस्या के कारण और उसके समाधान समझाए जाएंगे
SQLite और Rails की समस्याएँ
- डिफ़ॉल्ट रूप से SQLite का उपयोग करने वाले Rails application तुरंत इस्तेमाल के लिए तैयार नहीं होते
- थोड़े tuning और fine-tuning के जरिए high-performance और stable application बनाए जा सकते हैं
- Rails 8 में लक्ष्य है कि सिर्फ़ default settings के साथ भी production-ready स्थिति मिल जाए
डेमो application "Lorem News"
- "Lorem News" नाम की एक डेमो application के जरिए समस्याओं और समाधानों को समझाया जाएगा
- यह application Hacker News का एक clone है, जिसमें users post और comment लिख सकते हैं
प्रदर्शन परीक्षण
oha load test CLI और application के अंदर benchmarking path का उपयोग करके प्रदर्शन का परीक्षण किया गया
- single request और concurrent request के जरिए प्रदर्शन मापा गया
मुख्य समस्या: SQLITE_BUSY exception
- SQLite एक समय में सिर्फ़ एक write operation की अनुमति देने के लिए write lock का उपयोग करता है
- जब कई connections एक साथ write lock लेने की कोशिश करते हैं, तो
SQLITE_BUSY exception होता है
- इस समस्या को हल करने के लिए immediate transaction का उपयोग करना चाहिए
Immediate transaction
- डिफ़ॉल्ट रूप से SQLite deferred transaction mode का उपयोग करता है
- immediate transaction का उपयोग करने पर write lock तुरंत लेने की कोशिश होती है और असफल होने पर retry किया जा सकता है
sqlite3-ruby gem का उपयोग करके default transaction mode को immediate mode पर सेट किया जा सकता है
Timeout setting
database.yml फ़ाइल में timeout setting के जरिए SQLITE_BUSY exception को कम किया जा सकता है
- SQLite की
busy_timeout setting का उपयोग करके write lock के लिए retry किया जा सकता है
GVL (Global VM Lock) समस्या
sqlite3-ruby gem, SQLite के C code को call करते समय GVL को release नहीं करता
- इससे concurrency performance घट जाती है
busy_handler का उपयोग करके GVL को release किया जा सकता है और performance बेहतर की जा सकती है
busy_timeout का पुनः कार्यान्वयन
busy_timeout को फिर से implement करके यह सेट किया गया कि सभी query एक ही आवृत्ति पर retry हों
- इससे पुराने query timeout होने से बचते हैं
प्रदर्शन सुधार
- प्रदर्शन बेहतर करने के लिए निम्न settings लागू करनी चाहिए
- immediate transaction का उपयोग
- timeout setting
busy_handler का उपयोग
- WAL (Write-Ahead Logging) mode का उपयोग
- read/write connection pool को अलग करना
GN⁺ का सार
- SQLite का उपयोग करने वाले Rails application की performance समस्याओं और उनके समाधानों पर चर्चा की गई है
- immediate transaction, timeout setting, GVL release, WAL mode, और read/write connection pool separation जैसे तरीकों से performance सुधारी जा सकती है
- यह लेख SQLite और Rails का उपयोग करने वाले developers के लिए बहुत उपयोगी होगा
- समान क्षमता वाले अन्य project के रूप में PostgreSQL और MySQL की सिफ़ारिश की गई है
1 टिप्पणियां
Hacker News की राय
Oldmoe के Litestack प्रोजेक्ट का परिचय
विस्तृत लेख लिखने के लिए धन्यवाद
SQLite से जुड़े काम करने वालों के लिए सिफारिश
FOSS analytics system के बारे में सवाल
sqlite3-ruby gem की GVL समस्या
व्यक्तिगत webservice configuration
PRAGMA journal_mode = WALPRAGMA busy_timeout = 5000PRAGMA synchronous = NORMALPRAGMA cache_size = 1000000000PRAGMA foreign_keys = truePRAGMA temp_store = memoryBEGIN IMMEDIATEtransaction का उपयोगDjango के बारे में सवाल
busy_timeoutकी default setting पर सवालbusy_timeoutmethod में ऐसा delay क्यों है जो पुराने queries को दंडित करता हैSQLite और Rails के उपयोग पर राय
Rails integration issues सुलझाने के लिए धन्यवाद