sql >> Databáze >  >> NoSQL >> Redis

Ukládání tweetů do mezipaměti pomocí Node.js, Redis a Socket.io

V tomto článku vytvoříme seznam streamovaných tweetů na základě vyhledávacího dotazu zadaného uživatelem. Tweety budou načteny pomocí rozhraní Twitter Streaming API, budou uloženy v seznamu Redis a aktualizovány ve front-endu pomocí Socket.io. Redis budeme primárně používat jako mezipaměťovou vrstvu pro načítání tweetů.

Úvod

Zde je stručný popis technologií, které budeme používat:

Redis

Redis je úložiště datových struktur v paměti s otevřeným zdrojovým kódem (s licencí BSD), které se používá jako databáze, mezipaměť a zprostředkovatel zpráv. Podporuje datové struktury, jako jsou řetězce, hash, seznamy, sady, seřazené sady s dotazy na rozsah, bitmapy, hyperlogy a geoprostorové indexy s poloměrovými dotazy.

Node.js

Node.js je platforma postavená na běhovém prostředí JavaScriptu Chrome pro snadné vytváření rychlých a škálovatelných síťových aplikací. Node.js používá událostmi řízený, neblokující I/O model, díky kterému je lehký a efektivní, a proto je ideální pro datově náročné aplikace v reálném čase, které běží napříč distribuovanými zařízeními.

Express.js

Express.js je framework Node.js. Můžete vytvořit server a kód na straně serveru pro aplikaci jako většinu ostatních webových jazyků, ale pomocí JavaScriptu.

Socket.IO

Socket.IO je JavaScriptová knihovna pro webové aplikace v reálném čase. Umožňuje obousměrnou komunikaci mezi webovými klienty a servery v reálném čase. Má dvě části:knihovnu na straně klienta, která běží v prohlížeči, a knihovnu na straně serveru pro Node.js. Obě komponenty mají téměř identická rozhraní API.

Heroku

Heroku je cloudová platforma, která společnostem umožňuje vytvářet, dodávat, monitorovat a škálovat aplikace – je to nejrychlejší způsob, jak přejít od nápadu k adrese URL a obejít všechny ty problémy s infrastrukturou.

Tento článek předpokládá, že již máte na svém počítači nainstalovány Redis, Node.js a Heroku Toolbelt.

Nastavení

– Stáhněte si kód z následujícího úložiště: https://github.com/Scalegrid/code-samples/tree/sg-redis-node-socket-twitter-search/node-socket-redis-twitter-hashtags

- Spusťte npm install a nainstalujte potřebné součásti

- Nakonec můžete spustit uzlový server zadáním „node index.js“. Můžete také spustit „nodemon“, který také sleduje změny souborů.

Můžete také přistupovat k hostované verzi této aplikace zde: https://node-socket-redis-stream-tweet.herokuapp.com/

Proces

Zde je stručný popis procesu, který použijeme k vytvoření demo aplikace:

1. Začneme tím, že přijmeme vyhledávací dotaz od uživatele. Dotazem mohou být zmínky na Twitteru, hashtagy nebo jakýkoli náhodný hledaný text.

2. Jakmile máme vyhledávací dotaz, odešleme jej do Streaming API Twitteru, abychom načetli tweety. Vzhledem k tomu, že se jedná o stream, budeme naslouchat, když budou tweety odesílány rozhraním API.

3. Jakmile je tweet načten, uložíme jej do seznamu Redis a odešleme jej do front-endu.

Co jsou seznamy Redis?

Seznamy Redis jsou implementovány prostřednictvím propojených seznamů. To znamená, že i když máte v seznamu miliony prvků, operace přidání nového prvku na začátek nebo konec seznamu se provádí v konstantním čase. Rychlost přidání nového prvku pomocí příkazu LPUSH do záhlaví seznamu s deseti prvky je stejná jako přidání prvku do záhlaví seznamu s 10 miliony prvků.

V naší aplikaci budeme ukládat tweety přijaté prostřednictvím API do seznamu nazvaného „tweety“. Použijeme LPUSH k odeslání nově přijatého tweetu do seznamu, ořízneme jej pomocí LTRIM, což omezí množství použitého místa na disku (protože zápis streamu může zabrat hodně místa), načteme nejnovější tweet pomocí LRANGE a odešleme jej na front-end, kde bude připojen k seznamu streamování.

Co je LPUSH, LTRIM a LRANGE?

Jedná se o sadu příkazů Redis, které se používají k přidávání dat do seznamu. Zde je stručný popis:

LPUSH

Vložte všechny zadané hodnoty na začátek seznamu uloženého v klíči. Pokud klíč neexistuje, vytvoří se před provedením operací push jako prázdný seznam. Když klíč obsahuje hodnotu, která není seznamem, vrátí se chyba.

redis> LPUSH mylist "world"(integer) 1redis> LPUSH mylist "hello"(integer) 2redis> LRANGE mylist 0 -11) "hello"2) "world"

LTRIM

Ořízněte existující seznam tak, aby obsahoval pouze zadaný rozsah prvků. Start i stop jsou indexy založené na nule, kde 0 je první prvek seznamu (hlava), 1 další prvek a tak dále.

redis> RPUSH můj seznam "jedna" (celé číslo) 1redis> RPUSH můj seznam "dva" (celé číslo) 2redis> RPUSH můj seznam "tři" (celé číslo) 3redis> LTRIM můj seznam 1 -1"OK"redis> LRANGE můj seznam 0 -11 ) "dva"2) "tři"

VELKÝ ROZSAH

Vrátí zadané prvky seznamu uloženého v klíči. Počáteční a koncové odchylky jsou indexy založené na nule, přičemž 0 je první prvek seznamu (hlava seznamu), 1 je další atd.

Tyto offsety mohou být také záporná čísla označující pozice od konce seznamu. Například -1 je poslední prvek seznamu, -2 předposlední a tak dále.

redis> RPUSH můj seznam "one"(integer) 1redis> RPUSH mylist "two"(integer) 2redis> RPUSH mylist "three"(integer) 3redis> LRANGE mylist 0 01) "one"redis> LRANGE mylist -3 21 ) "jedna" 2) "dva"3) "tři"

Sestavení aplikace

Naše demo vyžaduje jak front-end, tak back-end. Náš front-end je docela jednoduché textové pole s tlačítkem, které se použije ke spuštění streamu.

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

Jakmile obdržíme tweet z našeho back-endu, potřebujeme pomocnou funkci k vytvoření tweetového boxu:

 var _buildTweetBox =function(status) { var html =''; html +='
'; html +='
'; html +=' '; html +=' ' + status.user.name + ''; html +=' ';{101} html +='
';{101} html +='
'; html +='
' + status.user.screen_name + '
'; html +='

' + status.text + '

'; html +='
';{101} html +='
';{101} $('#oblast_tweets').prepend(html); $('#tweets_area').find('.tweet-single').first().fadeIn('slow');};

Potřebujeme také posluchače, který zastaví stream a zabrání přidávání dalších tweetů do seznamu streamů:

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);});

Přejděme na zadní stranu věcí a začněme psát naše /search API.

/** * API – Hledat */app.post('/search', function(req, res, next) { _searchTwitter(req.body.val); res.send({ status:'OK' } );});/** * Streamujte data z Twitteru pro vstupní text * * 1. Použijte Twitter streaming API ke sledování konkrétní hodnoty zadané uživatelem * 2. Jakmile máme data z Twitteru, přidejte je do Redis seznam pomocí LPUSH * 3. Po přidání do seznamu omezte seznam pomocí LTRIM, aby stream nepřetekal disk * 4. Pomocí LRANGE načtěte nejnovější tweet a odešlete jej do front-endu pomocí Socket.io * * @ param {String} val Řetězec dotazu * @return */var _searchTwitter =function(val) { twit.stream('stavy/filtr', {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); });}

Výše uvedený kód obsahuje jádro našeho back-endu. Jakmile obdržíme požadavek na /search, spustíme stream pomocí streamovacího rozhraní API Twitteru, které vrací objekt streamu.

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

Můžeme poslouchat objekt streamu pro klíč zvaný „data“, který nám pošle nový tweet, až bude k dispozici.

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

Objekt „data“ obsahuje tweet JSON, který může vypadat nějak takto (část odpovědi byla vynechána):

{ "created_at":"Středa 26. července 08:01:56 +0000 2017", "id":890119982641803300, "id_str":"890119982641803264", "text":"RT @FM \"Jim" Není lepší muž než Jeff Sessions a žádný větší zastánce...agendy [prezidenta #Trumpa].\"… ", "zdroj":"Twitter pro Android
", "zkrácený":nepravda, "in_reply_to_status_id":null, "in_reply_to_status_id_str":null, "in_reply_to_user_id":null, "in_reply_id_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":"Konzervativní patriot, vysloužilý voják, vysloužilý civilista DOD. chovatel dobytka, jezdec, dobrodruh. Lovin Life ! GO HOGS!!", "chráněno":false, "verified":false, "followers_count ":226, "friends_count":346, "listed_count":0, "favourites_count":3751, "statuses_count":1339, "created_at":"So 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_Cfill_pro_color":"Barva_postranního_profilu_DEF0":"Barva_postranního_profilu_DEF0":, "profile_text_color":"333333", "profile_use_background_image":true, "profile_image_url":"http://pbs.twimg.com/profile_images/883522005210943488/rqyyXlEXlEX_projpg"https://www.bsimage_projpg. twimg.com/profile_images/883522005210943488/rqyyXlEX_normal.jpg", "default_profile":true, "default_profile_image":false, "following":"null, "follow_request_sent":null":null 

Tuto odpověď ukládáme do seznamu Redis nazvaného „tweety“ pomocí LPUSH:

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

Jakmile je tweet uložen, ořízneme seznam pomocí LTRIM, abychom zachovali maximální počet tweetů (takže se místo na disku nezaplní):

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

Po oříznutí seznamu načteme nejnovější tweet pomocí LRANGE a odešleme jej do front-endu:

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

Vzhledem k tomu, že se jedná o ukázkovou aplikaci, musíme také stream po určité době ručně zničit, aby nepřestával zapisovat na disk:

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

A máte hotovo! Spusťte server pomocí npm start a užijte si streamování.

Ukázka aplikace je k dispozici zde: https://node-socket-redis-stream-tweet.herokuapp.com/

Pro nasazení této aplikace na Heroku se podívejte na jejich dokumenty:https://devcenter.heroku.com/categories/deployment

Celý zdrojový kód je k dispozici také na GitHubu, kde si ho můžete rozdělit a pracovat na něm: https://github.com/Scalegrid/code-samples/tree/sg-redis-node-socket-twitter-search/node-socket-redis -twitter-hashtags

Jako vždy, pokud postavíte něco úžasného, ​​napište nám o tom tweet @scalegridio.

Pokud potřebujete pomoc se správou a hostingem pro Redis™*, kontaktujte nás na adrese [email protected] pro další informace.


  1. Jak na to:Povolte ověřování a autorizaci uživatele v Apache HBase

  2. E11000 duplicitní klíčový chybový index v mongodb mongoose

  3. Analýza pomalých dotazů v MongoDB

  4. Jak používat $ regex v agregačním dotazu mongodb v rámci $match