Redis常用命令及C C++调用Redis接口详解_redis c++,2024年最新360°深入了解Flutter

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)
img

正文

| MSETNX | 当指定的 key 都不存在时,用于设置多个键值对 |
| SET | 用于设定指定键的值 |
| SETBIT | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit) |
| SETEX | 将值 value 存储到 key中 ,并将 key 的过期时间设为 seconds (以秒为单位) |
| STRLEN | 返回 key 所储存的字符串值的长度 |
| SETNX | 当 key 不存在时设置 key 的值 |
| SETRANGE | 从偏移量 offset 开始,使用指定的 value 覆盖的 key 所存储的部分字符串值 |

List 命令

List 是 Redis 中最常用数据类型之一。Redis 提供了诸多用于操作列表类型的命令,通过这些命令你可以实现将一个元素添加到列表的头部,或者尾部等诸多操作。

List 常用的命令如下所示:

命令说明
BLPOP用于删除并返回列表中的第一个元素(头部操作),如果列表中没有元素,就会发生阻塞,直到列表等待超时或发现可弹出元素为止
BRPOP用于删除并返回列表中的最后一个元素(尾部操作),如果列表中没有元素,就会发生阻塞,直到列表等待超时或发现可弹出元素为止
BRPOPLPUSH从列表中取出最后一个元素,并插入到另一个列表的头部。如果列表中没有元素,就会发生阻塞,直到等待超时或发现可弹出元素时为止
LINDEX通过索引获取列表中的元素
LINSERT指定列表中一个元素在它之前或之后插入另外一个元素
LLEN用于获取列表的长度
LPOP从列表的头部弹出元素,默认为第一个元素
LPUSH在列表头部插入一个或者多个值
LPUSHX当储存列表的 key 存在时,用于将值插入到列表头部
LRANGE获取列表指定范围内的元素
LREM表示从列表中删除元素与 value 相等的元素。count 表示删除的数量,为 0 表示全部移除
LSET表示通过其索引设置列表中元素的值
LTRIM保留列表中指定范围内的元素值
Set 命令

Redis set 数据类型由键值对组成,这些键值对具有无序、唯一的性质,这与 Python 的 set 相似。当集合中最后一个元素被移除之后,该数据结构也会被自动删除,内存也同样会被收回。

由于 set 集合可以实现去重,因此它有很多适用场景,比如用户抽奖活动,使用 set 集合可以保证同一用户不被第二次选中。

Redis set 常用的命令如下所示:

命令说明
SADD向集合中添加一个或者多个元素,并且自动去重
SCARD返回集合中元素的个数
SDIFF求两个或对多个集合的差集
SDIFFSTORE求两个集合或多个集合的差集,并将结果保存到指定的集合(key)中
SINTER求两个或多个集合的交集
SINTERSTORE求两个或多个集合的交集,并将结果保存到指定的集合(key)中
SMEMBERS查看集合中所有元素
SMOVE将集合中的元素移动到指定的集合中
SPOP弹出指定数量的元素
SRANDMEMBER随机从集合中返回指定数量的元素,默认返回 1个
SREM删除一个或者多个元素,若元素不存在则自动忽略
SUNION求两个或者多个集合的并集
SUNIONSTORE求两个或者多个集合的并集,并将结果保存到指定的集合(key)中
Zset 命令

zset 是 Redis 提供的最具特色的数据类型之一,首先它是一个 set,这保证了内部 value 值的唯一性,其次它给每个 value 添加了一个 score(分值)属性,通过对分值的排序实现了有序化。比如用 zset 结构来存储学生的成绩,value 值代表学生的 ID,score 则是的考试成绩。我们可以对成绩按分数进行排序从而得到学生的的名次。

下面列出了 zset 的常用命令,如下所示:

命令说明
ZADD用于将一个或多个成员添加到有序集合中,或者更新已存在成员的 score 值
ZCARD获取有序集合中成员的数量
ZCOUNT用于统计有序集合中指定 score 值范围内的元素个数
ZINCRBY用于增加有序集合中成员的分值
ZINTERSTORE求两个或者多个有序集合的交集,并将所得结果存储在新的 key 中
ZRANGE返回有序集合中指定索引区间内的成员数量
ZRANGEBYLEX返回有序集中指定字典区间内的成员数量
ZRANGEBYSCORE返回有序集合中指定分数区间内的成员
ZRANK返回有序集合中指定成员的排名
ZREM移除有序集合中的一个或多个成员
ZREMRANGEBYRANK移除有序集合中指定排名区间内的所有成员
ZREMRANGEBYSCORE移除有序集合中指定分数区间内的所有成员
ZREVRANGE返回有序集中指定区间内的成员,通过索引,分数从高到低
ZREVRANK返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
ZSCORE返回有序集中,指定成员的分数值
ZUNIONSTORE求两个或多个有序集合的并集,并将返回结果存储在新的 key 中

二、C/C++调用接口连接和操作Redis数据库

上面的这些命令在是Redis自身的命令,但是在我们的C/C++代码,我们不能直接执行这些命令,我们需要通过Redis提供的API来访问Redis。

redis支持不同的编程语言,但是调用了不同的redis包,例如:java对应jedis;php对应phpredis;C++对应的则是hredis。

因此我们需要安转hredis。安装完hredis之后,我们就可以通过hredis提供的API来连接、操作Redis。

redis提供的api在头文件<hiredis.h>中提供,我们直接把文件内容拿过来了解一些,再一次讲解每个函数的使用方法。

hiredis.h

#ifndef __HIREDIS_H
#define __HIREDIS_H
#include “read.h”
#include <stdarg.h> /* for va_list */
#include <sys/time.h> /* for struct timeval */
#include <stdint.h> /* uintXX_t, etc */
#include “sds.h” /* for sds */
#include “alloc.h” /* for allocation wrappers */

#define HIREDIS_MAJOR 0
#define HIREDIS_MINOR 14
#define HIREDIS_PATCH 0
#define HIREDIS_SONAME 0.14

/* Connection type can be blocking or non-blocking and is set in the
* least significant bit of the flags field in redisContext. */
#define REDIS_BLOCK 0x1

/* Connection may be disconnected before being free’d. The second bit
* in the flags field is set when the context is connected. */
#define REDIS_CONNECTED 0x2

/* The async API might try to disconnect cleanly and flush the output
* buffer and read all subsequent replies before disconnecting.
* This flag means no new commands can come in and the connection
* should be terminated once all replies have been read. */
#define REDIS_DISCONNECTING 0x4

/* Flag specific to the async API which means that the context should be clean
* up as soon as possible. */
#define REDIS_FREEING 0x8

/* Flag that is set when an async callback is executed. */
#define REDIS_IN_CALLBACK 0x10

/* Flag that is set when the async context has one or more subscriptions. */
#define REDIS_SUBSCRIBED 0x20

/* Flag that is set when monitor mode is active */
#define REDIS_MONITORING 0x40

/* Flag that is set when we should set SO_REUSEADDR before calling bind() */
#define REDIS_REUSEADDR 0x80

#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */

/* number of times we retry to connect in the case of EADDRNOTAVAIL and
* SO_REUSEADDR is being used. */
#define REDIS_CONNECT_RETRIES 10

#ifdef __cplusplus
extern “C” {
#endif

/* This is the reply object returned by redisCommand() */
typedef struct redisReply {
int type; /* REDIS_REPLY_* */
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
size_t len; /* Length of string */
char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
} redisReply;

redisReader *redisReaderCreate(void);

/* Function to free the reply objects hiredis returns by default. */
void freeReplyObject(void *reply);

/* Functions to format a command according to the protocol. */
int redisvFormatCommand(char **target, const char *format, va_list ap);
int redisFormatCommand(char **target, const char *format, …);
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
void redisFreeCommand(char *cmd);
void redisFreeSdsCommand(sds cmd);

enum redisConnectionType {
REDIS_CONN_TCP,
REDIS_CONN_UNIX
};

/* Context for a connection to Redis */
typedef struct redisContext {
int err; /* Error flags, 0 when there is no error */
char errstr[128]; /* String representation of error when applicable */
int fd;
int flags;
char *obuf; /* Write buffer */
redisReader *reader; /* Protocol reader */

enum redisConnectionType connection_type;
struct timeval *timeout;

struct {
char *host;
char *source_addr;
int port;
} tcp;

struct {
char *path;
} unix_sock;

} redisContext;

redisContext *redisConnect(const char *ip, int port);
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
redisContext *redisConnectNonBlock(const char *ip, int port);
redisContext *redisConnectBindNonBlock(const char *ip, int port,
const char *source_addr);
redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
const char *source_addr);
redisContext *redisConnectUnix(const char *path);
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
redisContext *redisConnectUnixNonBlock(const char *path);
redisContext *redisConnectFd(int fd);

/**
* Reconnect the given context using the saved information.
*
* This re-uses the exact same connect options as in the initial connection.
* host, ip (or path), timeout and bind address are reused,
* flags are used unmodified from the existing context.
*
* Returns REDIS_OK on successful connect or REDIS_ERR otherwise.
*/
int redisReconnect(redisContext *c);

int redisSetTimeout(redisContext *c, const struct timeval tv);
int redisEnableKeepAlive(redisContext *c);
void redisFree(redisContext *c);
int redisFreeKeepFd(redisContext *c);
int redisBufferRead(redisContext *c);
int redisBufferWrite(redisContext *c, int *done);

/* In a blocking context, this function first checks if there are unconsumed
* replies to return and returns one if so. Otherwise, it flushes the output
* buffer to the socket and reads until it has a reply. In a non-blocking
* context, it will return unconsumed replies until there are no more. */
int redisGetReply(redisContext *c, void **reply);
int redisGetReplyFromReader(redisContext *c, void **reply);

/* Write a formatted command to the output buffer. Use these functions in blocking mode
* to get a pipeline of commands. */
int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);

/* Write a command to the output buffer. Use these functions in blocking mode
* to get a pipeline of commands. */
int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
int redisAppendCommand(redisContext *c, const char *format, …);
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

/* Issue a command to Redis. In a blocking context, it is identical to calling
* redisAppendCommand, followed by redisGetReply. The function will return
* NULL if there was an error in performing the request, otherwise it will
* return the reply. In a non-blocking context, it is identical to calling
* only redisAppendCommand and will always return NULL. */
void *redisvCommand(redisContext *c, const char *format, va_list ap);
void *redisCommand(redisContext *c, const char *format, …);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

#ifdef __cplusplus
}
#endif

#endif

从文件代码可以看到,对于我们使用C/C++来连接操作Redis数据库,我们最少需要了解:

  • 一个结构体:redisContext,这个结构体中,包含着我们连接Redis的信息。
  • 几个函数:
  • redisContext *redisConnect(const char *ip, int port);连接Redis函数
  • void *redisCommand(redisContext *c, const char *format, …);给Redis传递命令
  • void redisFree(redisContext *c);
  • void freeReplyObject(void *reply);

函数详解

函数原型:redisContext *redisConnect(const char *ip, int port)

说明:该函数用来连接redis数据库,参数为数据库的ip地址和端口,一般redis数据库的端口为6379

该函数返回一个结构体redisContext。

函数原型:void *redisCommand(redisContext *c, const char *format, …);

说明:该函数执行命令,就如sql数据库中的SQL语句一样,只是执行的是redis数据库中的操作命令,第一个参数为连接数据库时返回的redisContext,剩下的参数为变参,就如C标准函数printf函数一样的变参。返回值为void*,一般强制转换成为redisReply类型的进行进一步的处理。

函数原型void freeReplyObject(void *reply);

说明:释放redisCommand执行后返回的redisReply所占用的内存

函数原型:void redisFree(redisContext *c);

说明:释放redisConnect()所产生的连接。

同步API
连接redis数据库

函数 redisConnect 被用来创建一个 redisContext。这个 context 是hiredis持有的连接状态。redisConnect 结构体有一个整型的 err 变量来标识连接错误码,如果连接错误则为非零值。变量 errstr 标识连接结果的文字描述。更多这方面的信息会在以下Errors章节说明。当你使用 redisConnect 来创建连接时应该检查err变量来判断是否连接正常建立。

redisContext *c = redisConnect(“127.0.0.1”, 6379);
if (c != NULL && c->err) {undefined
printf(“Error: %s\n”, c->errstr); // handle error }

发送命令到redis

有多种方法可以发送命令到redis。

首先介绍的是redisCommand。此函数类似于printf的使用方式,如

reply = redisCommand(context, “SET foo bar”);

类似于printf的s%格式化方式,如

reply = redisCommand(context, “SET foo %s”, value);

当你需要发送二进制安全的命令可以采用%b的格式化方式,同时需要一个字符串指针和size_t类型的字符串长度参数,如下

reply = redisCommand(context, “SET foo %b”, value, (size_t) valuelen);

在API内部,Hiredis根据不同的参数分割命令转化为操作redis数据库的标准命令,你可以格式化多个参数来构造redis的命令,如下

reply = redisCommand(context, “SET key:%s %s”, myid, value);

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ue, (size_t) valuelen);

在API内部,Hiredis根据不同的参数分割命令转化为操作redis数据库的标准命令,你可以格式化多个参数来构造redis的命令,如下

reply = redisCommand(context, “SET key:%s %s”, myid, value);

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-VFfkVRe2-1713358084442)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值