Redis简介

Redis是一款开源的内存型键值数据库,支持多种数据结构(字符串、哈希、列表、集合、有序集合等),提供持久化、原子操作及高达10万+/秒的读写性能。主要应用于缓存、消息队列、会话存储、实时排行榜等场景。采用单线程模型保障操作原子性,同时支持主从复制、集群部署和高可用方案。

为了能在程序中调用Redis服务,我们使用redis-plus-plus库编写Redis的C++客户端

redis-plus-plus安装

这里仅介绍Ubuntu安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo apt update
# 安装前置依赖(C语言的库
sudo apt install -y libhiredis-dev

# 安装redis-plus-plus只能源码编译了
git clone https://github.com/sewenew/redis-plus-plus.git

cd ./redis-plus-plus/
mkdir build
cd ./build/
cmake ..
make
sudo make install
ldconfig

特别的,最后要再执行一下ldconfig指令防止程序运行时,找不到对应的动态库。我在使用docker容器时遇到了这样的问题。QWQ

编译链接选项

若在代码中使用了redis-plus-plus库,则需要在编译时同时假如连接选项-lredis++-lhiredis

1
g++ main.cpp -lredis++ -lhiredis

简单使用

关于命名空间

该库的大部分代码位于命名空间sw::redis::中,其中sw是作者名字的缩写

创建客户端对象

我们所有的Redis操作都是通过Redis客户端的接口向服务端发起网络请求来完成的,所以我们要先创建客户端对象才能进行后序的操作

我们的步骤如下

  1. 创建连接选项对象,填入相关参数
  2. 使用连接选项对象创建客户端对象
1
2
3
4
5
6
7
sw::redis::ConnectionOptions opts;
opts.host = ip;
opts.port = port;
opts.db = db;
opts.keep_alive = keep_alive;

sw::redis::Redis redis(opts);

使用Redis指令

该库中大部分的接口都是和redis-cli命令行客户端的指令是同名的

例如我们使用字符串指令

1
2
3
4
5
6
7
8
9
10
11
redis.set("mykey","myvalue");

sw::redis::OptionalString res = _redis->get("mykey");
if(!res.has_value())
{
std::cout<<"key不存在!"<<std::endl;
}
else
{
std::string value = res.value();
}

OptionalString

redis-plus-plus库提供了OptionalString类型,专门用来处理这种返回值可能不存在的情况。

我们先看一下这个OptionlaString底层用啥实现的:

1
2
3
4
5

template <typename T>
using Optional = std::optional<T>;

using OptionalString = Optional<std::string>;

可以看到,其实它就是特化了的std库中的std::optional<T>,模板参数固定为std::string类型

为什么要有Optional类型?因为对于一些结果不存在的情况,可以选择抛异常,可是对于即使结果不存在也不影响程序执行的情况,抛异常过于小题大做了,因此我们选择使用更温柔的处理方式:返回Optional类型。这样在处理结果时,先判断结果是否存在(调用has_value()接口),如果不存在,进入一个分支,如果存在,则调用value()接口进入另一个执行分支。

批量执行

该库也提供了接口将STL容器的内容批量插入到Redis服务中,或者从Redis服务中批量获取数据并存储到STL容器中。

批量插入

这类接口用起来比较简单,传入一个key开始接迭代器结束迭代器即可

1
2
std::unordered_map<string,string> m;
redis->hmset("hash_key",m.begin(),m.end())

批量插入

这里要用到STL库提供的插入器类,即std::inserter

1
2
std::unordered_map<string,string> m;
redis->hgetall("hash_key",std::inserter(m,m.begin()));