赞
踩
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
查看Redis命令大全 →
访问Redis论坛 →
Redis使用内存计算器 →
最近工作中使用Nodejs编写后端程序操作redis,从redis缓存中获取对应的站房的监测环境数据,然后再提供http和websocket接口,提供给前端获取并实时展示。刚开始使用的是node-redis这个库,其对应的github地址是:https://github.com/NodeRedis/node-redis,npm官网地址是:https://www.npmjs.com/package/node-redis,后来发现了国内阿里的一个Nodejs的redis库,其npm官网地址是:https://www.npmjs.com/package/ioredis,ioredis库比node-redis更新维护快并且比较新,所以就改用ioredis库了。
从redis缓存中获取对应的站房的监测环境数据,然后再提供http接口,返回所有的站房监测数据,获取可以根据某个站点编码返回对应的站房监测数据
根据数据类型(用datatype表示),站房环境数据的数据缓存结构的datatype为env
所有的数据存储都是以key-value键值对形式存储在Redis中,编码为UTF8。数据存储的key结构都是一致的,形式为
“数据类型:解析类型:站点编码:日期(yyyyMMdd):时间(HHmmss)”
数据存储value键都是以hash方式存储,其中field为数据标识, value为数据值。
监测数据的field根据解析类型有两种形式,如下
站房环境数据结构在redis中存储的形式如下图所示:
使用npm或cnpm安装依赖
$ npm install node-redis
相关的nodejs代码node_redis_client_demo.js如下所示:
var express = require('express'); var app = express(); var http = require('http').Server(app); var port = process.env.PORT || 3001; const redis = require('redis') http.listen(port, function(){ console.log('listening on localhost:' + port); }) const redisClient = redis.createClient({ host: '127.0.0.1', port: 6379, password: '1234', db: 3 }); // 站房环境数据信息 const envData = { CylinderGasPress3: 'CylinderGasPress3|9.05||EP126|', IA: 'IA|7.80||EP117|', SmokeState: 'SmokeState|0||EP113|', CylinderGasPress: 'CylinderGasPress|7.58||EP124|', StationHum: 'StationHum|39.59||EP121|', VB: 'VB|225.24||EP115|', PipeTemp: 'PipeTemp|32.50||EP122|', VC: 'VC|224.05||EP116|', IB: 'IB|7.34||EP118|', SwitchState: 'SwitchState|1||EP111|', PipeHum: 'PipeHum|20.10||EP123|', VA: 'VA|225.93||EP114|', Water1: 'Water1|1||EP112|', StationTemp: 'StationTemp|28.60||EP120|', AlarmState: 'AlarmState|0||EP110|', CylinderGasPress2: 'CylinderGasPress2|6.33||EP125|', IC: 'IC|2.92||EP119|' } // 站房环境信息 var lastenvBuff = {}; // 写入Javascript(JSON)对象 // 站房环境监测数据(测试3个站点) redisClient.hmset('env:hbxd:420100401:20200409:100901', envData, function(err){ console.log(err) }) redisClient.hmset('env:hbxd:421000405:20200409:172000', envData, function(err){ console.log(err) }) redisClient.hmset('env:hbxd:422800408:20200409:172800', envData, function(err){ console.log(err) }) // 读取Javscript(JSON)对象 // redisClient.hgetall('env:*', function (err, object) { // console.log(object) // }) redisClient.keys('env:*', function(err,keys){ console.log(keys) // 打印所有的站房环境数据的redis key console.log(keys); // 遍历站房环境数据的keys数组 for (let i = 0; i < keys.length; i++) { // 从keys中解析得到站点编码、数据时间等信息 const strArrayTemp = keys[i].split(':'); const strstcode = strArrayTemp[2]; const strdataTime = strArrayTemp[3] + strArrayTemp[4]; // 将数据时间从 20200228135130 转换成 2020-02-28 13:51:30 的格式 let year = strdataTime.substr(0, 4); let month = strdataTime.substr(4, 2); let day = strdataTime.substr(6, 2); let hour = strdataTime.substr(8, 2); let minute = strdataTime.substr(10, 2); let second = strdataTime.substr(12, 2); // let date = Date(); //timestamp = moment().format('YYYY-MM-DD HH:mm:ss'); var strTimestamp = year + '-' + month + '-' + day + ' ' + hour + ':' + minute+ ':' + second; // 根据每一个hash key获取到对应的filed和value // hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value redisClient.hgetall(keys[i], function(err,obj) { var envMonitorArr = []; // 当前站点的站房监测因子信息数组 console.log('第' + (i+1) + '个站点的站点编码为:' + strstcode + ',数据时间为:' + strTimestamp); // 遍历某个站点的所有站房监测信息 for (var pkey in obj) { // console.log('field:' + pkey + ',value:' + obj[pkey]); // 从value中解析出监测因子编码,数值,标记位,单位 var strValArray = obj[pkey].split('|'); var sValue = strValArray[1]; var strMark = strValArray[2]; var strParamCode = strValArray[3]; var strUnit = strValArray[4]; console.log('监测因子编码:' + strParamCode + ',数值:' + sValue + ',标记位:' + (strMark ? strMark: 'N')); // 将站房监测因子添加到监测因子数组中 envMonitorArr.push({ 'code': strParamCode, 'value': sValue, 'mark': strMark ? strMark: 'N' }) } var jsonObj = { 'stcode': strstcode, 'time': strdataTime, 'envList': envMonitorArr } // 缓存每个站点的站房的最新数据 var env_data_arr = []; env_data_arr.push(Object.assign({}, jsonObj)); // 遍历站房缓存数据数组 for (var ii = 0; ii < env_data_arr.length; ii++) { var iitem = env_data_arr[ii]; console.log('站房监测信息:' + JSON.stringify(iitem)); var stacode = iitem.stcode; if (!(stacode in lastenvBuff)) { lastenvBuff[stacode] = {'stcode': stacode, 'time': strTimestamp, 'envList': iitem.envList}; } else { if (strdataTime > lastenvBuff[stacode].time) { lastenvBuff[stacode] = {'stcode': stacode, 'time': strTimestamp, 'envList': iitem.envList}; } } } // 打印当前所有站点的站房环境信息 console.log(JSON.stringify(lastenvBuff)) }) } }) // 获取某个站点的最新的站房环境数据 app.get('/api/envData/:stcode', function (req, res) { console.log(req.params) // 获取客户端传过来的站点编码 var stcode = req.params.stcode // 以站点编码为key,返回缓存中的历史报警记录 res.send(lastenvBuff[stcode]); }); // 获取当前所有站点的站房环境数据 app.get('/api/allEnvData/', function (req, res) { res.send(lastenvBuff); });
使用npm或者cnpm安装ioredis库
$ npm install ioredis
对应的noejs代码ioredis_client_demo.js如下:
var express = require('express'); var app = express(); var http = require('http').Server(app); var port = process.env.PORT || 3001; http.listen(port, function(){ console.log('listening on localhost:' + port); }) const Redis = require("ioredis"); // redis配置 const redisConfig = { host: "127.0.0.1", // Redis host port: 7001, // Redis port password: "1234", db: 4, retryStrategy: function(times){ return Math.min(times * 50, 5000) }, // enableOfflineQueue: false } const redisClient = new Redis(redisConfig); // uses defaults unless given configuration object // 站房环境数据信息 const envData = { CylinderGasPress3: 'CylinderGasPress3|9.05||EP126|', IA: 'IA|7.80||EP117|', SmokeState: 'SmokeState|0||EP113|', CylinderGasPress: 'CylinderGasPress|7.58||EP124|', StationHum: 'StationHum|39.59||EP121|', VB: 'VB|225.24||EP115|', PipeTemp: 'PipeTemp|32.50||EP122|', VC: 'VC|224.05||EP116|', IB: 'IB|7.34||EP118|', SwitchState: 'SwitchState|1||EP111|', PipeHum: 'PipeHum|20.10||EP123|', VA: 'VA|225.93||EP114|', Water1: 'Water1|1||EP112|', StationTemp: 'StationTemp|28.60||EP120|', AlarmState: 'AlarmState|0||EP110|', CylinderGasPress2: 'CylinderGasPress2|6.33||EP125|', IC: 'IC|2.92||EP119|' } // 站房环境信息 var lastenvBuff = {}; // 写入Javascript(JSON)对象 // 站房环境监测数据(测试3个站点) redisClient.hmset('env:hbxd:420100401:20200409:100901', envData, function(err){ console.log(err) }) redisClient.hmset('env:hbxd:421000405:20200409:172000', envData, function(err){ console.log(err) }) redisClient.hmset('env:hbxd:422800408:20200409:172800', envData, function(err){ console.log(err) }) redisClient.on('connect', () => { console.log('成功连接到Redis') // 获取站房环境数据的所有key列表 redisClient.keys('env:hbxd:*', function(err,keys){ // 打印所有的站房环境数据的redis key console.log(keys); envKeys = keys; // 遍历站房环境数据的keys数组 for (let i = 0; i < keys.length; i++) { // 从keys中解析得到站点编码、数据时间等信息 const strArrayTemp = keys[i].split(':'); const strstcode = strArrayTemp[2]; const strdataTime = strArrayTemp[3] + strArrayTemp[4]; // 将数据时间从 20200228135130 转换成 2020-02-28 13:51:30 的格式 let year = strdataTime.substr(0, 4); let month = strdataTime.substr(4, 2); let day = strdataTime.substr(6, 2); let hour = strdataTime.substr(8, 2); let minute = strdataTime.substr(10, 2); let second = strdataTime.substr(12, 2); // let date = Date(); //timestamp = moment().format('YYYY-MM-DD HH:mm:ss'); var strTimestamp = year + '-' + month + '-' + day + ' ' + hour + ':' + minute+ ':' + second; // 根据每一个hash key获取到对应的filed和value // hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value redisClient.hgetall(keys[i], function(err,obj) { var envMonitorArr = []; // 当前站点的站房监测因子信息数组 console.log('第' + (i+1) + '个站点的站点编码为:' + strstcode + ',数据时间为:' + strTimestamp); // 遍历某个站点的所有站房监测信息 for (var pkey in obj) { // console.log('field:' + pkey + ',value:' + obj[pkey]); // 从value中解析出监测因子编码,数值,标记位,单位 var strValArray = obj[pkey].split('|'); var sValue = strValArray[1]; var strMark = strValArray[2]; var strParamCode = strValArray[3]; var strUnit = strValArray[4]; console.log('监测因子编码:' + strParamCode + ',数值:' + sValue + ',标记位:' + (strMark ? strMark: 'N')); // 将站房监测因子添加到监测因子数组中 envMonitorArr.push({ 'code': strParamCode, 'value': sValue, 'mark': strMark ? strMark: 'N' }) } var jsonObj = { 'stcode': strstcode, 'time': strdataTime, 'envList': envMonitorArr } // 缓存每个站点的站房的最新数据 var env_data_arr = []; env_data_arr.push(Object.assign({}, jsonObj)); // 遍历站房缓存数据数组 for (var ii = 0; ii < env_data_arr.length; ii++) { var iitem = env_data_arr[ii]; console.log('站房监测信息:' + JSON.stringify(iitem)); var stacode = iitem.stcode; if (!(stacode in lastenvBuff)) { lastenvBuff[stacode] = {'stcode': stacode, 'time': strTimestamp, 'envList': iitem.envList}; } else { if (strdataTime > lastenvBuff[stacode].time) { lastenvBuff[stacode] = {'stcode': stacode, 'time': strTimestamp, 'envList': iitem.envList}; } } } // 打印当前所有站点的站房环境信息 // console.log(JSON.stringify(lastenvBuff)) }) } }) }) // 获取某个站点的最新的站房环境数据 app.get('/api/envData/:stcode', function (req, res) { console.log(req.params) // 获取客户端传过来的站点编码 var stcode = req.params.stcode // 以站点编码为key,返回缓存中的历史报警记录 res.send(lastenvBuff[stcode]); }); // 获取当前所有站点的站房环境数据 app.get('/api/allEnvData/', function (req, res) { res.send(lastenvBuff); });
保证在对应系统中安装好express和ioredis、node-redis依赖后,使用node ioredis_client_demo.js执行对应的nodejs后台程序,在localhost:3001端口上监听,提供http服务。
在浏览器中输入路径:http://localhost:3001/api/allEnvData/
得到当前所有站点的站房环境数据,如下图所示:
完整的JSON数据如下所示:
{ 420100401: { stcode: "420100401", time: "2020-04-09 17:28:00", envList: [ { code: "EP126", value: "9.05", mark: "N" }, { code: "EP117", value: "7.80", mark: "N" }, { code: "EP113", value: "0", mark: "N" }, { code: "EP124", value: "7.58", mark: "N" }, { code: "EP121", value: "39.59", mark: "N" }, { code: "EP115", value: "225.24", mark: "N" }, { code: "EP122", value: "32.50", mark: "N" }, { code: "EP116", value: "224.05", mark: "N" }, { code: "EP118", value: "7.34", mark: "N" }, { code: "EP111", value: "1", mark: "N" }, { code: "EP123", value: "20.10", mark: "N" }, { code: "EP114", value: "225.93", mark: "N" }, { code: "EP112", value: "1", mark: "N" }, { code: "EP120", value: "28.60", mark: "N" }, { code: "EP110", value: "0", mark: "N" }, { code: "EP125", value: "6.33", mark: "N" }, { code: "EP119", value: "2.92", mark: "N" } ] }, 421000405: { stcode: "421000405", time: "2020-04-09 17:28:00", envList: [ { code: "EP126", value: "9.05", mark: "N" }, { code: "EP117", value: "7.80", mark: "N" }, { code: "EP113", value: "0", mark: "N" }, { code: "EP124", value: "7.58", mark: "N" }, { code: "EP121", value: "39.59", mark: "N" }, { code: "EP115", value: "225.24", mark: "N" }, { code: "EP122", value: "32.50", mark: "N" }, { code: "EP116", value: "224.05", mark: "N" }, { code: "EP118", value: "7.34", mark: "N" }, { code: "EP111", value: "1", mark: "N" }, { code: "EP123", value: "20.10", mark: "N" }, { code: "EP114", value: "225.93", mark: "N" }, { code: "EP112", value: "1", mark: "N" }, { code: "EP120", value: "28.60", mark: "N" }, { code: "EP110", value: "0", mark: "N" }, { code: "EP125", value: "6.33", mark: "N" }, { code: "EP119", value: "2.92", mark: "N" } ] }, 422800408: { stcode: "422800408", time: "2020-04-09 17:28:00", envList: [ { code: "EP126", value: "9.05", mark: "N" }, { code: "EP117", value: "7.80", mark: "N" }, { code: "EP113", value: "0", mark: "N" }, { code: "EP124", value: "7.58", mark: "N" }, { code: "EP121", value: "39.59", mark: "N" }, { code: "EP115", value: "225.24", mark: "N" }, { code: "EP122", value: "32.50", mark: "N" }, { code: "EP116", value: "224.05", mark: "N" }, { code: "EP118", value: "7.34", mark: "N" }, { code: "EP111", value: "1", mark: "N" }, { code: "EP123", value: "20.10", mark: "N" }, { code: "EP114", value: "225.93", mark: "N" }, { code: "EP112", value: "1", mark: "N" }, { code: "EP120", value: "28.60", mark: "N" }, { code: "EP110", value: "0", mark: "N" }, { code: "EP125", value: "6.33", mark: "N" }, { code: "EP119", value: "2.92", mark: "N" } ] } }
在浏览器中输入路径:http://localhost:3001/api/envData/421000405
得到站点421000405的站房环境数据,如下图所示:
对应的完整的json数据如下所示:
{ stcode: "421000405", time: "2020-04-09 17:28:00", envList: [ { code: "EP126", value: "9.05", mark: "N" }, { code: "EP117", value: "7.80", mark: "N" }, { code: "EP113", value: "0", mark: "N" }, { code: "EP124", value: "7.58", mark: "N" }, { code: "EP121", value: "39.59", mark: "N" }, { code: "EP115", value: "225.24", mark: "N" }, { code: "EP122", value: "32.50", mark: "N" }, { code: "EP116", value: "224.05", mark: "N" }, { code: "EP118", value: "7.34", mark: "N" }, { code: "EP111", value: "1", mark: "N" }, { code: "EP123", value: "20.10", mark: "N" }, { code: "EP114", value: "225.93", mark: "N" }, { code: "EP112", value: "1", mark: "N" }, { code: "EP120", value: "28.60", mark: "N" }, { code: "EP110", value: "0", mark: "N" }, { code: "EP125", value: "6.33", mark: "N" }, { code: "EP119", value: "2.92", mark: "N" } ] }
[redis中文文档](http://www.redis.cn/documentation.html)
node-redis
A high performance Node.js Redis client. http://redis.js.org/
https://github.com/NodeRedis/node-redis
ioredis
A robust, performance-focused and full-featured Redis client for Node.js.
https://www.npmjs.com/package/ioredis
https://github.com/luin/ioredis
建议在Nodejs后台程序中使用ioredis,功能比较全,并且更新维护频率高,比node-redis维护要好。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。