PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

बड़ी मात्रा में प्रश्नों के साथ नोड-पोस्टग्रेज

अपडेट करें

यह उत्तर तब से इस लेख से हटा दिया गया है:डेटा आयात , जो सबसे अद्यतित दृष्टिकोण का प्रतिनिधित्व करता है।

आपके परिदृश्य को दोहराने के लिए मैंने pg-promise का इस्तेमाल किया पुस्तकालय, और मैं इस बात की पुष्टि कर सकता हूं कि इसे सिर पर आजमाने से कभी काम नहीं चलेगा, चाहे आप किसी भी पुस्तकालय का उपयोग करें, यह दृष्टिकोण है जो मायने रखता है।

नीचे एक संशोधित दृष्टिकोण है जहां हम विभाजन को टुकड़ों में विभाजित करते हैं और फिर लेनदेन के भीतर प्रत्येक खंड को निष्पादित करते हैं, जो लोड संतुलन (उर्फ थ्रॉटलिंग) है:

function insertRecords(N) {
    return db.tx(function (ctx) {
        var queries = [];
        for (var i = 1; i <= N; i++) {
            queries.push(ctx.none('insert into test(name) values($1)', 'name-' + i));
        }
        return promise.all(queries);
    });
}
function insertAll(idx) {
    if (!idx) {
        idx = 0;
    }
    return insertRecords(100000)
        .then(function () {
            if (idx >= 9) {
                return promise.resolve('SUCCESS');
            } else {
                return insertAll(++idx);
            }
        }, function (reason) {
            return promise.reject(reason);
        });
}
insertAll()
    .then(function (data) {
        console.log(data);
    }, function (reason) {
        console.log(reason);
    })
    .done(function () {
        pgp.end();
    });

इसने लगभग 4 मिनट में 1,000,000 रिकॉर्ड बनाए, पहले 3 लेनदेन के बाद नाटकीय रूप से धीमा। मैं नोड जेएस 0.10.38 (64-बिट) का उपयोग कर रहा था, जिसने लगभग 340 एमबी मेमोरी की खपत की। इस तरह हमने लगातार 10 बार 100,000 रिकॉर्ड डाले।

यदि हम ऐसा ही करते हैं, तो केवल इस बार 100 लेन-देन के भीतर 10,000 रिकॉर्ड डालें, वही 1,00,000 रिकॉर्ड केवल 1m25 में जोड़े जाते हैं, कोई धीमा नहीं, नोड जेएस के साथ लगभग 100 एमबी मेमोरी की खपत होती है, जो हमें बताता है कि इस तरह से डेटा का विभाजन करना बहुत है अच्छा विचार।

इससे कोई फर्क नहीं पड़ता कि आप किस पुस्तकालय का उपयोग करते हैं, दृष्टिकोण समान होना चाहिए:

  1. अपने निवेशों को कई लेन-देन में विभाजित/थ्रॉटल करें;
  2. एक ही लेन-देन में इंसर्ट की सूची को लगभग 10,000 रिकॉर्ड पर रखें;
  3. अपने सभी लेन-देन एक समकालिक श्रृंखला में निष्पादित करें।
  4. प्रत्येक लेनदेन के COMMIT के बाद कनेक्शन को वापस पूल में छोड़ दें।

यदि आप इनमें से किसी भी नियम को तोड़ते हैं, तो आपको परेशानी की गारंटी है। उदाहरण के लिए, यदि आप नियम 3 को तोड़ते हैं, तो आपकी नोड JS प्रक्रिया के स्मृति से वास्तविक रूप से जल्दी समाप्त होने और एक त्रुटि होने की संभावना है। मेरे उदाहरण में नियम 4 पुस्तकालय द्वारा प्रदान किया गया था।

और अगर आप इस पैटर्न का पालन करते हैं, तो आपको कनेक्शन पूल सेटिंग्स के साथ खुद को परेशान करने की आवश्यकता नहीं है।

अपडेट 1

pg-promise के बाद के संस्करण ऐसे परिदृश्यों का पूरी तरह से समर्थन करें, जैसा कि नीचे दिखाया गया है:

function factory(index) {
    if (index < 1000000) {
        return this.query('insert into test(name) values($1)', 'name-' + index);
    }
}

db.tx(function () {
    return this.batch([
        this.none('drop table if exists test'),
        this.none('create table test(id serial, name text)'),
        this.sequence(factory), // key method
        this.one('select count(*) from test')
    ]);
})
    .then(function (data) {
        console.log("COUNT:", data[3].count);
    })
    .catch(function (error) {
        console.log("ERROR:", error);
    });

और यदि आप कुछ अतिरिक्त शामिल नहीं करना चाहते हैं, जैसे टेबल बनाना, तो यह और भी आसान लगता है:

function factory(index) {
    if (index < 1000000) {
        return this.query('insert into test(name) values($1)', 'name-' + index);
    }
}

db.tx(function () {
    return this.sequence(factory);
})
    .then(function (data) {
        // success;
    })
    .catch(function (error) {
        // error;
    });

देखें तुल्यकालिक लेन-देन ब्योरा हेतु।

Bluebird का उपयोग करना वादा पुस्तकालय के रूप में, उदाहरण के लिए, मेरी उत्पादन मशीन पर 1,000,000 रिकॉर्ड सम्मिलित करने में 1m43s लगते हैं (लंबे स्टैक ट्रेस सक्षम किए बिना)।

आपके पास बस आपकी factory होगी index . के अनुसार विधि वापसी अनुरोध , जब तक आपके पास कुछ नहीं बचा, उतना ही सरल।

और सबसे अच्छी बात, यह न केवल तेज़ है, बल्कि आपकी NodeJS प्रक्रिया पर बहुत कम भार भी डालता है। मेमोरी परीक्षण प्रक्रिया पूरे परीक्षण के दौरान 60MB से कम रहती है, CPU समय का केवल 7-8% खर्च करती है।

अपडेट 2

संस्करण 1.7.2 से शुरू, pg-promise आसानी से सुपर-विशाल लेनदेन का समर्थन करता है। अध्याय देखें तुल्यकालिक लेन-देन

उदाहरण के लिए, मैं विंडोज 8.1 64-बिट के साथ अपने होम पीसी पर सिर्फ 15 मिनट में एक ट्रांजैक्शन में 10,000,000 रिकॉर्ड डाल सकता हूं।

परीक्षण के लिए मैंने अपने पीसी को प्रोडक्शन मोड पर सेट किया, और Bluebird का उपयोग किया वादा पुस्तकालय के रूप में। परीक्षण के दौरान, संपूर्ण NodeJS 0.12.5 प्रक्रिया (64-बिट) के लिए मेमोरी खपत 75MB से अधिक नहीं गई, जबकि मेरे i7-4770 CPU ने लगातार 15% लोड दिखाया।

उसी तरह 100 मीटर रिकॉर्ड डालने के लिए अधिक धैर्य की आवश्यकता होगी, लेकिन अधिक कंप्यूटर संसाधनों की नहीं।

इस बीच, 1m सम्मिलन के लिए पिछला परीक्षण 1m43s से 1m31s तक गिर गया।

3 अपडेट करें

निम्नलिखित बातों से बहुत बड़ा अंतर आ सकता है:प्रदर्शन बूस्ट

अपडेट 4

संबंधित प्रश्न, एक बेहतर कार्यान्वयन उदाहरण के साथ:pg-promise के साथ बड़े पैमाने पर इंसर्ट

अपडेट 5

एक बेहतर और नया उदाहरण यहां पाया जा सकता है:nodeJS डेटा डालना PostgreSQL त्रुटि में



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. डेटाबेस में तैयार विवरण सम्मिलित करना - PSQL

  2. Postgresql date_trunc समय क्षेत्र के साथ क्षेत्र 1 घंटे से बदल जाता है

  3. मैं sqlalchemy के साथ डॉकर के भीतर postgresql का उपयोग कैसे करूं?

  4. ऑपरेटर मौजूद नहीं है:uuid =bytea Java with Postgres

  5. स्प्रिंग बूट टेस्ट के लिए एंबेडेड पोस्टग्रेज