分布式学习第二天 redis学习
目录
1. 数据库类型
1.1 基本概念
-
关系型数据库 - sql
-
操作数据必须要使用sql语句
-
数据存储在磁盘
-
存储的数据量大
-
举例:
-
mysql
-
oracle
-
sqlite - 文件数据库
-
sql server
-
-
-
非关系数据库 - nosql
-
操作不使用sql语句
-
命令
-
-
数据默认存储在内存
-
速度快, 效率高
-
存储的数据量小
-
-
不需要数据库表
-
以键值对的方式存储的
-
-
1.2 关系/非关系型数据库搭配使用
==RDBMS: Relational Database Management System== 关系型数据库
-
所有的数据默认存储在关系型数据库中
-
客户端访问服务器, 有一些数据, 服务器需要频繁的查询数据
-
服务器首先将数据从关系型数据库中读出 -> 第一次
-
将数据写入到redis中
-
-
客户端第二次包含以后访问服务器
-
服务器从redis中直接读数据
-
-
2. Redis
-
知道redis是什么?
-
非关系型数据库 也可以叫 内存数据库
-
-
能干什么?
-
存储访问频率高的数据
-
共享内存
-
服务器端 -> redis
-
-
-
怎么使用?
-
常用的操作命令
-
各种数据类型 -> 会查
-
-
redis的配置文件
-
redis的数据持久化
-
写程序的时候如何对redis进行操作
-
客户端 -> 服务器
-
-
2.1 基本知识点
-
# 服务器 - 启动
-
redis-server # 默认启动
-
redis-server confFileName # 根据配置文件的设置启动 远程
-
# 客户端
-
redis-cli # 默认连接本地, 绑定了6379默认端口的服务器
-
redis-cli -p 端口号
-
redis-cli -h IP地址 -p 端口 # 连接远程主机的指定端口的redis
-
# 通过客户端关闭服务器
-
shutdown
-
# 客户端的测试命令
-
ping [MSG]
redis中数据的组织格式
-
键值对
-
key: 必须是字符串 - "hello"
-
value: 可选的
-
String类型
-
List类型
-
Set类型
-
SortedSet类型
-
Hash类型
-
-
redis中常用数据类型
-
String类型
-
字符串
-
-
List类型
-
存储多个string字符串的
-
-
Set类型
-
集合
-
stl集合
-
默认是排序的, 元素不重复
-
-
redis集合
-
元素不重复, 数据是无序的
-
-
-
-
SortedSet类型
-
排序集合, 集合中的每个元素分为两部分
-
[分数, 成员] -> [66, ''tom'']
-
-
-
Hash类型
-
跟map数据组织方式一样: key:value
-
Qt -> QHash, QMap
-
Map -> 红黑树
-
hash -> 数组
-
a[index] = xx
-
-
-
2.2 redis常用命令
String类型
-
key -> string
-
value -> string
-
# 设置一个键值对->string:string
-
SET key value
-
# 通过key得到value
-
GET key
-
# 同时设置一个或多个 key-value 对
-
MSET key value [key value ...]
-
# 同时查看过个key
-
MGET key [key ...]
-
# 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾
-
-
APPEND key value
-
# 返回 key 所储存的字符串值的长度
-
STRLEN key
-
# 将 key 中储存的数字值减一。
-
# 前提, value必须是数字字符串 -"12345"
-
DECR key
List类型 - 存储多个字符串
-
key -> string
-
value -> list
-
# 将一个或多个值 value 插入到列表 key 的表头
-
LPUSH key value [value ...]
-
# 将一个或多个值 value 插入到列表 key 的表尾 (最右边)。
-
RPUSH key value [value ...]
-
-
LPOP key # 删除最左侧元素
-
RPOP key # 删除最右侧元素
-
# 遍历
-
LRANGE key start stop
-
start: 起始位置, 0
-
stop: 结束位置, -1
-
# 通过下标得到对应位置的字符串
-
LINDEX key index
-
-
LLEN key
Set类型
-
key -> string
-
value -> set类型 ("string", "string1")
-
# 添加元素
-
# 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略
-
SADD key member [member ...]
-
# 遍历
-
SMEMBERS key
-
# 差集
-
SDIFF key [key ...]
-
# 交集
-
SINTER key [key ...]
-
# 并集
-
SUNION key [key ...]
SortedSet 类型
-
key -> string
-
value -> sorted ([socre, member], [socre, member], ...)
-
# 添加元素
-
ZADD key score member [[score member] [score member] ...]
-
# 遍历
-
ZRANGE key start stop [WITHSCORES] # -> 升序集合
-
ZREVRANGE key start stop [WITHSCORES] # -> 降序集合
-
# 指定分数区间内元素的个数
-
ZCOUNT key min max
Hash类型
-
key ->string
-
value -> hash ([key:value], [key:value], [key:value], ...)
-
# 添加数据
-
HSET key field value
-
# 取数据
-
HGET key field
-
# 批量插入键值对
-
HMSET key field value [field value ...]
-
# 批量取数据
-
HMGET key field [field ...]
-
# 删除键值对
-
HDEL key field [field ...]
Key 相关的命令
-
# 删除键值对
-
DEL key [key ...]
-
# 查看key值
-
KEYS pattern
-
查找所有符合给定模式 pattern 的 key 。
-
KEYS * 匹配数据库中所有 key 。
-
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
-
KEYS h*llo 匹配 hllo 和 heeeeello 等。
-
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
-
# 给key设置生存时长
-
EXPIRE key seconds
-
# 取消生存时长
-
PERSIST key
-
-
TYPE key
配置文件是给redis服务器使用 的
-
配置文件位置
-
从源码安装目录中找 -> redis.conf
-
-
配置文件配置项
-
# redis服务器绑定谁之后, 谁就能访问redis服务器
-
# 任何客户端都能访问服务器, 需要注释该选项
-
bind 127.0.0.1 192.168.1.100
-
# 保护模式, 如果要远程客户端访问服务器, 该模式要关闭
-
protected-mode yes
-
# reids服务器启动时候绑定的端口, 默认为6379
-
port 6379
-
# 超时时长, 0位关闭该选项, >0则开启
-
timeout 0
-
# 服务器启动之后不是守护进程 一般会使用yes 让其为守护进程
-
daemonize yes
-
# 如果服务器是守护进程, 就会生成一个pid文件
-
# ./ -> reids服务器启动时候对应的目录
-
pidfile ./redis.pid
-
# 日志级别
-
loglevel notice
-
# 如果服务器是守护进程, 才会写日志文件
-
logfile "" -> 这是没写
-
logfile "./redis.log" //打印的是终端的信息
-
# redis中数据库的个数 默认是16个 类似于mysql中的database
-
databases 16
-
- 切换 select dbID [dbID == 0 ~ 16-1]
2.4 redis数据持久化
持久化: 数据从内存到磁盘的过程 关机之后内存的数据释放了 但是存在磁盘上 下次可以直接读取磁盘的数据
持久化的两种方式: rgb和aof两种方式
rgb数据完整性较低 但效率高 aof数据完整性高 但效率低
-
rdb方式
-
这是一种默认的持久化方式, 默认打开
-
磁盘的持久化文件xxx.rdb
-
将内存数据以二进制的方式直接写入磁盘文件
-
文件比较小, 恢复时间短, 效率高
-
以用户设定的频率 -> 容易丢失数据
-
数据完整性相对较低
-
-
aof方式
-
默认是关闭的
-
磁盘的持久化文件xxx.aof
-
直接将生成数据的命令写入磁盘文件
-
文件比较大, 恢复时间长, 效率低
-
以某种频率 -> 1sec
-
数据完整性高
-
-
# rdb的同步频率, 任意一个满足都可以
-
save 900 1 //900s发生1次改变
-
save 300 10 //300发生10次改变
-
save 60 10000
-
# rdb文件的名字
-
dbfilename dump.rdb
-
-
-
# 生成的持久化文件保存的那个目录下, rdb和aof
-
dir ./
-
-
# 是不是要打开aof模式
-
appendonly no
-
-> 打开: yes
-
# 设置aof文件的名字
-
appendfilename "appendonly.aof"
-
# aof更新的频率
-
# appendfsync always
-
appendfsync everysec
-
# appendfsync no
-
aof和rdb能不能同时打开?
-
可以
-
-
aof和rdb能不能同时关闭?
-
可以
-
rdb如何关闭?
save ""
-
-
两种模式同时开启, 如果要进行数据恢复, 如何选择?
-
效率上考虑: rdb模式
-
数据的完整性: aof模式
-
3 hiredis的使用
-
hiredis的安装
-
安装
-
make
-
make
-
-
hiredis API接口的使用
连接数据库
-
// 连接数据库
-
redisContext *redisConnect(const char *ip, int port);
-
redisContext *redisConnectWithTimeout(const char *ip,
-
int port, const struct timeval tv);
执行redis命令函数
-
// 执行redis命令
-
void *redisCommand(redisContext *c, const char *format, ...);
-
-
//虽然返回的是void *实际上是redisply类型
-
// redisCommand 函数实际的返回值类型
-
typedef struct redisReply {
-
/* 命令执行结果的返回类型 */
-
int type;
-
/* 存储执行结果返回为整数 */
-
long long integer;
-
/* str变量的字符串值长度 */
-
size_t len;
-
/* 存储命令执行结果返回是字符串, 或者错误信息 */
-
char *str;
-
/* 返回结果是数组, 代表数据的大小 */
-
size_t elements;
-
/* 存储执行结果返回是数组*/
-
struct redisReply **element;
-
} redisReply;
-
-
//访问数组里面的元素
-
redisReply a[100];
-
element[i]->str
-
-
//根据类型取出对应的值
-
type为类型
type状态表示 | 含义 |
---|---|
REDIS_REPLY_STRING==1 | 返回值是字符串,字符串储存在redis->str当中,字符串长度为redi |
REDIS_REPLY_ARRAY== 2 | 返回值是数组,数组大小存在redis->elements里面,数组值存储在redis->element[i]里面。数组里面存储的是指向redisReply的指针,数组里面的返回值可以通过redis->element[i]->str来访问,数组的结果里全是type==REDIS_REPLY_STRING的redisReply对象指针。 |
REDIS_REPLY_INTEGER == 3 | 返回整数long long,从integer字段获取值 |
REDIS_REPLY_NIL==4 | 返回值为空表示执行结果为空 |
REDIS_REPLY_STATUS ==5 | 返回命令执行的状态,比如set foo bar 返回的状态为OK,存储在str当中 reply->str == "OK" 。 |
REDIS_REPLY_ERROR ==6 | 命令执行错误,错误信息存放在 reply->str当中。 |
释放资源
-
// 释放资源
-
void freeReplyObject(void *reply);
-
void redisFree(redisContext *c);
案列代码
-
-
-
-
int main()
-
{
-
// 1. 连接redis服务器
-
redisContext* c = redisConnect("127.0.0.1", 6379);
-
if (c->err != 0)
-
{
-
return -1;
-
}
-
// 2. 执行redis命令
-
void *prt = redisCommand(c, "hmset user userName zhang3 passwd 123456 age 23 sex man");
-
redisReply* ply = (redisReply*)prt;
-
if(ply->type == 5)
-
{
-
// 状态输出
-
printf("状态: %s\n", ply->str);
-
}
-
freeReplyObject(ply);
-
-
// 3. 从数据库中读数据
-
prt = redisCommand(c, "hgetall user");
-
ply = (redisReply*)prt;
-
if(ply->type == 2)
-
{
-
// 遍历
-
for(int i=0; i<ply->elements; i =2)
-
{
-
printf("key: %s, value: %s\n", ply->element[i]->str, ply->element[i 1]->str);
-
}
-
}
-
freeReplyObject(ply);
-
-
redisFree(c);
-
return 0;
-
}
4. 复习
fastDFS
-
是什么?
-
分布式文件系统
-
-
干什么?
-
提供文件上传
-
提供文件下载
-
-
怎么使用?
-
根据主机的角色 -> 修改对应的配置文件
-
启动各个角色
-
-
fdfs_trackerd /etc/fdfs/tracker.conf
-
fdfs_storaged /etc/fdfs/storage.conf
-
客户端编写
-
-
![1531272014374](1531272014374.png)
-
-
- 操作步骤
-
-
1. 创建管道 - pipe
-
2. 创建子进程
-
3. 子进程干什么?
-
-
- 写管道, 关闭读端
-
- 将标准输出 -> 管道的写端
-
- 重定向
-
- 执行execl命令, 调用另外的进程fdfs_upload_file
-
- 子进程退出
-
4. 父进程?
-
- 读管道, 关闭写端
-
- 释放子进程资源 - pcb
-
- wait()/ waitpid()
实现代码
fdfs.upload_file.h
-
-
-
-
int upload_file1(const char *configfile, const char * myfile,char * fileid);
-
int upload_file2(const char * configFile, const char * upLoadFile, char * fileid, int size);
-
-
fdfs.upload_file.c
-
-
-
-
-
-
-
-
-
-
-
-
-
//第一种方法 改写源码 将其改为底层可用
-
int upload_file1(const char *configfile, const char * myfile,char * fileid)
-
{
-
char group_name[FDFS_GROUP_NAME_MAX_LEN 1];
-
ConnectionInfo *pTrackerServer;
-
int result;
-
int store_path_index;
-
ConnectionInfo storageServer;
-
-
if ((result=fdfs_client_init(configfile)) != 0)
-
{
-
return result;
-
}
-
-
pTrackerServer = tracker_get_connection();
-
if (pTrackerServer == NULL)
-
{
-
fdfs_client_destroy();
-
return errno != 0 ? errno : ECONNREFUSED;
-
}
-
-
*group_name = '\0';
-
if ((result=tracker_query_storage_store(pTrackerServer, \
-
&storageServer, group_name, &store_path_index)) != 0)
-
{
-
fdfs_client_destroy();
-
fprintf(stderr, "tracker_query_storage fail, " \
-
"error no: %d, error info: %s\n", \
-
result, STRERROR(result));
-
return result;
-
}
-
-
result = storage_upload_by_filename1(pTrackerServer, \
-
&storageServer, store_path_index, \
-
myfile, NULL, \
-
NULL, 0, group_name, fileid);
-
if (result == 0)
-
{
-
printf("%s\n", fileid);
-
}
-
else
-
{
-
fprintf(stderr, "upload file fail, " \
-
"error no: %d, error info: %s\n", \
-
result, STRERROR(result));
-
}
-
-
tracker_disconnect_server_ex(pTrackerServer, true);
-
fdfs_client_destroy();
-
-
return result;
-
}
-
-
//第二种方法 使用execlp
-
//使用多进程实现
-
int upload_file2(const char * configFile, const char * upLoadFile, char * fileid, int size)
-
{
-
//1、创建管道
-
int fd[2];
-
int ret = pipe(fd);
-
if (ret == -1)
-
{
-
perror("pipe error");
-
return -1;
-
}
-
-
//2、创建子线程
-
pid_t pid = fork();
-
//如果是子线程
-
if(pid == 0)
-
{
-
//3、重定向到管道的写端 old,new
-
dup2(fd[1], STDIN_FILENO);
-
-
//关闭读端
-
close(fd[0]);
-
-
//执行exclp命令
-
execlp("file_upload_file", "xxx", configFile, upLoadFile, NULL);
-
perror("execlp error");
-
}
-
else
-
{
-
//关闭写端
-
close(fd[1]);
-
-
//读取数据 将数据读出到fileid参数中
-
char buf[1024];
-
read(fd[0], fileid, size);
-
-
//回收子进程
-
wait(NULL);
-
}
-
}
main.c
-
-
-
-
-
-
-
-
//查找位置 在编译时加上
-
//find / -name "fdfs_client.h"
-
-
int main(int argc, char **argv[])
-
{
-
char fileID[1024];
-
upload_file1("/etc/fdfs/client.conf", "main.c", fileID);
-
printf("fileID: %s\n", fileID);
-
printf("================================================================\n");
-
-
upload_file2("/etc/fdfs/client.conf", "main.c", fileID, sizeof(fileID));
-
printf("fileID: %s\n", fileID);
-
return 0;
-
};
执行 需要找到头文件和库
gcc *.c -I /usr/include/fastdfs -I /usr/include/fastcommon/ -lfdfsclient
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgaffac
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01