您的位置:首页 > 数据库 > Redis

Redis中modules扩展模块的开发使用详解

2016-12-12 13:40 691 查看
本文和大家分享的主要是redis中modules扩展模块的开发与使用相关内容,希望通过本文的分享对大家学习redis 有所帮助,一起开看看吧。
  首先我们要安装redis 4.0 rc 新版. antirez说过,在3.x版本中不会加入自定义模块加载的.
  #xiaorui.cc
  wget https://github.com/antirez/redis/archive/4.0-rc2.tar.gz   tar zxvf 4.0*cd 4.0makemake test
  下载第三方的Redis modules模块,make编译
  gitclonehttps://github.com/RedisLabsModules/redexcd redexmake
  上面编译完了后,在src下是有一堆动态链接库so 文件的, 然后我们修改redis.conf的配置, 加入这些so文件。
  --loadmodule /path/src/module.so
  redisEx moudules的扩展基本是 在redis本身数据结构基础上做的调整 .
  Includedmodules:
  rxkeys - extendedkeyscommands (ModuleHubpage)
  rxstrings - extendedStringscommands (ModuleHubpage)
  rxhashes - extendedHashescommands (ModuleHubpage)
  rxlists - extendedListscommands (ModuleHubpage)
  rxsets - extendedSets commands (ModuleHubpage)
  rxzsets - extendedSorted Sets commands (ModuleHubpage)
  rxgeo - extendedGeoSets commands (ModuleHubpage)
  我们看下RedisEx对 zset的相关调整,比如里面的zpop 和 zrevpop , 一看这名字我觉得大家就能感觉出来他是干嘛的吧?
  redis 本身的zset 是没有pop命令的,如果你想获取并删除,那么就只能 zrange and zrem . zpop 是帮你pop出来一个最小score的数据,zrevpop 反之.
  # xiaorui.cc
  int ZPopGenericCommand(RedisModuleCtx *ctx, RedisModuleString **argv,
  int argc) {
  if (argc < 2 || argc > 3) {
  return RedisModule_WrongArity(ctx);
  }
  RedisModule_AutoMemory(ctx);
  /* Getthetargetcommand. */
  size_tcmdlen;
  constchar *cmd = RedisModule_StringPtrLen(argv[0], &cmdlen);
  int rev = !strncasecmp("zrevpop", cmd, cmdlen);
  int withscore = RMUtil_ArgExists("WITHSCORE", argv, argc, 2);
  if ((argc == 3) && !withscore) return RedisModule_WrongArity(ctx);
  // open thekeyand makesureit's indeed a ZSETand not empty
  RedisModuleKey *key =
  RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE);
  if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) {
  // and emptykey - return null
  if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_EMPTY) {
  RedisModule_ReplyWithNull(ctx);
  return REDISMODULE_OK;
  }
  // 类型错误,抛出异常
  RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
  return REDISMODULE_ERR;
  }
  // 获取最小score分值的元素
  doublescore;
  (rev ? RedisModule_ZsetLastInScoreRange : RedisModule_ZsetFirstInScoreRange)(
  key, REDISMODULE_NEGATIVE_INFINITE, REDISMODULE_POSITIVE_INFINITE, 0, 0);
  RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key, &score);
  RedisModule_ZsetRangeStop(key);
  // 删除这个元素
  RedisModule_ZsetRem(key, ele, NULL);
  // 返回元素 或者 含有分值 (取决于是否传入withscore参数)
  RedisModule_ReplyWithArray(ctx, (withscore ? 2 : 1));
  RedisModule_ReplyWithString(ctx, ele);
  if (withscore) RedisModule_ReplyWithDouble(ctx, score);
  return REDISMODULE_OK;
  }
  Redis set里多了一个 msismember的命令扩展,是个sismember的多扩展 . 用来判断多个集合里是否含有某个元素, 符合一个条件加 +1 , 如果返回 2 ,那么就是两个集合都含有这个元素.
  redis> SADDadminsAliceBobxiaorui.cc
  (integer) 3redis> SADDoncallZoeBobXavier
  (integer) 3redis> MSISMEMBERadminsoncallAlice
  (integer) 1redis> MSISMEMBERadminsoncallZoe
  (integer) 1redis> MSISMEMBERadminsoncallBob
  (integer) 2
  Reids Msismember 命令源代码如下 :
  #xiaorui.cc
  int MSIsMemberCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
  if (argc < 3) {
  if (RedisModule_IsKeysPositionRequest(ctx))
  return REDISMODULE_OK;
  else
  return RedisModule_WrongArity(ctx);
  }
  if (RedisModule_IsKeysPositionRequest(ctx)) {
  size_t i;
  for (i = 1; i < argc - 1; i++) RedisModule_KeyAtPos(ctx, i);
  return REDISMODULE_OK;
  }
  RedisModule_AutoMemory(ctx);
  int iele = argc - 1;
  size_tcount = 0;
  int i;
  for (i = 1; i < iele; i++) {
  RedisModuleKey *key =
  RedisModule_OpenKey(ctx, argv[i], REDISMODULE_READ | REDISMODULE_WRITE);
  if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_EMPTY) continue;
  if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_SET) { // 判断数据类型
  RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE);
  return REDISMODULE_ERR;
  }
  RedisModuleCallReply *rep =
  RedisModule_Call(ctx, "SISMEMBER", "ss", argv[i], argv[iele]); // 循环遍历调用 sismember 查看set集合中是否含有该元素
  RMUTIL_ASSERT_NOERROR(rep)
  count += RedisModule_CallReplyInteger(rep); // 如何一个就加一个数
  }
  RedisModule_ReplyWithLongLong(ctx, count); //返回
  return REDISMODULE_OK;
  }
  通过上面几个redis扩展源码我们发现,基本都是多个命令合并成一个函数,对于客户端来说节省了网络io的开销,又保证了原子性。

来源:峰云就她了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: