redis select 插入出错
初学redis,写了个小demo,预想目标:db0-db9每个插入一条数据,现实情况是全部都插入到db9了,请帮忙看下,谢谢。
app.js提供服务:
var express = require("express");
var bodyParser = require('body-parser');
var redis = require("redis");
var client = redis.createClient("6379","192.168.205.161");
var app = express();
app.use(bodyParser());
app.post("/",function(req,res){
client.SELECT(req.body.id,function(){
client.HMSET(req.body.id,req.body,function(err){
if(err){
console.log("插入失败");
return false;
}
console.log("插入成功");
client.EXPIRE(req.body.id,86400);
});
})
});
app.listen("3001");
利用request
模拟post请求
var request = require("request");
for(var i = 0;i<10;i++){
(function(i){
request.post({
url:'http://127.0.0.1:3001/',
json:{'id':i}
});
})(i);
}
4 回复
应该for循环的原因,i直接就是9了,你调试下看你req.body.id
是多少
把 var client = redis.createClient(“6379”,“192.168.205.161”); 放到路由函数里面
模拟请求的部分是正确的,问题出在 select 命令和 hmset 命令不是同时执行上。具体来说,10 个请求同时发生,这是会同时执行 10 个 select
命令,所有最后一个是 select 9
,接下来会执行 10 个 hmset
命令,这样所有的数据都会写入到 9 号 db 中了。当然这个顺序和网络时延有关,你可以在 redis-cli 中执行 monitor 来查看所有命令的顺序。
解决方法是使用 Redis 的 transaction 或者客户端的 pipelining。使用 pipelining 的例子是:
var express = require('express');
var bodyParser = require('body-parser');
var Redis = require('ioredis');
var client = new Redis('6379', '192.168.205.161');
var app = express();
app.use(bodyParser());
app.post('/',function(req,res){
client.pipeline()
.select(req.body.id)
.hmset(req.body.id,req.body)
.exec(function (err) {
if(err){
console.log('插入失败');
return false;
}
console.log('插入成功');
client.pipeline().select(req.body.id).expire(req.body.id, 86400).exec();
res.json({ success: true });
});
});
app.listen('3001');
@luinlee 明白了,非常感谢