diff --git a/README.md b/README.md index a23cc18..13a1937 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Pop-up store demo using RedisTimeSeries, RedisGears and Redis plugins for Grafana -![Pop-up](https://github.com/RedisTimeSeries/redis-pop-up-store/blob/master/images/pop-up.gif) +![Pop-up](https://github.com/RedisTimeSeries/redis-pop-up-store/blob/master/images/pop-up-dashboard.png) [![Grafana 8](https://img.shields.io/badge/Grafana-8-orange)](https://www.grafana.com) [![Redis Data Source](https://img.shields.io/badge/dynamic/json?color=blue&label=Redis%20Data%20Source&query=%24.version&url=https%3A%2F%2Fgrafana.com%2Fapi%2Fplugins%2Fredis-datasource)](https://grafana.com/grafana/plugins/redis-datasource) [![Redis Application](https://img.shields.io/badge/dynamic/json?color=blue&label=Redis%20Application&query=%24.version&url=https%3A%2F%2Fgrafana.com%2Fapi%2Fplugins%2Fredis-app)](https://grafana.com/grafana/plugins/redis-app) -The Pop-up store demo is using [Redis Streams](https://redis.io/topics/streams-intro), [RedisTimeSeries](https://oss.redis.com/redistimeseries/), [RedisGears](https://oss.redis.com/redisgears/) and [Redis plugins](https://redisgrafana.github.io) to visualize data pipeline in Grafana. +The Pop-up store is using [Redis Streams](https://redis.io/topics/streams-intro), [RedisTimeSeries](https://oss.redis.com/redistimeseries/), [RedisGears](https://oss.redis.com/redisgears/) and [Redis plugins](https://redisgrafana.github.io) to visualize data pipeline in Grafana. ## How it works @@ -51,29 +51,25 @@ gb.register(prefix='queue:orders', batch=3, trimStream=True) - Grafana query streams and Time-Series keys every 5 seconds to display samples using Grafana plugins. -## What is displayed on Grafana dashboard +## Demo -- `Product Available` - the value of `product` key -- `Customers Ordering` - length of `queue:customers` -- `Orders Processing` - length of `queue:orders` -- `Orders Completed` - length of `queue:complete` -- `Customers Overflow` - the difference between customer submitted orders and orders completed -- `Customers Ordering` - change of `queue:customers` length -- `Orders In Queue` - change of `queue:orders` length -- `Completed Flow` - how many orders processed +Demo is available on [demo.volkovlabs.io](https://demo.volkovlabs.io): + +- [Redis Overview dashboard](https://demo.volkovlabs.io/d/TgibHBv7z/redis-overview?orgId=1&refresh=1h) +- [Pop-up Store dashboard](https://demo.volkovlabs.io/d/0LC0Sm7Ml/pop-up-store?orgId=1) ## Requirements - [Docker](https://docker.com) to start Redis and Grafana. - [Node.js](https://nodejs.org) to run simulation script. -## Start Redis with RedisTimeSeries and RedisGears modules installed and Grafana +## Start Redis with RedisTimeSeries, RedisGears modules installed and Grafana ``` npm run start ``` -## Register [StreamReaders](https://oss.redis.com/redisgears/readers.html#streamreader) +## Register RedisGears functions Install Readers to add Time-Series and complete orders @@ -81,9 +77,9 @@ Install Readers to add Time-Series and complete orders npm run register ``` -## Install [ioredis](https://github.com/luin/ioredis) module and run simulation +## Install [ioredis](https://github.com/luin/ioredis) module and start simulation -Script `pop-up-store.js` will add customers to stream `queue:customers` and their orders to `queue:orders`. +Script `pop-up-store.js` will add customers to stream `queue:customers` and their orders to the `orders` keys. ``` npm run simulation diff --git a/gears-execute.sh b/gears-execute.sh deleted file mode 100755 index bc9c571..0000000 --- a/gears-execute.sh +++ /dev/null @@ -1,5 +0,0 @@ -# Install StreamReader to add Queue to Time-Series -cat gears/timeseries.py | docker exec -i redis redis-cli -x RG.PYEXECUTE - -# Install StreamReader to complete orders -cat gears/complete.py | docker exec -i redis redis-cli -x RG.PYEXECUTE diff --git a/gears/complete.py b/gears/orders.py similarity index 66% rename from gears/complete.py rename to gears/orders.py index 290bda4..79b49be 100644 --- a/gears/complete.py +++ b/gears/orders.py @@ -5,8 +5,12 @@ def complete(x): execute('XDEL', 'queue:customers', x['value']['customer']) execute('DECR', 'product') + product = execute('GET', 'product') + if int(product) < 1000: + execute('SET', 'product', 10000) + # Stream Reader for Orders queue gb = GearsBuilder('StreamReader') gb.map(complete) -gb.register(prefix='queue:orders', batch=3, trimStream=True) +gb.register(prefix='orders', batch=3, trimStream=True) diff --git a/images/pop-up-dashboard.png b/images/pop-up-dashboard.png new file mode 100644 index 0000000..5ae0c6d Binary files /dev/null and b/images/pop-up-dashboard.png differ diff --git a/images/pop-up.gif b/images/pop-up.gif deleted file mode 100644 index 515e495..0000000 Binary files a/images/pop-up.gif and /dev/null differ diff --git a/package.json b/package.json index 703b31b..bc4a1ce 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "name": "redis-pop-up-store", "scripts": { "redis-cli": "docker exec -it redis redis-cli", - "register": "./gears-execute.sh && docker exec -it redis redis-cli RG.DUMPREGISTRATIONS", + "register": "./register.sh && docker exec -it redis redis-cli RG.DUMPREGISTRATIONS", "simulation": "npm i; node src/pop-up-store.js", "start": "docker-compose pull && docker-compose up", "stop": "docker-compose down", diff --git a/provisioning/dashboards/pop-up-streaming.json b/provisioning/dashboards/pop-up-streaming.json deleted file mode 100644 index 71eb118..0000000 --- a/provisioning/dashboards/pop-up-streaming.json +++ /dev/null @@ -1,614 +0,0 @@ -{ - "__inputs": [], - "__requires": [ - { - "type": "panel", - "id": "gauge", - "name": "Gauge", - "version": "" - }, - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "8.2.0" - }, - { - "type": "datasource", - "id": "redis-datasource", - "name": "Redis", - "version": "1.5.0" - }, - { - "type": "panel", - "id": "stat", - "name": "Stat", - "version": "" - }, - { - "type": "panel", - "id": "timeseries", - "name": "Time series", - "version": "" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "gnetId": null, - "graphTooltip": 0, - "id": null, - "iteration": 1633981078325, - "links": [], - "liveNow": false, - "panels": [ - { - "datasource": "$redis", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "max": 10000, - "min": 0, - "noValue": "0", - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "dark-red", - "value": null - }, - { - "color": "dark-yellow", - "value": 1000 - }, - { - "color": "dark-green", - "value": 5000 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 5, - "w": 3, - "x": 0, - "y": 0 - }, - "id": 4, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": ["mean"], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "text": {} - }, - "pluginVersion": "8.2.0", - "targets": [ - { - "command": "get", - "keyName": "product", - "query": "", - "refId": "A", - "streaming": true, - "streamingDataType": "DataFrame", - "type": "command" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Product Available", - "type": "gauge" - }, - { - "datasource": "$redis", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "graph": false, - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "dark-green", - "value": null - }, - { - "color": "dark-yellow", - "value": 50 - }, - { - "color": "dark-red", - "value": 100 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 11, - "w": 9, - "x": 3, - "y": 0 - }, - "id": 2, - "options": { - "legend": { - "calcs": [], - "displayMode": "hidden", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "pluginVersion": "7.5.1", - "targets": [ - { - "command": "xlen", - "keyName": "queue:customers", - "query": "", - "refId": "A", - "streaming": true, - "type": "command" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Customers Ordering", - "type": "timeseries" - }, - { - "datasource": "$redis", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "graph": false, - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "links": [], - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 11, - "w": 12, - "x": 12, - "y": 0 - }, - "id": 13, - "options": { - "legend": { - "calcs": [], - "displayMode": "hidden", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "pluginVersion": "7.5.1", - "targets": [ - { - "aggregation": "", - "bucket": 5000, - "command": "ts.get", - "keyName": "ts:enqueue:queue:customers", - "legend": "Customers", - "query": "", - "refId": "A", - "streaming": true, - "streamingDataType": "TimeSeries", - "type": "timeSeries" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Customers Overflow", - "type": "timeseries" - }, - { - "datasource": "$redis", - "fieldConfig": { - "defaults": { - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "dark-blue", - "value": null - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 3, - "x": 0, - "y": 5 - }, - "id": 15, - "options": { - "colorMode": "background", - "graphMode": "area", - "justifyMode": "center", - "orientation": "auto", - "reduceOptions": { - "calcs": ["mean"], - "fields": "", - "values": false - }, - "text": {}, - "textMode": "auto" - }, - "pluginVersion": "8.2.0", - "targets": [ - { - "command": "xlen", - "keyName": "queue:complete", - "query": "", - "refId": "A", - "streaming": true, - "streamingDataType": "TimeSeries", - "type": "command" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Orders Completed", - "type": "stat" - }, - { - "datasource": "$redis", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 11 - }, - "id": 8, - "title": "Orders", - "type": "row" - }, - { - "datasource": "$redis", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "graph": false, - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "dark-green", - "value": null - }, - { - "color": "dark-yellow", - "value": 50 - }, - { - "color": "dark-red", - "value": 100 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 13, - "w": 12, - "x": 0, - "y": 12 - }, - "id": 3, - "options": { - "legend": { - "calcs": [], - "displayMode": "hidden", - "placement": "bottom" - }, - "tooltip": { - "mode": "multi" - } - }, - "pluginVersion": "7.5.1", - "targets": [ - { - "command": "xlen", - "keyName": "queue:orders", - "query": "", - "refId": "A", - "streaming": true, - "streamingDataType": "TimeSeries", - "type": "command" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "In Queue", - "type": "timeseries" - }, - { - "datasource": "$redis", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "graph": false, - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "decimals": 0, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 13, - "w": 12, - "x": 12, - "y": 12 - }, - "id": 19, - "options": { - "graph": {}, - "legend": { - "calcs": [], - "displayMode": "hidden", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "pluginVersion": "7.5.1", - "targets": [ - { - "command": "ts.get", - "keyName": "ts:enqueue:queue:complete", - "legend": "Orders", - "query": "", - "refId": "A", - "streaming": true, - "type": "timeSeries" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Completed Flow", - "type": "timeseries" - } - ], - "refresh": "", - "schemaVersion": 31, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "selected": false, - "text": "Redis", - "value": "Redis" - }, - "description": null, - "error": null, - "hide": 0, - "includeAll": false, - "label": "Redis", - "multi": false, - "name": "redis", - "options": [], - "query": "redis-datasource", - "queryValue": "", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "type": "datasource" - } - ] - }, - "time": { - "from": "now-5m", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Pop-up (Real-time)", - "uid": "0LC0Sm7Ml", - "version": 1 -} diff --git a/provisioning/dashboards/pop-up.json b/provisioning/dashboards/pop-up.json index 238ed5a..f378649 100644 --- a/provisioning/dashboards/pop-up.json +++ b/provisioning/dashboards/pop-up.json @@ -11,7 +11,7 @@ "type": "grafana", "id": "grafana", "name": "Grafana", - "version": "8.2.0" + "version": "8.2.1" }, { "type": "datasource", @@ -19,12 +19,24 @@ "name": "Redis", "version": "1.5.0" }, + { + "type": "panel", + "id": "redis-latency-panel", + "name": "Redis Latency", + "version": "" + }, { "type": "panel", "id": "stat", "name": "Stat", "version": "" }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + }, { "type": "panel", "id": "timeseries", @@ -56,7 +68,7 @@ "gnetId": null, "graphTooltip": 0, "id": null, - "iteration": 1633981297746, + "iteration": 1634046481196, "links": [], "liveNow": false, "panels": [ @@ -109,7 +121,7 @@ "showThresholdMarkers": true, "text": {} }, - "pluginVersion": "8.2.0", + "pluginVersion": "8.2.1", "targets": [ { "command": "get", @@ -311,6 +323,7 @@ "datasource": "$redis", "fieldConfig": { "defaults": { + "decimals": 0, "mappings": [], "min": 0, "thresholds": { @@ -335,7 +348,7 @@ "options": { "colorMode": "background", "graphMode": "area", - "justifyMode": "center", + "justifyMode": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["mean"], @@ -345,7 +358,7 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "8.2.0", + "pluginVersion": "8.2.1", "targets": [ { "command": "xlen", @@ -364,10 +377,6 @@ }, { "datasource": "$redis", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, "gridPos": { "h": 1, "w": 24, @@ -456,7 +465,7 @@ "targets": [ { "command": "xlen", - "keyName": "queue:orders", + "keyName": "orders", "query": "", "refId": "A", "streaming": true, @@ -559,9 +568,470 @@ "timeShift": null, "title": "Completed Flow", "type": "timeseries" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 17 + }, + "id": 23, + "panels": [], + "title": "Redis Performance", + "type": "row" + }, + { + "datasource": "$redis", + "fieldConfig": { + "defaults": { + "custom": { + "align": null, + "displayMode": "auto", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 176 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "PD" + }, + "properties": [ + { + "id": "custom.width", + "value": 242 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Triggered" + }, + "properties": [ + { + "id": "custom.width", + "value": 90 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Mode" + }, + "properties": [ + { + "id": "custom.width", + "value": 92 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Success" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Failures" + }, + "properties": [ + { + "id": "custom.width", + "value": 84 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Aborted" + }, + "properties": [ + { + "id": "custom.width", + "value": null + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Status" + }, + "properties": [ + { + "id": "custom.width", + "value": 94 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Reader" + }, + "properties": [ + { + "id": "custom.width", + "value": 154 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Args" + }, + "properties": [ + { + "id": "custom.width", + "value": 147 + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 21, + "options": { + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "command": "rg.dumpregistrations", + "query": "", + "refId": "A", + "streaming": true, + "streamingDataType": "DataFrame", + "type": "gears" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Registrations", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "PD": true, + "desc": true, + "id": true + }, + "indexByName": { + "PD": 4, + "args": 1, + "desc": 3, + "id": 2, + "lastError": 10, + "mode": 5, + "numAborted": 9, + "numFailures": 8, + "numSuccess": 7, + "numTriggered": 6, + "reader": 0, + "status": 11 + }, + "renameByName": { + "args": "Args", + "lastError": "Last Error", + "mode": "Mode", + "numAborted": "Aborted", + "numFailures": "Failures", + "numSuccess": "Success", + "numTriggered": "Triggered", + "reader": "Reader", + "status": "Status" + } + } + } + ], + "type": "table" + }, + { + "datasource": "$redis", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 51, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 25, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.0", + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "stats", + "streaming": true, + "streamingCapacity": 1000, + "streamingInterval": 1000, + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Ops/sec", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["instantaneous_ops_per_sec", "#time"] + } + } + } + ], + "type": "timeseries" + }, + { + "datasource": "$redis", + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 27 + }, + "id": 29, + "options": { + "hideZero": true, + "interval": 1000, + "maxItemsPerSeries": 300, + "viewMode": "Graph" + }, + "pluginVersion": "7.3.7", + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "type": "redis-latency-panel" + }, + { + "datasource": "$redis", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 52, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 27, + "options": { + "legend": { + "calcs": ["mean", "lastNotNull"], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.0", + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "memory", + "streaming": true, + "streamingCapacity": 1000, + "streamingInterval": 1000, + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory Usage", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": [ + "used_memory", + "used_memory_rss", + "used_memory_peak", + "total_system_memory", + "used_memory_lua", + "maxmemory", + "#time" + ] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": {}, + "renameByName": { + "maxmemory": "Memory Limit", + "total_system_memory": "Total System Memory", + "used_memory": "Used Memory", + "used_memory_lua": "Used Memory, LUA", + "used_memory_peak": "Used Memory, Peak", + "used_memory_rss": "Used Memory, RSS" + } + } + } + ], + "type": "timeseries" } ], - "refresh": "", + "refresh": false, "schemaVersion": 31, "style": "dark", "tags": [], @@ -608,7 +1078,7 @@ ] }, "timezone": "", - "title": "Pop-up (Real-time)", + "title": "Pop-up Store", "uid": "0LC0Sm7Ml", "version": 1 } diff --git a/register.sh b/register.sh new file mode 100755 index 0000000..256b4f0 --- /dev/null +++ b/register.sh @@ -0,0 +1,5 @@ +# Install StreamReader for Time-Series +cat gears/timeseries.py | docker exec -i redis redis-cli -x RG.PYEXECUTE + +# Install StreamReader for Orders +cat gears/orders.py | docker exec -i redis redis-cli -x RG.PYEXECUTE \ No newline at end of file diff --git a/src/pop-up-store.js b/src/pop-up-store.js index 136a2b3..55a72ce 100644 --- a/src/pop-up-store.js +++ b/src/pop-up-store.js @@ -35,12 +35,12 @@ function submitOrder(err, result) { } /** - * Waiting to customer to submit order + * Waiting for customer to submit order * * @see https://redis.io/commands/xadd */ setTimeout(function () { - redis.xadd("queue:orders", "*", "id", genId(), "customer", result); + redis.xadd("orders", "*", "id", genId(), "customer", result); }, Math.floor(Math.random() * 1000)); } @@ -54,9 +54,9 @@ function newCustomer() { redis.xadd("queue:customers", "*", "id", genId(), submitOrder); /** - * Waiting for next + * Waiting for the next */ - setTimeout(newCustomer, Math.floor(Math.random() * 100)); + setTimeout(newCustomer, Math.floor(Math.random() * 1000)); } /**