redis服务搭建,C++实现redis客户端,redis远程可视化工具

news2024/11/16 21:38:07

目录

  • redis简介
  • redis服务搭建
  • redis常用命令
  • C++实现redis客户端
  • redis远程可视化工具:Another Redis DeskTop Manager

redis简介

官方网址:https://redis.io/
开源地址:https://github.com/redis
中文文档:http://www.redis.cn/documentation.html

redis服务搭建

下载地址:https://redis.io/download/
下载版本:redis-7.0.11.tar.gz
操作系统:CentOS7

服务安装

#上传到目录,解压缩安装包
cd /opt/soft/
tar -zxvf redis-7.0.11.tar.gz
cd /opt/soft/redis-7.0.11/
make
make install

启动服务

cp /opt/soft/redis-7.0.11/redis.conf /usr/local/bin/mtconfig
vim redis.conf
daemonize no --> yes	#默认后台启动
cd /usr/local/bin/
./redis-server mtconfig/redis.conf	#启动服务
redis-cli -p 6379	#连接服务
ping	#测试,打印PONG
ps -ef | grep redis	#查看服务进程

常用命令

127.0.0.1:6379> ping			#查看当前连接是否正常,正常返回PONG
PONG
127.0.0.1:6379> keys *			#查看当前库里所有的key
(empty array)
127.0.0.1:6379> set name haka	#添加一个key为‘name’ value为‘haka’的数据
OK
127.0.0.1:6379> get name		#查询key为‘name’的value值
"haka"
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> EXISTS name		#判断当前key是否存在
(integer) 1
127.0.0.1:6379> move name 1		#移除当前库1的key为‘name‘的数据
(integer) 1
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set name1 haka1
OK
127.0.0.1:6379> type name1		#查看数据类型
string
127.0.0.1:6379> EXPIRE name1 15	#设置key为’name‘的数据过期时间为15秒 单位seconds
(integer) 1
127.0.0.1:6379> ttl name1		#查看当前key为’name‘的剩余生命周期时间
(integer) 9
127.0.0.1:6379> ttl name1		#如若返回-2,证明key已过期
(integer) -2
127.0.0.1:6379> get name 1
(error) ERR wrong number of arguments for 'get' command
127.0.0.1:6379> get name1
(nil)
127.0.0.1:6379> FLUSHALL		#清空所有库的内容
OK
127.0.0.1:6379>config set requirepass 123456 #设置临时密码
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth 123456		#使用密码认证

redis常用命令

1、字符串string操作命令

#设置指定的key值
SET key value
#获取指定key的值
GET key
#设置指定key的值,并将key的过期时间设为seconds秒
SETEX key seconds value
#只有在key不存在时设置key的值
SETNX key value

2、哈希hash操作命令
Redis hash是一个string类型的field和value的映射表,hash特别适用于存储对象,常用命令:

#将哈希表key中的字段field的值设为value
HSET key field value
#获取存储在哈希表中指定字段的值
HGET key field
#删除存储在哈希表中的指定字段
HDEL key field
#获取哈希表中所有字段
HKEYS key
#获取哈希表中所有值
HVALS key 
#获取在哈希表中指定key的所有字段和值
HGETALL key

3、列表list操作命令
Redis列表是简单的字符串列表,按照插入顺序排序,常用命令:

#将一个或多个值插入到列表头部
LPUSH key value1 [value2] 
#获取列表指定范围内的元素
LRANGE key start stop 
#移除并获取列表最后一个元素
RPOP key
#获取列表长度
LLEN key
#移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
BRPOP key1 [key2] timeout

4、集合set操作命令
Redis set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,常用命令:

#向集合添加一个或多个成员
SADD key member1 [member2]
#返回集合中的所有成员
SMEMBERS key 
#获取集合中的成员数
SCARD key
#返回给定所有集合的交集
SINTER key1 [key2]
#返回所有给定集合的并集
SUNION key1 [key2]
#返回给定所有集合的差集
SDIFF key1 [key2]
#移除集合中一个或多个成员
SREM key member1 [member2]

5、有序集合sorted set操作命令
Redis sorted set有序集合是string类型元素的集合,且不允许重复的成员。每个元素都会关联一个double类型的分数(score)。redis正是通过分数来为集合中的成员进行从小到大排序。有序集合的成员是唯一的,但分数却可以重复。
常用命令:

#向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZADD key score1 member1 [score2 member2]
#通过索引区间返回有序集合中指定区间内的成员
ZRANGE key start stop [WITHSCORES]
#有序集合中对指定成员的分数加上增量increment
ZINCRBY key increment member
#移除有序集合中的一个或多个成员
ZREM key member [member...]

C++实现redis客户端

使用redis官方提供的开源客户端:hiredis。
下载地址:https://github.com/redis/hiredis
下载开发包:hiredis-master.zip

unzip hiredis-master.zip
cd hiredis-master/
make
make install
/usr/local/include/hiredis	#头文件目录
/usr/local/lib				#库文件目录

代码实现,使用QT测试:
pro文件添加:LIBS += -lhiredis
头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <hiredis/hiredis.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

using namespace std;
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void init();
    int setString(string key, string value);
    string getString(string key);

    int setList(string key, vector<string> value);
    vector<string> getList(string key);

private:
    Ui::MainWindow *ui;

    redisContext *m_redis;
};
#endif // MAINWINDOW_H

源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <iostream>
#include <sstream>

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    init();

    //test string
    setString("name","haka");
    string msg = getString("name");
    printf("msg=%s\n",msg.c_str());

    //测试list
    vector<string> vec ={"cat","dog","rat","bird"};
    setList("bao",vec);
    vector<string> vecResult = getList("bao");
    for(int i=0;i<vecResult.size();i++)
    {
        cout<<vecResult[i]<<" ";
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
//建立连接
    struct timeval timeout = { 1, 500000 }; // 1.5 seconds 设置连接等待时间
    char ip[255];
    strcpy(ip, "127.0.0.1");
    m_redis = redisConnectWithTimeout(ip, 6379, timeout);
    if (m_redis->err) {
        printf("RedisTool : Connection error: %s\n", m_redis->errstr);
    }
    else
    {
        //REDIS_REPLY响应的类型type
        cout << "init redis tool success " << endl;
        cout << "#define REDIS_REPLY_STRING 1"<< endl;
        cout << "#define REDIS_REPLY_ARRAY 2"<< endl;
        cout << "#define REDIS_REPLY_INTEGER 3"<< endl;
        cout << "#define REDIS_REPLY_NIL 4"<< endl;
        cout << "#define REDIS_REPLY_STATUS 5"<< endl;
        cout << "#define REDIS_REPLY_ERROR 6"<< endl;
    }
//设置密码
    redisReply *reply = (redisReply *)redisCommand(m_redis, "AUTH %s", "123456");
    if (reply->type == REDIS_REPLY_ERROR)
    {
        printf("Redis认证失败!\n");
    }
    else
    {
        printf("Redis认证成功!\n");
    }
    freeReplyObject(reply);
}

//向数据库写入string类型数据
int MainWindow::setString(string key, string value)
{
    if(m_redis == NULL || m_redis->err)//int err; /* Error flags, 错误标识,0表示无错误 */
    {
        cout << "Redis init Error !!!" << endl;
        init();
        return -1;
    }
    redisReply *reply;
    reply = (redisReply *)redisCommand(m_redis,"SET %s %s", key.c_str(), value.c_str());//执行写入命令
    cout<<"set string type = "<<reply->type<<endl;//获取响应的枚举类型
    int result = 0;
    if(reply == NULL)
    {
        redisFree(m_redis);
        m_redis = NULL;
        result = -1;
        cout << "set string fail : reply->str = NULL " << endl;
        //pthread_spin_unlock(&m_redis_flock);
        return -1;
    }
    else if(strcmp(reply->str, "OK") == 0)//根据不同的响应类型进行判断获取成功与否
    {
        result = 1;
    }
    else
    {
        result = -1;
        cout << "set string fail :" << reply->str << endl;
    }
    freeReplyObject(reply);//释放响应信息

    return result;
}

//从数据库读出string类型数据
string MainWindow::getString(string key)
{
    if(m_redis == NULL || m_redis->err)
    {
        cout << "Redis init Error !!!" << endl;
        init();
        return NULL;
    }
    redisReply *reply;
    reply = (redisReply *)redisCommand(m_redis,"GET %s", key.c_str());
    cout<<"get string type = "<<reply->type<<endl;

    if(reply == NULL)
    {
        redisFree(m_redis);
        m_redis = NULL;
        cout << "ERROR getString: reply = NULL!!!!!!!!!!!! maybe redis server is down" << endl;
        return NULL;
    }
    else if(reply->len <= 0)
    {
        freeReplyObject(reply);
        return NULL;
    }
    else
    {
        stringstream ss;
        ss << reply->str;
        freeReplyObject(reply);
        return ss.str();
    }
}

//向数据库写入vector(list)类型数据
int MainWindow::setList(string key,vector<string> value)
{
    if(m_redis == NULL || m_redis->err)
    {
        cout << "Redis init Error !!!" << endl;
        init();
        return -1;
    }

    redisReply *reply;

    int valueSize = value.size();
    int result = 0;

    for(int i=0; i<valueSize; i++)
    {
        reply = (redisReply*)redisCommand(m_redis,"RPUSH %s %s", key.c_str(),value.at(i).c_str());
        cout<<"set list type = "<<reply->type<<" ";
        int old = reply->integer;
        if(reply == NULL)
        {
            redisFree(m_redis);
            m_redis = NULL;
            result = -1;
            cout << "set list fail : reply->str = NULL " << endl;
            //pthread_spin_unlock(&m_redis_flock);
            return -1;
        }
        else if(reply->integer == old++)
        {
            result = 1;
            cout<<"rpush list ok"<<endl;
            continue;
        }
        else
        {
            result = -1;
            cout << "set list fail ,reply->integer = " << reply->integer << endl;
            return -1;
        }

    }

    freeReplyObject(reply);
    cout<<"set List  success"<<endl;
    return result;

}

//从数据库读出vector(list)类型数据
vector<string> MainWindow::getList(string key)
{
    if(m_redis == NULL || m_redis->err)
    {
        cout << "Redis init Error !!!" << endl;
        init();
        return vector<string>{};//返回空的向量
    }

    redisReply *reply;
    reply = (redisReply*)redisCommand(m_redis,"LLEN %s", key.c_str());
    int valueSize = reply->integer;
    cout<<"List size is :"<<reply->integer<<endl;

    reply = (redisReply*)redisCommand(m_redis,"LRANGE %s %d %d", key.c_str(),0,valueSize-1);
    cout<<"get list type = "<<reply->type<<endl;
    cout<<"get list size = "<<reply->elements<<endl;//对于数组类型可以用elements元素获取数组长度

    redisReply** replyVector = reply->element;//获取数组指针
    vector<string> result;
    for(int i=0;i<valueSize;i++)
    {
        string temp =(*replyVector)->str;//遍历redisReply*数组,存入vector向量
//        int a =atoi(temp.c_str());
        result.push_back(temp);
        replyVector++;
    }

    cout<<"result size:"<<result.size()<<endl;
    return result;
}



打印:

init redis tool success 
#define REDIS_REPLY_STRING 1
#define REDIS_REPLY_ARRAY 2
#define REDIS_REPLY_INTEGER 3
#define REDIS_REPLY_NIL 4
#define REDIS_REPLY_STATUS 5
#define REDIS_REPLY_ERROR 6
Redis认证成功!
set string type = 5
get string type = 1
msg=haka
set list type = 3 rpush list ok
set list type = 3 rpush list ok
set list type = 3 rpush list ok
set list type = 3 rpush list ok
set List  success
List size is :4
get list type = 2
get list size = 4
result size:4
cat dog rat bird 

redis远程可视化工具:Another Redis DeskTop Manager

下载地址:https://github.com/qishibo/AnotherRedisDesktopManager/releases
下载exe安装包:Another-Redis-Desktop-Manager.1.6.0.exe。
安装程序后运行。

远程连接配置
1、关闭防火墙

 systemctl status firewalld		#查看防火墙状态
 systemctl stop firewalld		#关闭防火墙

2、修改redis配置文件

 vim redis.conf
 bind 0.0.0.0		#设置为0.0.0.0开放所有,或指定IP
 protected-mode no	#关闭保护模式,才能远程连接
 deamonize yes		#redis设置为后台启动
 requirepass 123456	#设置访问密码

编辑连接
在这里插入图片描述
连接成功
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/493298.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

造轮子系列】面试官问:你能手写Vuex吗(一)?

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 Vuex 是 Vue.js 的状态管理模式&#xff0c;它主要解决了组件之间共享状态时的问题。在本文…

网络原理之传输层

网络原理&#xff0c;进一步了解网络是如何工作的~~ 按照网络协议这几个层次来展开分为五点&#xff1a; 应用层&#xff08;重点介绍&#xff09;传输层&#xff08;重点介绍&#xff09;网络层&#xff08;跳过&#xff09;数据链路层&#xff08;跳过&#xff09;物理层&a…

JavaScript,

JS-引入方式JS-基础语法 书写语法变量数据类型&#xff0c;运算符&#xff0c;控制语句 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"…

Abstract Expressionist

古董地图画集 10大最有名的抽象艺术家 抽象表现主义是现代许多不同艺术思想和表达流派中最奇特的艺术运动之一。这场运动开始从社会变革中涌现出来&#xff0c;恰逢第二次世界大战的最后几周和几个月。 这一次&#xff0c;来自世界各地的人们开始欢迎在经历了多年有史以来最致…

【JavaWeb 用户认证】Cookie、Session、Token、JWT、Interceptor、SpringBoot、Spring Security

Token基本了解&#xff1a;【详细阐述Token的来源】公钥私钥基本了解&#xff1a;【理解公钥】 文章目录 一、Cookie 经典介绍以及使用案例二、Session 经典介绍以及拦截登录案例三、Token MySQL 的基本介绍及其基本使用四、JWT 基本介绍及其基本讲解五、SpringBoot 使用拦截器…

使用PyQt5设计一款简单的计算器

目录 一、环境配置&#xff1a; 二、代码实现 三、主程序 四、总结 本文使用PyQt5设计一款简单的计算器&#xff0c;可以通过界面交互实现加减乘除的功能&#xff0c;希望能够给初学者一些帮助。主要涉及的知识点有类的定义与初始化、类的成员函数、pyqt5的信号与槽函数等。…

LeetCode 牛客单链表OJ题目思路分享

目录 反转链表合并两个有序链表链表分割 反转链表 链接: link 题目描述&#xff1a; 题目思路&#xff1a; 方法1&#xff1a;改变链表链接的方向 方法1思路&#xff1a; 这力我们需要三个指针n1 n2 n3方便我们进行迭代 初始化n1指向NULL&#xff0c;n2指向第一个节点&…

云原生时代崛起的编程语言Go常用标准库实战

文章目录 基础标准库简述字符串-string底层结构函数长度格式化输出 模版-templatetext/templatehtml/template 正则表达式-regexp编码-encodingBase64JSONXML 时间-time网络-netURLHTTP客户端和服务端 加密IO操作读写文件环境变量命令行 数据库排序-sort测试和基准测试 基础标准…

OpenLDAP安装报错

tip:基于centos7&#xff0c;OpenLDAP使用2.4.44版本 只要有succeeded就可以。error可以忽略 配置base.ldif文件&#xff0c;下面的空行是必须的。 dn: dcts,dccom o: ts com dc: ts objectClass: top objectClass: dcObject objectclass: organizationdn: cnManager,dcts,d…

leveldb自定义env

leveldb自定义env 未完待续。。。 由于项目需求&#xff0c;需要自定义LevelDB的env&#xff0c;也就是以块接口实现env中各个文件接口&#xff0c;在网上没找到类似的代码&#xff0c;就打算自己参照util/env_posix.cc实现一个简单的demo&#xff0c;等到功能实现差不多的时候…

ADRV9002官方例程开发过程中遇到的问题

开发环境&#xff1a;Vivado2021.2 HDL版本&#xff1a;hdl_2021_r2 GitHub - analogdevicesinc/hdl at hdl_2021_r2 no-OS版本&#xff1a;no_OS-2021_R2 GitHub - analogdevicesinc/no-OS at 2021_R2 &#xff08;PS&#xff1a;也可以用Vivado2019.1开发&#xff0c…

【漏洞复现】Joomla未授权访问漏洞(CVE-2023-23752)

文章目录 前言声明一、漏洞简介二、影响版本三、环境搭建四、漏洞分析五、漏洞复现六、修复建议前言 Joomla是一套全球知名的内容管理系统(CMS),其使用PHP语言加上MySQL数据库所开发,可以在Linux、Windows、MacOSX等各种不同的平台上运行。 声明 本篇文章仅用于漏洞复现与…

华为OD机试真题-密码强度等级【2023】【JAVA】

一、题目描述 密码按如下规则进行计分&#xff0c;并根据不同的得分为密码进行安全等级划分。 1、密码长度&#xff1a; 5 分: 小于等于4 个字符 10 分: 5 到7 字符 25 分: 大于等于8 个字符 2、字母&#xff1a; 0 分: 没有字母 10 分: 密码里的字母全都是小&#xff08;…

电脑硬盘磁盘不小心被格式化了?如何一键恢复操作教程

Easyrecovery是一款功能齐全的数据恢复软件&#xff0c;恢复内容包括&#xff1a;硬盘数据恢复、手机数据恢复、U盘数据恢复、Mac数据恢复、恢复删除文件及高级数据恢复等。当用户发生数据丢失问题时&#xff0c;第一时间想到的就是使用数据恢复软件来恢复已经丢失的文件。在众…

【机器学习】集成学习解读(ensemble learning)

【机器学习】集成学习解读&#xff08;ensemble learning&#xff09; 文章目录 【机器学习】集成学习解读&#xff08;ensemble learning&#xff09;1. 集成学习(ensemble learning)1.1 前言1.2 什么是集成学习 2. 如何得到若干个个体学习器2.1 集成学习之 Bagging2.2 集成学…

《Netty》从零开始学netty源码(五十三)之PoolThreadCache的功能

allocateNormal 在前面分析PoolArena的分配内存的方法中&#xff0c;每次分配都是先从本地线程缓存中分配&#xff0c;本地线程缓存PoolThreadCache的分配方法如下&#xff1a; 分配过程主要有两步&#xff1a; 从PoolThreadCache的缓存数组中获取相应大小的缓存cache将需要…

手残也不该敲的命令

Linux命令是一种很有趣且有用的东西&#xff0c;但在你不知道会带来什么后果的时候&#xff0c;它又会显得非常危险。所以&#xff0c;在输入某些命令前&#xff0c;请多多检查再敲回车。 rm –rf rm –rf是删除文件夹和里面附带内容的一种最快捷的方法&#xff0c;但是细微的…

mybatis拦截器统一处理createBy、createTime、updateBy等字段

一、问题描述 createBy 、createTime、updateBy等字段是我们创建表的时候经常要用到的几个字段&#xff0c;但是我们不可能每一次在增删改查的时候都手动去修改或者添加这几个字段的属性值&#xff0c;我们可以在系统层面统一处理&#xff0c;如何实现呢&#xff1f; 二、实现…

轻松掌握KubeKey单节点和集群安装k8s和kubesphere

1、KubeKey单节点AllInOne装kubesphere及k8s 如果只想安装k8s&#xff0c;注意在命令里不指定kubesphere即可。 1、设置hostname hostnamectl set-hostname k8s-node05 2、准备KubeKey export KKZONEcncurl -sfL https://get-kk.kubesphere.io | VERSIONv1.1.1 sh -chmod …

Codeforces Round 867 (Div. 3) AK题解

目录 A. TubeTube Feed&#xff08;签到&#xff09; 题意&#xff1a; 思路&#xff1a; 代码&#xff1a; B. Karina and Array&#xff08;签到&#xff09; 题意&#xff1a; 思路&#xff1a; 代码&#xff1a; C. Bun Lover&#xff08;结论&#xff09; 题意&…