Redis
 sql >> डेटाबेस >  >> NoSQL >> Redis

Node.js, Redis और Socket.io का उपयोग करके कैशिंग ट्वीट्स

इस लेख में, हम उपयोगकर्ता द्वारा दर्ज की गई खोज क्वेरी के आधार पर ट्वीट्स की एक स्ट्रीमिंग सूची बनाएंगे। ट्वीट्स को ट्विटर के स्ट्रीमिंग एपीआई का उपयोग करके प्राप्त किया जाएगा, जिसे रेडिस सूची में संग्रहीत किया जाएगा और सॉकेट.io का उपयोग करके फ्रंट-एंड में अपडेट किया जाएगा। ट्वीट्स लाने के लिए हम मुख्य रूप से Redis का उपयोग कैशिंग लेयर के रूप में करेंगे।

परिचय

यहां उन तकनीकों का संक्षिप्त विवरण दिया गया है जिनका हम उपयोग करेंगे:

रेडिस

रेडिस एक ओपन-सोर्स (बीएसडी लाइसेंस प्राप्त), इन-मेमोरी डेटा स्ट्रक्चर स्टोर है, जिसका उपयोग डेटाबेस, कैश और मैसेज ब्रोकर के रूप में किया जाता है। यह डेटा संरचनाओं जैसे स्ट्रिंग्स, हैश, सूचियों, सेट, श्रेणी प्रश्नों के साथ सॉर्ट किए गए सेट, बिटमैप्स, हाइपरलॉग्स और त्रिज्या प्रश्नों के साथ भू-स्थानिक अनुक्रमणिका का समर्थन करता है।

नोड.जेएस

Node.js आसानी से तेज़ और स्केलेबल नेटवर्क एप्लिकेशन बनाने के लिए क्रोम के जावास्क्रिप्ट रनटाइम पर बनाया गया एक प्लेटफॉर्म है। Node.js एक इवेंट-संचालित, गैर-अवरुद्ध I/O मॉडल का उपयोग करता है जो इसे हल्का और कुशल बनाता है, और इस प्रकार वितरित उपकरणों पर चलने वाले डेटा-गहन रीयल-टाइम अनुप्रयोगों के लिए एकदम सही है।

Express.js

Express.js एक Node.js ढांचा है। आप अधिकांश अन्य वेब भाषाओं की तरह किसी एप्लिकेशन के लिए सर्वर और सर्वर-साइड कोड बना सकते हैं, लेकिन जावास्क्रिप्ट का उपयोग कर सकते हैं।

सॉकेट.आईओ

Socket.IO रीयल-टाइम वेब अनुप्रयोगों के लिए एक जावास्क्रिप्ट लाइब्रेरी है। यह वेब क्लाइंट और सर्वर के बीच रीयल-टाइम, द्वि-दिशात्मक संचार को सक्षम बनाता है। इसके दो भाग हैं:एक क्लाइंट-साइड लाइब्रेरी जो ब्राउज़र पर चलती है, और एक सर्वर-साइड लाइब्रेरी Node.js के लिए। दोनों घटकों में लगभग समान एपीआई हैं।

हेरोकू

Heroku एक क्लाउड प्लेटफ़ॉर्म है जो कंपनियों को ऐप्स बनाने, वितरित करने, मॉनिटर करने और स्केल करने देता है — यह उन सभी बुनियादी ढांचे के सिरदर्द को दरकिनार करते हुए एक विचार से दूसरे URL तक जाने का सबसे तेज़ तरीका है।

यह आलेख मानता है कि आपकी मशीन पर पहले से ही Redis, Node.js और Heroku Toolbelt स्थापित हैं।

सेटअप

- निम्नलिखित रिपॉजिटरी से कोड डाउनलोड करें: https://github.com/Scalegrid/code-samples/tree/sg-redis-node-socket-twitter-search/node-socket-redis-twitter-hashtags

- आवश्यक घटकों को स्थापित करने के लिए npm इंस्टॉल चलाएं

- अंत में, आप "नोड इंडेक्स.जेएस" करके नोड सर्वर शुरू कर सकते हैं। आप "नोडमोन" भी चला सकते हैं जो फ़ाइल परिवर्तनों को भी देखता है।

आप इस ऐप के होस्ट किए गए संस्करण को यहां भी एक्सेस कर सकते हैं: https://node-socket-redis-stream-tweet.herokuapp.com/

प्रक्रिया

यहां उस प्रक्रिया का संक्षिप्त विवरण दिया गया है जिसका उपयोग हम डेमो एप्लिकेशन बनाने के लिए करेंगे:

1. हम उपयोगकर्ता से एक खोज क्वेरी स्वीकार करके शुरू करेंगे। क्वेरी ट्विटर उल्लेख, हैशटैग या कोई यादृच्छिक खोज पाठ हो सकती है।

2. एक बार हमारे पास खोज क्वेरी हो जाने के बाद, हम इसे ट्वीट्स लाने के लिए ट्विटर के स्ट्रीमिंग एपीआई को भेज देंगे। चूंकि यह एक स्ट्रीम है, हम तब सुनेंगे जब एपीआई द्वारा ट्वीट भेजे जाएंगे।

3. जैसे ही कोई ट्वीट पुनः प्राप्त होता है, हम उसे एक रेडिस सूची में संग्रहीत कर देंगे और इसे फ्रंट-एंड पर प्रसारित कर देंगे।

Redis सूचियां क्या हैं?

रेडिस सूचियों को लिंक्ड सूचियों के माध्यम से कार्यान्वित किया जाता है। इसका मतलब यह है कि भले ही आपके पास सूची के अंदर लाखों तत्व हों, फिर भी सूची के शीर्ष या टेल पर एक नया तत्व जोड़ने का कार्य निरंतर समय में किया जाता है। दस तत्वों वाली सूची के शीर्ष पर एलपीयूएसएच कमांड के साथ एक नया तत्व जोड़ने की गति 10 मिलियन तत्वों वाली सूची के शीर्ष पर एक तत्व जोड़ने के समान है।

हमारे आवेदन में, हम एपीआई के माध्यम से प्राप्त ट्वीट्स को "ट्वीट्स" नामक सूची में संग्रहीत करेंगे। हम सूची में नए प्राप्त ट्वीट को पुश करने के लिए एलपीयूएसएच का उपयोग करेंगे, एलटीआरआईएम का उपयोग करके इसे ट्रिम करेंगे जो उपयोग किए गए डिस्क स्थान की मात्रा को प्रतिबंधित करता है (क्योंकि एक स्ट्रीम लिखने में बहुत अधिक जगह लग सकती है), LRANGE का उपयोग करके नवीनतम ट्वीट प्राप्त करें, और इसे प्रसारित करें फ्रंट-एंड जहां इसे स्ट्रीमिंग सूची में जोड़ा जाएगा।

LPUSH, LTRIM और LRANGE क्या है?

ये रेडिस कमांड का एक सेट है जो किसी सूची में डेटा जोड़ने के लिए उपयोग किया जाता है। यहाँ एक संक्षिप्त विवरण दिया गया है:

एलपीयूएसएच

कुंजी पर संग्रहीत सूची के शीर्ष पर सभी निर्दिष्ट मान डालें। यदि कुंजी मौजूद नहीं है, तो इसे पुश ऑपरेशन करने से पहले एक खाली सूची के रूप में बनाया जाता है। जब कुंजी में कोई मान होता है जो सूची नहीं है, तो एक त्रुटि लौटा दी जाती है।

redis> LPUSH mylist "world"
(integer) 1

redis> LPUSH mylist "hello"
(integer) 2

redis> LRANGE mylist 0 -1
1) "hello"
2) "world"

एलटीआरआईएम

किसी मौजूदा सूची को ट्रिम करें ताकि उसमें केवल निर्दिष्ट तत्वों की श्रेणी शामिल हो। स्टार्ट और स्टॉप दोनों शून्य-आधारित इंडेक्स हैं, जहां 0 सूची का पहला तत्व है (सिर), 1 अगला एक तत्व और इसी तरह।

redis> RPUSH mylist "one"
(integer) 1

redis> RPUSH mylist "two"
(integer) 2

redis> RPUSH mylist "three"
(integer) 3

redis> LTRIM mylist 1 -1
"OK"

redis> LRANGE mylist 0 -1
1) "two"
2) "three"

LRANGE

कुंजी पर संग्रहीत सूची के निर्दिष्ट तत्व लौटाता है। ऑफ़सेट स्टार्ट और स्टॉप शून्य-आधारित इंडेक्स हैं, जिसमें 0 सूची का पहला तत्व है (सूची का प्रमुख), 1 अगला है, और इसी तरह।

ये ऑफ़सेट ऋणात्मक संख्याएँ भी हो सकती हैं जो सूची के अंत से स्थिति दर्शाती हैं। उदाहरण के लिए, -1 सूची का अंतिम तत्व है, -2 अंतिम, और इसी तरह।

redis> RPUSH mylist "one"
(integer) 1

redis> RPUSH mylist "two"
(integer) 2

redis> RPUSH mylist "three"
(integer) 3

redis> LRANGE mylist 0 0
1) "one"

redis> LRANGE mylist -3 2
1) "one"
2) "two"
3) "three"

एप्लिकेशन बनाना

हमारे डेमो को फ्रंट-एंड और बैक-एंड दोनों की आवश्यकता होती है। हमारा फ्रंट-एंड एक बटन के साथ एक बहुत ही सरल टेक्स्ट बॉक्स है जिसका उपयोग स्ट्रीम शुरू करने के लिए किया जाएगा।

$('body').on('click', '.btn-search', function() {
   $('#tweets_area').empty();
   $(this).text('Streaming...').attr('disabled', true);
   $.ajax({
       url: '/search',
       type: 'POST',
       data: {
           val: $.trim($('.search-txt').val())
       }
   });
});

एक बार जब हम अपने बैक-एंड से ट्वीट प्राप्त कर लेते हैं, तो हमें एक ट्वीट बॉक्स बनाने के लिए एक हेल्पर फंक्शन की आवश्यकता होती है:

 var _buildTweetBox = function(status) {
     var html = '';
     html += '<div class="media tweet-single">';
     html += ' <div class="media-left">';
     html += ' <a href="https://twitter.com/' + status.user.screen_name + '" target="_blank" title="' + status.user.name + '">';
     html += ' <img class="media-object" src="' + status.user.profile_image_url_https + '" alt="' + status.user.name + '" />';
     html += ' </a>';
     html += ' </div>';
     html += ' <div class="media-body">';
     html += ' <h5 class="media-heading"><a href="https://twitter.com/' + status.user.screen_name + '" target="_blank">' + status.user.screen_name + '</a></h5>';
     html += '<p class="tweet-body" title="View full tweet" data-link="https://twitter.com/' + status.user.screen_name + '/status/' + status.id_str + '">' + status.text + '</p>';
     html += ' </div>';
     html += '</div>';
     $('#tweets_area').prepend(html);
     $('#tweets_area').find('.tweet-single').first().fadeIn('slow');
};

स्ट्रीम को रोकने और स्ट्रीमिंग सूची में कोई और ट्वीट जोड़ने से रोकने के लिए हमें एक श्रोता की भी आवश्यकता होती है:

socket.on('stream:destroy', function(status) {
    $('.btn-search').text('Start streaming').removeAttr('disabled');
    $('.alert-warning').fadeIn('slow');
    setTimeout(function() {
       $('.alert-warning').fadeOut('slow');
    }, STREAM_END_TIMEOUT * 1000);
});

आइए चीजों के बैक-एंड पर स्विच करें और अपना /Search API लिखना शुरू करें।

/**
 * API - Search
 */
app.post('/search', function(req, res, next) {
   _searchTwitter(req.body.val);
   res.send({
       status: 'OK'
   });
});

/**
 * Stream data from Twitter for input text
 *
 * 1. Use the Twitter streaming API to track a specific value entered by the user
 * 2. Once we have the data from Twitter, add it to a Redis list using LPUSH
 * 3. After adding to list, limit the list using LTRIM so the stream doesn't overflow the disk
 * 4. Use LRANGE to fetch the latest tweet and emit it to the front-end using Socket.io
 *
 * @param {String} val Query String
 * @return
 */
var _searchTwitter = function(val) {
   twit.stream('statuses/filter', {track: val}, function(stream) {
   stream.on('data', function(data) {
       client.lpush('tweets', JSON.stringify(data), function() {
           client.ltrim('tweets', 0, TWEETS_TO_KEEP, function() {
              client.lrange('tweets', 0, 1, function(err, tweetListStr) {
                  io.emit('savedTweetToRedis', JSON.parse(tweetListStr[0]));
               });
           });
        });
    });
    stream.on('destroy', function(response) {
        io.emit('stream:destroy');
    });
    stream.on('end', function(response) {
        io.emit('stream:destroy');
    });
    setTimeout(stream.destroy, STREAM_TIMEOUT * 1000);
    });
}

उपरोक्त कोड में हमारे बैक-एंड का मूल है। /Search पर अनुरोध प्राप्त होने के बाद, हम Twitter के स्ट्रीमिंग API का उपयोग करके स्ट्रीम शुरू करते हैं जो एक स्ट्रीम ऑब्जेक्ट देता है।

twit.stream('statuses/filter', {track: val}, function(stream) {});

हम "डेटा" नामक कुंजी के लिए स्ट्रीम ऑब्जेक्ट को सुन सकते हैं जो उपलब्ध होने पर हमें एक नया ट्वीट भेजेगी।

stream.on('data', function(data) {});

"डेटा" ऑब्जेक्ट में ट्वीट JSON होता है जो कुछ इस तरह दिख सकता है (प्रतिक्रिया का हिस्सा छोड़ दिया गया है):

{
 "created_at": "Wed Jul 26 08:01:56 +0000 2017",
 "id": 890119982641803300,
 "id_str": "890119982641803264",
 "text": "RT @FoxNews: Jim DeMint: \"There is no better man than Jeff Sessions, and no greater supporter...of [President #Trump's] agenda.\"… ",
 "source": "<a href=\"http://twitter.com/download/android\" rel=\"nofollow\">Twitter for Android</a>",
 "truncated": false,
 "in_reply_to_status_id": null,
 "in_reply_to_status_id_str": null,
 "in_reply_to_user_id": null,
 "in_reply_to_user_id_str": null,
 "in_reply_to_screen_name": null,
 "user": {
 "id": 4833141138,
 "id_str": "4833141138",
 "name": "randy joe davis",
 "screen_name": "randyjoedavis1",
 "location": null,
 "url": null,
 "description": "Conservative Patriot, retired military, retired DOD civilian. cattle farmer, horseman, adventurer. Lovin Life ! GO HOGS !!",
 "protected": false,
 "verified": false,
 "followers_count": 226,
 "friends_count": 346,
 "listed_count": 0,
 "favourites_count": 3751,
 "statuses_count": 1339,
 "created_at": "Sat Jan 30 03:39:16 +0000 2016",
 "utc_offset": null,
 "time_zone": null,
 "geo_enabled": false,
 "lang": "en",
 "contributors_enabled": false,
 "is_translator": false,
 "profile_background_color": "F5F8FA",
 "profile_background_image_url": "",
 "profile_background_image_url_https": "",
 "profile_background_tile": false,
 "profile_link_color": "1DA1F2",
 "profile_sidebar_border_color": "C0DEED",
 "profile_sidebar_fill_color": "DDEEF6",
 "profile_text_color": "333333",
 "profile_use_background_image": true,
 "profile_image_url": "http://pbs.twimg.com/profile_images/883522005210943488/rqyyXlEX_normal.jpg",
 "profile_image_url_https": "https://pbs.twimg.com/profile_images/883522005210943488/rqyyXlEX_normal.jpg",
 "default_profile": true,
 "default_profile_image": false,
 "following": null,
 "follow_request_sent": null,
 "notifications": null
 }
}

हम इस प्रतिक्रिया को एलपीयूएसएच का उपयोग करके "ट्वीट्स" नामक एक रेडिस सूची में संग्रहीत करते हैं:

client.lpush('tweets', JSON.stringify(data), function() {});

एक बार ट्वीट सहेज लिए जाने के बाद, हम ट्वीट्स की अधिकतम संख्या रखने के लिए एलटीआरआईएम का उपयोग करके सूची को ट्रिम कर देते हैं (ताकि हमारा डिस्क स्थान पूर्ण न हो):

client.ltrim('tweets', 0, TWEETS_TO_KEEP, function() {});

सूची को ट्रिम करने के बाद, हम LRANGE का उपयोग करके नवीनतम ट्वीट प्राप्त करते हैं और इसे फ्रंट-एंड पर भेजते हैं:

client.lrange('tweets', 0, 1, function(err, tweetListStr) {
 io.emit('savedTweetToRedis', JSON.parse(tweetListStr[0]));
});

चूंकि यह एक डेमो एप्लिकेशन है, इसलिए हमें एक विशिष्ट समय के बाद स्ट्रीम को मैन्युअल रूप से नष्ट करने की भी आवश्यकता होती है ताकि यह डिस्क पर लिखना जारी न रखे:

stream.on('end', function(response) {
 io.emit('stream:destroy');
});
setTimeout(stream.destroy, STREAM_TIMEOUT * 1000);

और आपने कल लिया! npm start का उपयोग करके सर्वर को सक्रिय करें और स्ट्रीमिंग अनुभव का आनंद लें।

एप्लिकेशन का डेमो यहां उपलब्ध है: https://node-socket-redis-stream-tweet.herokuapp.com/

इस एप्लिकेशन को हरोकू पर तैनात करने के लिए, उनके दस्तावेज़ देखें:https://devcenter.heroku.com/categories/deployment

आपके लिए कांटा और काम करने के लिए संपूर्ण स्रोत कोड GitHub पर भी उपलब्ध है: https://github.com/Scalegrid/code-samples/tree/sg-redis-node-socket-twitter-search/node-socket-redis -ट्विटर-हैशटैग

हमेशा की तरह, अगर आप कुछ शानदार बनाते हैं, तो हमें इसके बारे में ट्वीट करें @scalegridio.

यदि आपको Redis™* के प्रबंधन और होस्टिंग में सहायता की आवश्यकता है, तो अधिक जानकारी के लिए [email protected] पर हमसे संपर्क करें।


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. जावा बाइट्स को बाइनरी सेफ स्ट्रिंग में बदलें

  2. रेडिस सीपीयू उपयोग को प्रदर्शित करने के लिए किस इकाई का उपयोग किया जाता है

  3. रेडिस के लिए पासवर्ड कैसे सेट करें?

  4. रूबी - समाप्ति कार्यान्वयन के साथ रेडिस आधारित म्यूटेक्स

  5. Azure Redis कैश - GET कॉल पर टाइमआउट