தமிழ்

பெரிய டேட்டாசெட்களை திறமையாக கையாண்டு, அளவிடுதல் மற்றும் பதிலளிக்கும் தன்மையை மேம்படுத்துவதன் மூலம், உங்கள் பயன்பாட்டின் செயல்திறனை Node.js ஸ்ட்ரீம்கள் எவ்வாறு புரட்சிகரமாக மாற்றுகின்றன என்பதை அறியுங்கள்.

Node.js ஸ்ட்ரீம்கள்: பெரிய டேட்டாவை திறமையாக கையாளுதல்

டேட்டாவை அடிப்படையாகக் கொண்ட பயன்பாடுகளின் இந்த நவீன காலத்தில், பெரிய டேட்டாசெட்களை திறமையாக கையாள்வது மிக முக்கியம். Node.js, அதன் நான்-பிளாக்கிங், ஈவென்ட்-டிரைவன் கட்டமைப்புடன், டேட்டாவை நிர்வகிக்கக்கூடிய சிறு துண்டுகளாக செயலாக்க ஒரு சக்திவாய்ந்த வழிமுறையை வழங்குகிறது: ஸ்ட்ரீம்கள். இந்த கட்டுரை Node.js ஸ்ட்ரீம்களின் உலகிற்குள் ஆழமாகச் சென்று, அவற்றின் நன்மைகள், வகைகள் மற்றும் வளங்களை வீணாக்காமல் பெரிய அளவிலான டேட்டாவை கையாளக்கூடிய, அளவிடக்கூடிய மற்றும் பதிலளிக்கக்கூடிய பயன்பாடுகளை உருவாக்குவதற்கான அதன் நடைமுறை பயன்பாடுகளை ஆராய்கிறது.

ஸ்ட்ரீம்களை ஏன் பயன்படுத்த வேண்டும்?

பாரம்பரியமாக, ஒரு கோப்பை முழுமையாகப் படிப்பது அல்லது ஒரு நெட்வொர்க் கோரிக்கையிலிருந்து எல்லா டேட்டாவையும் செயலாக்குவதற்கு முன்பு பெறுவது, குறிப்பிடத்தக்க செயல்திறன் தடைகளை ஏற்படுத்தும், குறிப்பாக பெரிய கோப்புகள் அல்லது தொடர்ச்சியான டேட்டா ஊட்டங்களைக் கையாளும்போது. பஃபரிங் எனப்படும் இந்த அணுகுமுறை, கணிசமான நினைவகத்தைப் பயன்படுத்தும் மற்றும் பயன்பாட்டின் ஒட்டுமொத்த பதிலளிக்கும் தன்மையை மெதுவாக்கும். ஸ்ட்ரீம்கள், டேட்டாவை சிறிய, சுதந்திரமான துண்டுகளாக செயலாக்குவதன் மூலம் ஒரு திறமையான மாற்றீட்டை வழங்குகின்றன. முழு டேட்டாசெட் ஏற்றப்படும் வரை காத்திருக்காமல், டேட்டா கிடைத்தவுடன் அதனுடன் வேலை செய்யத் தொடங்க இது உங்களை அனுமதிக்கிறது. இந்த அணுகுமுறை குறிப்பாக இதற்கு பயனுள்ளதாக இருக்கும்:

ஸ்ட்ரீம் வகைகளைப் புரிந்துகொள்ளுதல்

Node.js நான்கு அடிப்படை வகையான ஸ்ட்ரீம்களை வழங்குகிறது, ஒவ்வொன்றும் ஒரு குறிப்பிட்ட நோக்கத்திற்காக வடிவமைக்கப்பட்டுள்ளது:

  1. படிக்கக்கூடிய ஸ்ட்ரீம்கள் (Readable Streams): படிக்கக்கூடிய ஸ்ட்ரீம்கள் ஒரு மூலத்திலிருந்து, அதாவது ஒரு கோப்பு, ஒரு நெட்வொர்க் இணைப்பு அல்லது ஒரு டேட்டா ஜெனரேட்டரிலிருந்து டேட்டாவைப் படிக்கப் பயன்படுகின்றன. புதிய டேட்டா கிடைக்கும்போது அவை 'data' நிகழ்வுகளையும், டேட்டா மூலம் முழுமையாகப் பயன்படுத்தப்பட்டவுடன் 'end' நிகழ்வுகளையும் வெளியிடுகின்றன.
  2. எழுதக்கூடிய ஸ்ட்ரீம்கள் (Writable Streams): எழுதக்கூடிய ஸ்ட்ரீம்கள் ஒரு இலக்குக்கு, அதாவது ஒரு கோப்பு, ஒரு நெட்வொர்க் இணைப்பு அல்லது ஒரு டேட்டாபேஸுக்கு டேட்டாவை எழுதப் பயன்படுகின்றன. அவை டேட்டாவை எழுதுவதற்கும் பிழைகளைக் கையாளுவதற்கும் முறைகளை வழங்குகின்றன.
  3. டியூப்ளெக்ஸ் ஸ்ட்ரீம்கள் (Duplex Streams): டியூப்ளெக்ஸ் ஸ்ட்ரீம்கள் படிக்கக்கூடியதாகவும் எழுதக்கூடியதாகவும் இருக்கும், இதனால் டேட்டா ஒரே நேரத்தில் இரு திசைகளிலும் பாய அனுமதிக்கிறது. அவை பொதுவாக சாக்கெட்டுகள் போன்ற நெட்வொர்க் இணைப்புகளுக்குப் பயன்படுத்தப்படுகின்றன.
  4. டிரான்ஸ்ஃபார்ம் ஸ்ட்ரீம்கள் (Transform Streams): டிரான்ஸ்ஃபார்ம் ஸ்ட்ரீம்கள் ஒரு சிறப்பு வகை டியூப்ளெக்ஸ் ஸ்ட்ரீம்கள் ஆகும், அவை டேட்டா கடந்து செல்லும்போது அதை மாற்றியமைக்க அல்லது உருமாற்ற முடியும். சுருக்கம், குறியாக்கம் அல்லது டேட்டா மாற்றம் போன்ற பணிகளுக்கு அவை சிறந்தவை.

படிக்கக்கூடிய ஸ்ட்ரீம்களுடன் வேலை செய்தல்

படிக்கக்கூடிய ஸ்ட்ரீம்கள் பல்வேறு மூலங்களிலிருந்து டேட்டாவைப் படிப்பதற்கான அடித்தளமாகும். ஒரு படிக்கக்கூடிய ஸ்ட்ரீமைப் பயன்படுத்தி ஒரு பெரிய டெக்ஸ்ட் கோப்பைப் படிப்பதற்கான ஒரு அடிப்படை உதாரணம் இங்கே:

const fs = require('fs');

const readableStream = fs.createReadStream('large-file.txt', { encoding: 'utf8', highWaterMark: 16384 });

readableStream.on('data', (chunk) => {
  console.log(`Received ${chunk.length} bytes of data`);
  // Process the data chunk here
});

readableStream.on('end', () => {
  console.log('Finished reading the file');
});

readableStream.on('error', (err) => {
  console.error('An error occurred:', err);
});

இந்த எடுத்துக்காட்டில்:

எழுதக்கூடிய ஸ்ட்ரீம்களுடன் வேலை செய்தல்

எழுதக்கூடிய ஸ்ட்ரீம்கள் பல்வேறு இலக்குகளுக்கு டேட்டாவை எழுதப் பயன்படுகின்றன. ஒரு எழுதக்கூடிய ஸ்ட்ரீமைப் பயன்படுத்தி ஒரு கோப்பில் டேட்டாவை எழுதுவதற்கான ஒரு உதாரணம் இங்கே:

const fs = require('fs');

const writableStream = fs.createWriteStream('output.txt', { encoding: 'utf8' });

writableStream.write('This is the first line of data.\n');
writableStream.write('This is the second line of data.\n');
writableStream.write('This is the third line of data.\n');

writableStream.end(() => {
  console.log('Finished writing to the file');
});

writableStream.on('error', (err) => {
  console.error('An error occurred:', err);
});

இந்த எடுத்துக்காட்டில்:

ஸ்ட்ரீம்களை பைப்பிங் செய்தல்

பைப்பிங் என்பது படிக்கக்கூடிய மற்றும் எழுதக்கூடிய ஸ்ட்ரீம்களை இணைப்பதற்கான ஒரு சக்திவாய்ந்த வழிமுறையாகும், இது ஒரு ஸ்ட்ரீமிலிருந்து மற்றொரு ஸ்ட்ரீமிற்கு டேட்டாவை தடையின்றி மாற்ற அனுமதிக்கிறது. pipe() முறை ஸ்ட்ரீம்களை இணைக்கும் செயல்முறையை எளிதாக்குகிறது, டேட்டா ஓட்டம் மற்றும் பிழை பரவலை தானாகவே கையாளுகிறது. இது ஸ்ட்ரீமிங் முறையில் டேட்டாவைச் செயலாக்க மிகவும் திறமையான வழியாகும்.

const fs = require('fs');
const zlib = require('zlib'); // For gzip compression

const readableStream = fs.createReadStream('large-file.txt');
const gzipStream = zlib.createGzip();
const writableStream = fs.createWriteStream('large-file.txt.gz');

readableStream.pipe(gzipStream).pipe(writableStream);

writableStream.on('finish', () => {
  console.log('File compressed successfully!');
});

இந்த எடுத்துக்காட்டு ஒரு பெரிய கோப்பை பைப்பிங் பயன்படுத்தி எவ்வாறு சுருக்குவது என்பதைக் காட்டுகிறது:

பைப்பிங் பின்தள்ளுவிசையை தானாகவே கையாளுகிறது. ஒரு படிக்கக்கூடிய ஸ்ட்ரீம், எழுதக்கூடிய ஸ்ட்ரீம் நுகரக்கூடியதை விட வேகமாக டேட்டாவை உருவாக்கும்போது பின்தள்ளுவிசை ஏற்படுகிறது. எழுதக்கூடிய ஸ்ட்ரீம் அதிக டேட்டாவைப் பெறத் தயாராகும் வரை டேட்டாவின் ஓட்டத்தை இடைநிறுத்துவதன் மூலம், படிக்கக்கூடிய ஸ்ட்ரீம் எழுதக்கூடிய ஸ்ட்ரீமை மூழ்கடிப்பதை பைப்பிங் தடுக்கிறது. இது திறமையான வளப் பயன்பாட்டை உறுதிசெய்து, நினைவக வழிதலைத் தடுக்கிறது.

டிரான்ஸ்ஃபார்ம் ஸ்ட்ரீம்கள்: டேட்டாவை பயணத்தின் போதே மாற்றுதல்

டிரான்ஸ்ஃபார்ம் ஸ்ட்ரீம்கள், படிக்கக்கூடிய ஸ்ட்ரீமிலிருந்து எழுதக்கூடிய ஸ்ட்ரீமிற்கு டேட்டா பாயும்போது அதை மாற்றியமைக்க அல்லது உருமாற்ற ஒரு வழியை வழங்குகின்றன. டேட்டா மாற்றம், வடிகட்டுதல் அல்லது குறியாக்கம் போன்ற பணிகளுக்கு அவை குறிப்பாக பயனுள்ளதாக இருக்கும். டிரான்ஸ்ஃபார்ம் ஸ்ட்ரீம்கள் டியூப்ளெக்ஸ் ஸ்ட்ரீம்களிலிருந்து பெறப்படுகின்றன மற்றும் டேட்டா உருமாற்றத்தைச் செய்யும் _transform() முறையைச் செயல்படுத்துகின்றன.

டெக்ஸ்டை பெரிய எழுத்துகளாக மாற்றும் ஒரு டிரான்ஸ்ஃபார்ம் ஸ்ட்ரீமின் உதாரணம் இங்கே:

const { Transform } = require('stream');

class UppercaseTransform extends Transform {
  constructor() {
    super();
  }

  _transform(chunk, encoding, callback) {
    const transformedChunk = chunk.toString().toUpperCase();
    callback(null, transformedChunk);
  }
}

const uppercaseTransform = new UppercaseTransform();

const readableStream = process.stdin; // Read from standard input
const writableStream = process.stdout; // Write to standard output

readableStream.pipe(uppercaseTransform).pipe(writableStream);

இந்த எடுத்துக்காட்டில்:

பின்தள்ளுவிசையை கையாளுதல்

பின்தள்ளுவிசை என்பது ஸ்ட்ரீம் செயலாக்கத்தில் ஒரு முக்கியமான கருத்தாகும், இது ஒரு ஸ்ட்ரீம் மற்றொரு ஸ்ட்ரீமை மூழ்கடிப்பதைத் தடுக்கிறது. ஒரு படிக்கக்கூடிய ஸ்ட்ரீம், எழுதக்கூடிய ஸ்ட்ரீம் நுகரக்கூடியதை விட வேகமாக டேட்டாவை உருவாக்கும்போது பின்தள்ளுவிசை ஏற்படுகிறது. சரியான கையாளுதல் இல்லாமல், பின்தள்ளுவிசை நினைவக வழிதலுக்கும் பயன்பாட்டு உறுதியற்ற தன்மைக்கும் வழிவகுக்கும். Node.js ஸ்ட்ரீம்கள் பின்தள்ளுவிசையை திறம்பட நிர்வகிப்பதற்கான வழிமுறைகளை வழங்குகின்றன.

pipe() முறை பின்தள்ளுவிசையை தானாகவே கையாளுகிறது. ஒரு எழுதக்கூடிய ஸ்ட்ரீம் அதிக டேட்டாவைப் பெறத் தயாராக இல்லாதபோது, எழுதக்கூடிய ஸ்ட்ரீம் தயாராக உள்ளது என்று சமிக்ஞை செய்யும் வரை படிக்கக்கூடிய ஸ்ட்ரீம் இடைநிறுத்தப்படும். இருப்பினும், ஸ்ட்ரீம்களுடன் நிரல்ரீதியாக (pipe() ஐப் பயன்படுத்தாமல்) வேலை செய்யும்போது, readable.pause() மற்றும் readable.resume() முறைகளைப் பயன்படுத்தி நீங்கள் பின்தள்ளுவிசையை கைமுறையாகக் கையாள வேண்டும்.

பின்தள்ளுவிசையை கைமுறையாக எவ்வாறு கையாள்வது என்பதற்கான ஒரு உதாரணம் இங்கே:

const fs = require('fs');

const readableStream = fs.createReadStream('large-file.txt');
const writableStream = fs.createWriteStream('output.txt');

readableStream.on('data', (chunk) => {
  if (!writableStream.write(chunk)) {
    readableStream.pause();
  }
});

writableStream.on('drain', () => {
  readableStream.resume();
});

readableStream.on('end', () => {
  writableStream.end();
});

இந்த எடுத்துக்காட்டில்:

Node.js ஸ்ட்ரீம்களின் நடைமுறைப் பயன்பாடுகள்

Node.js ஸ்ட்ரீம்கள் பெரிய டேட்டாவைக் கையாள்வது முக்கியமான பல்வேறு சூழ்நிலைகளில் பயன்பாடுகளைக் கண்டறிகின்றன. சில எடுத்துக்காட்டுகள் இங்கே:

Node.js ஸ்ட்ரீம்களைப் பயன்படுத்துவதற்கான சிறந்த நடைமுறைகள்

Node.js ஸ்ட்ரீம்களை திறம்படப் பயன்படுத்தவும் அவற்றின் நன்மைகளை அதிகரிக்கவும், பின்வரும் சிறந்த நடைமுறைகளைக் கவனியுங்கள்:

முடிவுரை

Node.js ஸ்ட்ரீம்கள் பெரிய டேட்டாவை திறமையாகக் கையாளுவதற்கான ஒரு சக்திவாய்ந்த கருவியாகும். டேட்டாவை நிர்வகிக்கக்கூடிய துண்டுகளாகச் செயலாக்குவதன் மூலம், ஸ்ட்ரீம்கள் நினைவக நுகர்வைக் கணிசமாகக் குறைக்கின்றன, செயல்திறனை மேம்படுத்துகின்றன மற்றும் அளவிடுதலை அதிகரிக்கின்றன. வெவ்வேறு ஸ்ட்ரீம் வகைகளைப் புரிந்துகொள்வது, பைப்பிங்கில் தேர்ச்சி பெறுவது மற்றும் பின்தள்ளுவிசையைக் கையாள்வது ஆகியவை பெரிய அளவிலான டேட்டாவை எளிதாகக் கையாளக்கூடிய வலுவான மற்றும் திறமையான Node.js பயன்பாடுகளை உருவாக்குவதற்கு அவசியமானவை. இந்தக் கட்டுரையில் கோடிட்டுக் காட்டப்பட்டுள்ள சிறந்த நடைமுறைகளைப் பின்பற்றுவதன் மூலம், நீங்கள் Node.js ஸ்ட்ரீம்களின் முழு திறனையும் பயன்படுத்திக் கொள்ளலாம் மற்றும் பரந்த அளவிலான டேட்டா-தீவிர பணிகளுக்கான உயர் செயல்திறன், அளவிடக்கூடிய பயன்பாடுகளை உருவாக்கலாம்.

உங்கள் Node.js மேம்பாட்டில் ஸ்ட்ரீம்களை அரவணைத்து, உங்கள் பயன்பாடுகளில் ஒரு புதிய அளவிலான செயல்திறனையும் அளவிடுதலையும் திறக்கவும். டேட்டா தொகுதிகள் தொடர்ந்து வளர்ந்து வருவதால், டேட்டாவை திறமையாக செயலாக்கும் திறன் பெருகிய முறையில் முக்கியமானதாக மாறும், மேலும் Node.js ஸ்ட்ரீம்கள் இந்த சவால்களை எதிர்கொள்ள ஒரு உறுதியான அடித்தளத்தை வழங்குகின்றன.