{"id":19404314,"url":"https://github.com/hasithaishere/introduction-to-redis","last_synced_at":"2025-02-25T00:32:16.535Z","repository":{"id":96571968,"uuid":"44794613","full_name":"hasithaishere/Introduction-to-redis","owner":"hasithaishere","description":null,"archived":false,"fork":false,"pushed_at":"2015-10-23T09:06:48.000Z","size":1800,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-07T12:47:37.969Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hasithaishere.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-23T06:19:42.000Z","updated_at":"2015-12-12T07:42:16.000Z","dependencies_parsed_at":"2023-03-13T16:29:58.993Z","dependency_job_id":null,"html_url":"https://github.com/hasithaishere/Introduction-to-redis","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasithaishere%2FIntroduction-to-redis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasithaishere%2FIntroduction-to-redis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasithaishere%2FIntroduction-to-redis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasithaishere%2FIntroduction-to-redis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hasithaishere","download_url":"https://codeload.github.com/hasithaishere/Introduction-to-redis/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240581423,"owners_count":19824139,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T11:34:00.131Z","updated_at":"2025-02-25T00:32:16.503Z","avatar_url":"https://github.com/hasithaishere.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction to Redis\n\n## Install Redis in ubuntu\n\nTo install Redis in ubuntu first clone the this branch and run install_in_ubuntu/install.sh file using following command.\n\n```js\n\nsudo sh install.sh\n```\nAfter installation have been completed Redis automatically start as a service.\n\n## Using Redis Publish-Subscribe with Node.js\n\nTo use the Redis pub/sub mechanism with Node.js, the first thing you will want to do is select a native Redis client. The preferred Node client is the [node_redis](https://github.com/mranney/node_redis) package.\n\nThe first thing you want to do is run `npm install redis` to install the node package into your project. \n\nSecond, you want to require the node_redis project and create a Client for both the publisher and subscriber. Note, we are using the default client settings here. \n\n```js\n\nvar redis = require(\"redis\");\n\nvar pub = redis.createClient();\nvar sub = redis.createClient();\n```\n\nNext, you want to set event handlers to the client to handle receiving messages and subscribe to the right channel.\n\n```js\n\nsub.on(\"subscribe\", function(channel, count) {\n\tconsole.log(\"Subscribed to \" + channel + \". Now subscribed to \" + count + \" channel(s).\");\n});\n\nsub.on(\"message\", function(channel, message) {\n\tconsole.log(\"Message from channel \" + channel + \": \" + message);\n});\n\nsub.subscribe(\"analytics\");\n```\n\nNext, you want to set up the publisher to send messages on the channel.\n\n```js\npub.publish(\"analytics\", \"page_viewed\");\n```\n\nThat's all you need to use Redis pub/sub!\n\n# Scaling a Real-time Messaging Application with Pub/Sub\n\nBy itself it may be unclear why Redis' Pub/Sub feature is useful. However we can explain why this is so useful for scalability with a simple chat application. We'll be using Socket.IO and Node.js to do this application example but the architectural principal transcends languages.\n\nWe won't be going into much of the application details but if you want to learn more about the inner workings of Socket.IO and Node Express, check out one of our [previous MVAs](https://github.com/sayar/NodeMVA/tree/master/09_NodeChatroom).\n\n## Creating the Application\n\nFirst let's quickly build a chat application using the [Yeoman generator](http://yeoman.io). Yeoman allows us to quickly scaffold an app using a variety of technologies that work together. \n\nExecute these commands:\n\n```bash\nnpm install yo -g\nnpm npm install -g generator-socketio\nyo socketio\n# Answer all the questions Yeoman asks (we will call our app test-chat)\n# Npm May fail to install (you may need to run it with sudo). If so execute:\nnpm install\nnpm install bower -g\nbower install\n```\nNow run the application by executing:\n\n```bash\n# install grunt cli\nnpm install -g grunt-cli\n# star the app\ngrunt\n```\n\nAlright and if everything went well for you, your default web browser should have launched with the live chat app where you can send a message:\n\n![Alt text](http://gdurl.com/ObvE \"\")\n\nYou'll notice the debug output when you send a message:\n\n\n```bash\ndebug - websocket writing 5:::{\"name\":\"blast\",\"args\":[{\"msg\":\"\u003cspan style=\\\"color:red !important\\\"\u003esomeone connected\u003c/span\u003e\"}]}\n   info  - unhandled socket.io url\n   info  - unhandled socket.io url\n{ msg: 'test message' }\n   debug - websocket writing 5:::{\"name\":\"blast\",\"args\":[{\"msg\":\"test message\"}]}\n   debug - sending data ack packet\n   debug - websocket writing 6:::1\n   info  - unhandled socket.io url\n   info  - unhandled socket.io url\n\n```\n\n## Scaling the Application\n\n### The Problem\n\nNotice that multiple clients can chat with each other when they connect to the same server. This is a high-level look at the application messaging architecture:\n\n![Alt text](http://gdurl.com/tQxZ \"\")\n\nA client sends a message to everyone else connected to the server by dispatching a message to the server. Then the server broadcasts it to its connected clients.\n\nRunning locally we have 1 server, however when you roll out a service, you want more than just 1 instance of the server running. Say we add another Socket.IO server to scale the chat service:\n\n![Alt text](http://gdurl.com/o4Yq \"\")\n\nNow, the way things are, Client D would never get any messages from clients A B \nor C. \n\n### Creating the Messaging Application\n\nWe can try this out for real by just copying the application we made to another directory:\n\n```bash\n# copy the application directory to another\n$ cp -R test-chat test-chat2\n```\n\nNow change the port you run the application by modifying the top couple lines in the `Grunt.js` file generated to run on port `35728` and `1338`:\n\n`Grunt.js`:\n\n```js\nvar LIVERELOAD_PORT = 35728;\nvar RUNNING_PORT = 1338; // \u003c- if you change this, you need to change in public/js/app.js and recompile\n```\n\nNext, in `public/js/app.js` modify this first line of code to tell the browser to connect to the new port number we just set:\n\n`public/js/app.js`:\n\n```js\n// connect to our socket server\nvar socket = io.connect('http://127.0.0.1:1338/');\n```\n\nNotice, how we can't send a message from one window to the other:\n\n![Alt text](http://gdurl.com/NKdh \"\")\n\n#### Scaling With Redis\n\nA great way to solve this is by using Redis' pub/sub feature to facilitate messages between our Socket.IO servers. With this here's how our architecture looks:\n\n![Alt text](http://gdurl.com/gfum \"\")\n\nIn this scenario, client D can now receive a message from client A because the backend servers are connected with Redis.\n\nLet's actually implement this. Luckily the nice folks at Socket.IO has already created a [Socket.IO Redis adapter](http://npmjs.com/package/socket.io-redis) just for this use.\n\nIn our case we need to make the following changes for **each** version of the application. In the real-world deployment we wouldn't have to do this because we would have a load balancer in place.\n\nFirst, we have to install the Redis adapter and update the Socket.IO package. Execute this command to install the adapter:\n\n```bash\nnpm install socket.io-redis --save\n```\n\nAs of writing this the Yeoman Socket.IO generator uses an outdated version of the package. Change your `package.json` dependencies to look like this:\n\n```json\n\"dependencies\": {\n    \"ejs\": \"~0.8.5\",\n    \"express\": \"~3.4.6\",\n    \"express-device\": \"~0.3.7\",\n    \"socket.io\": \"~1.3.5\",\n    \"socket.io-redis\": \"^0.1.4\"\n  }\n```\n\nNow we need to tell the Node.js servers to use Redis.  Change `server.js` first few `require` statements to use the Redis adapter:\n\n`server.js`\n\n```js\nvar server = require('http').createServer(app);\nvar io = require('socket.io')(server);\nvar redis = require('socket.io-redis');\nio.adapter(redis({ host: 'localhost', port: 6379 }));\n```\n\nRemember all these changes need to be made to **both** versions of your app to make this demo work.\n\nNow run both applications by using two terminal windows and executing `grunt`. Navigate one browser to `http://localhost:1338` and the other to `http://localhost:1337`.\n\nNotice now, we can send messages between the windows, even though they are both connected to two different Socket.IO servers:\n\n![Alt text](http://gdurl.com/DDa0 \"\")\n\nRedis allows us to horizontally scale our service allowing multiple servers to publish and subscribe to messages so that users connected to different instances of the app can communicate.\n\nWe won't actually do this in our walkthrough but when you deploy to [Azure](http://azure.com) or any other cloud service your final architecture would have a load balancer, which logically would look like a single server to your clients. Azure abstracts the load balancer from you and makes it easy to setup load balancing without having to do any low-level web server configuration.\n\nHere's what this architecture would look like in an actual cloud deployment:\n\n![Alt text](http://gdurl.com/StiX \"\")\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhasithaishere%2Fintroduction-to-redis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhasithaishere%2Fintroduction-to-redis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhasithaishere%2Fintroduction-to-redis/lists"}