【发布时间】:2014-04-07 18:40:06
【问题描述】:
有没有办法在 Redis 中做条件集?
我想用 Redis 来缓存一些对象。缓存的每个用户(服务器程序)都会检查一个对象,如果它有更新的版本,就更新它。我需要确保在更新步骤中只有最新版本真正保存在 Redis 中。
【问题讨论】:
标签: redis
有没有办法在 Redis 中做条件集?
我想用 Redis 来缓存一些对象。缓存的每个用户(服务器程序)都会检查一个对象,如果它有更新的版本,就更新它。我需要确保在更新步骤中只有最新版本真正保存在 Redis 中。
【问题讨论】:
标签: redis
您可以编写一个 lua 脚本来检查键的当前值并在值与新值不同时更改它。我在 c 中添加了一个通过 c-program 调用 lua 脚本并完成所需工作的示例。
//g++ -g -o condition condition.cpp -I/usr/local/include/hiredis -L/usr/local/lib -levent -lhiredis
/*----------------------
EVAL
------------------------*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <hiredis/hiredis.h>
using namespace std;
struct timeval _timeout ;
redisContext *_redisContext;
const long long SEC_TO_USEC = 1000000 ;
void connect(const std::string &ip,
int port,
int timeoutInUsec )
{
_timeout.tv_sec = timeoutInUsec / SEC_TO_USEC ;
_timeout.tv_usec = timeoutInUsec % SEC_TO_USEC ;
_redisContext = redisConnectWithTimeout(ip.c_str(), port, _timeout);
if (_redisContext->err)
{
std::cout << "Cannot connect to redis server. "
<< " Error : " << _redisContext->errstr
<< std::endl ;
exit(1);
}
}
//lua scrip for conditional set
string scriptMultipleCommands =
"local res = redis.call(\"GET\", KEYS[1]) "
"if res == ARGV[1] then "
" return nil "
"else "
"redis.call(\"SET\", KEYS[1], ARGV[1]) "
"end "
"local data = redis.call(\"GET\",KEYS[1]) "
"return data ";
void luaCommand(char** argv)
{
string command;
command.append( scriptMultipleCommands );
redisReply *reply =
( redisReply * ) redisCommand( _redisContext,
"EVAL %s %d %s %s ",command.c_str(),1,argv[1],argv[2]);
cout<<"Redis reply type "<<reply->type<<endl;
if (reply->type == REDIS_REPLY_ARRAY)
{
cout<<"Redis reply size "<<reply->elements<<endl;
for (int j = 0; j < reply->elements; j++)
{
if((j+1) < reply->elements)
{
cout<<(reply->element[j]->str)<<","<<(reply->element[j+1]->str)<<endl;
++j;
}
}
}
else if (reply->type == REDIS_REPLY_INTEGER) {
cout<<"Key value "<<reply->integer<<endl;
}
else
cout<<endl<<"EVAL: "<< reply->str<<endl;
freeReplyObject(reply);
}
int main(int argc,char** argv)
{
connect("10.0.0.30",6379,1500000);
luaCommand(argv);
return 0;
}
【讨论】: