前言:
现时我们对“云计算php”可能比较珍视,小伙伴们都想要剖析一些“云计算php”的相关资讯。那么小编同时在网上收集了一些关于“云计算php””的相关资讯,希望大家能喜欢,大家一起来学习一下吧!Redis数据库
进度数据池和状态数据池的读写频率较高,且一般不需要保证数据的持久性,所以选用内存数据库比较合适。而相对于Memcached,Redis支持更多的数据结构和模式,对未知应用场景的包容性会更强一些。因此,Redis比较适合作为进度数据池与状态数据池的载体。下面将对Redis进行详细讲解。
说明:一般情况下,进度数据池和状态数据池中的数据更新频率是较高的,且新数据会覆盖旧数据,即使旧数据丢失,新的数据也会在最多几秒后产生。因此,进度数据池和状态数据池中的数据一般不需要保证持久性。另外,比较重要的数据需要通过定时任务定时写到磁盘数据库中。
Redis(Remote Dictionary Server,远程字典服务)是一个开源的键值(Key-Value)存储非关系型数据库,其数据按照“键值对”的形式进行组织、索引和存储。Redis的数据存储在内存当中,所以Redis的读写效率非常高。另外,Redis还支持消息订阅等功能。
Redis本身是一个独立软件,第三方软件需要与Redis建立通信后才能使用Redis。与Redis建立连接后,第三方软件可以向Redis发送操作指令,Redis处理完指令后会返回处理结果,如图5.28所示。
1.Redis的基本操作
Redis的基本操作如代码5.19所示,包括创建与销毁连接、发送指令、返回结果处理和释放结果变量。Redis的指令与SQL类似,都是语句指令,只是Redis的指令远没有SQL丰富。需要注意的是,Redis不支持根据存储值的关键字查询。
说明:以下示例代码是使用C++编写的,除了C++以外,Redis还支持其他语言,如Python、Java、Ruby、PHP等。虽然实际使用的开发语言不尽相同,但调用方式是大同小异的。
代码5.19 Redis的基本操作
//Redis相关头文件,需要先安装相关的库(libhiredis-dev)
#include <hiredis/hiredis.h>
//定义连接变量,connecton为连接变量,与Redis通信都需要加上此变量
redisContext *connection;
//创建与销毁连接
//创建连接,需要Redis的IP地址与端口,6379为Redis的默认端口
connection = redisConnect ("IP地址", 6379);
if (connection == NULL || connect->err) {
//发生错误
}
//密码认证(实际上是发送了一条指令),无密码时无须调用
redisReply *reply = (redisReply *)redisCommand(connection, "AUTH %s",
"Redis密码");
if (reply->type == REDIS_REPLY_ERROR) {
//发生错误
}
//断开连接
redisFree(connection);
//发送指令
//向Redis发送指令,"Redis Command"为具体指令
redisReply *reply = (redisReply *)redisCommand(connection, "Redis
Common");
//返回结果处理
//通用说明:指令返回值处理,指令返回值会放到一个结构体变量中
redisReply *reply; //接收指令结果的变量//不同指令会返回不同的结果,根据reply->type判断
if(type->type == REDIS_REPLY_STRING){ //返回字符串
reply->str; //结果字符串的开始指针(char *)
reply->len; //结果字符串的长度
}
if(type->type == REDIS_REPLY_ARRAY){ //返回数组
for(int index = 0; index < reply->elements; index++){ //遍历数组
//获取数组中单个值
redisReply *tempReply = reply->element[index];
…
}
}
if(type->type == REDIS_REPLY_INTEGER){ //返回数字
reply->integer; //数字结果(long long)
}
if(type->type == REDIS_REPLY_NIL){ //无返回值
}
if(type->type == REDIS_REPLY_STATUS){ //返回状态
reply->str; //状态字符串的开始指针(char *)
reply->len; //状态字符串的长度
}
if(type->type == REDIS_REPLY_ERROR){ //发生错误
reply->str; //状态字符串的开始指针(char *)
reply->len; //状态字符串的长度
}
//释放结果变量
freeReplyObject(reply);
2.Redis的数据类型
Redis的数据都是以“键值对”的形式存储的,如图5.29所示。其中,“键值对中的键”是字符串,而“键值对中的值”支持多种数据类型,包括字符串、哈希表、列表、集合和有序集合。
(1)键(Key)。键是负责标识数据的字符串。在Redis中,键是唯一的,如果使用相同的键存储不同的数据,那么后存储的数据会覆盖先存储的数据。键的常用操作如代码5.20所示,其中,返回结果的处理方式请参考代码5.19。
代码5.20 键的常用操作
//删除键,指令:DEL key
const char* key = "键的名称";
redisReply *reply = (redisReply *)redisCommand(connection, "DEL %s", key);
//检查键是否存在,指令:EXISTS key
const char* key = "键的名称";
redisReply *reply = (redisReply *)redisCommand(connection, "EXISTS %s", key);
//设置键的过期时间(
ms),指令:PEXPIRE key milliseconds
const char* key = "键的名称";
int milliseconds = 1000; //1000ms后过期
redisReply *reply = (redisReply *)redisCommand(connection, "PEXPIRE %s %d",
key, milliseconds);
//检索给定模式的键,指令:KEYS patternconst char* pattern = "abc*"; //可以添加通配符
redisReply *reply = (redisReply *)redisCommand(connection, "KEYS %s", key);
//修改键名称,指令:RENAME key newkey
const char* oldkey = "旧键名称";
const char* newkey = "新键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "RENAME %s %s",
oldkey, newkey);
(2)字符串(String)。字符串是数据的基本类型。Redis中的字符串是二进制安全的,也就是说,任意数据可以转换成字符串存储到Redis中,当该字符串被获取并重新转换成原本的数据格式时,数据不会产生偏差。通过这一特性,将JSON格式的数据转换成字符串后,即可存入Redis。字符串类型数据的常用操作如代码5.21所示,其中,返回结果的处理方式请参考代码5.19。
代码5.21 字符串类型数据的常用操作
//设置字符串的值,指令:SET key value
const char* key = "数据的键名称";
const char* value = "值";
redisReply *reply = (redisReply *)redisCommand(connection, "SET %s %s",
key, value);
//获取字符串的值,指令:GET key
const char* key = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "GET %s",
key);
(3)哈希表(Hash)。哈希表是字符串的“键值对”,哈希表的应用场景是存储一些结构化的数据,例如存储个人信息(包含用户名、年龄、性别等信息)。哈希表类型数据的常用操作如代码5.22所示,其中,返回结果的处理方式请参考代码5.19。
代码5.22 哈希表类型数据的常用操作
//设置哈希表中的值,指令:HSET key field value
const char* key = "数据的键名称";
const char* field = "哈希表的键名称";
const char* value = "哈希表的值";
redisReply *reply = (redisReply *)redisCommand(connection, "HSET %s %s
%s",key, field, value);
//获取哈希表中的值,指令:HGET key field
const char* key = "数据的键名称";
const char* field = "哈希表的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "HGET %s %s",
key, field);
//删除哈希表中的值,指令:HDEL key field
const char* key = "数据的键名称";
const char* field = "哈希表的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "HDEL %s %s",
key, field);
//在哈希表中查看键是否存在,指令:HEXISTS key field
const char* key = "数据的键名称";
const char* field = "哈希表的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "HEXISTS %s
%s", key, field);
//获取哈希表中的所有键,指令:HKEYS key
const char* key = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "HKEYS %s",
key);
(4)列表(List)。列表是字符串的列表,其顺序是按插入顺序排列的,插入新数据时,可以选择将数据添加到列表的头部(左)或者末尾(右)。列表中的字符串是可以重复的。列表类型数据的常用操作如代码5.23所示,其中,返回结果的处理方式请参考代码5.19。
代码5.23 列表类型数据的常用操作
//在列表的头部添加一个值,指令:LPUSH key value
const char* key = "数据的键名称";
const char* value = "值";
redisReply *reply = (redisReply *)redisCommand(connection, "LPUSH %s
%s", key, value);
//在列表的末尾添加一个值,指令:RPUSH key value
const char* key = "数据的键名称";
const char* value = "值";
redisReply *reply = (redisReply *)redisCommand(connection, "RPUSH %s
%s", key, value);
//获取并移除列表中的第一个值,指令:LPOP key value
const char* key = "数据的键名称";redisReply *reply = (redisReply *)redisCommand(connection, "LPOP %s %s",
key, value);
//获取并移除列表中的最后一个值,指令:RPOP key value
const char* key = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "RPOP %s %s",
key, value);
//通过索引获取列表的值,指令:LINDEX key index
const char* key = "数据的键名称";
int index = 2; //索引
redisReply *reply = (redisReply *)redisCommand(connection, "LINDEX %s
%d", key, index);
(5)集合(Set)。集合是字符串的无序集合,集合中不能存储重复的字符串。使用集合的好处是可以进行交集、合集、差集等操作,例如利用集合的交集求共同的好友等。集合类型数据的常用操作如代码5.24所示,其中,返回结果的处理方式请参考代码5.19。
代码5.24 集合类型数据的常用操作
//向集合添加值,指令:SADD key value
const char* key = "数据的键名称";
const char* value = "值";
redisReply *reply = (redisReply *)redisCommand(connection, "SADD %s %s",
key, value);
//获取集合中的所有成员,指令:SMEMBERS key
const char* key = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "SMEMBERS %s ",
key);
//判断元素是否在集合当中,指令:SISMEMBER key value
const char* key = "数据的键名称";
const char* value = "需要判断的值";
redisReply *reply = (redisReply *)redisCommand(connection, "SISMEMBER
%s %s",
key, value);
//获取多个集合的交集,指令:SINTER key1 [key2]
const char* key1 = "数据的键名称";
const char* key2 = "数据的键名称";
const char* key3 = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "SINTER %s
%s %s",
key1, key2, key3);//获取多个集合的交集并存储在新的键中,指令:SINTERSTORE destination key1 [key2]
const char* destination = "存储的键名称"
const char* key1 = "数据的键名称";
const char* key2 = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "SINTERSTORE
%s %s %s",
destination, key1, key2);
//获取多个集合的合集,指令:SUNION key1 [key2]
const char* key1 = "数据的键名称";
const char* key2 = "数据的键名称";
const char* key3 = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "SUNION %s
%s %s",
key1, key2, key3);
//获取多个集合的合集并存储在新的键中,指令:SUNIONSTORE destination key1 [key2]
const char* destination = "存储的键名称"
const char* key1 = "数据的键名称";
const char* key2 = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "SUNIONSTORE
%s %s %s",
destination, key1, key2);
//获取多个集合的差集,指令:SDIFF key1 [key2]
const char* key1 = "数据的键名称";
const char* key2 = "数据的键名称";
const char* key3 = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "SDIFF %s %s
%s",
key1, key2, key3);
//获取多个集合的差集并存储在新的键中,指令:SDIFFSTORE destination key1 [key2]
const char* destination = "存储的键名称"
const char* key1 = "数据的键名称";
const char* key2 = "数据的键名称";
redisReply *reply = (redisReply *)redisCommand(connection, "SDIFFSTORE
%s %s %s",
destination, key1, key2);
(6)有序集合(Set)。有序集合是字符串的有序集合。有序集合与集合的区别是,有序集合的值都会关联一个浮点(double)类型的分数,Redis会按照分数对有序集合中的值进行自动排序。有序集合中不能存储重复的字符串,但分数是可以重复的。有序列表的应用场景是一些需要自动排序的场景,例如,获取成绩前十的学生姓名,有序集合的值为学生姓名,而分数为成绩。有序集合类型数据的常用操作如代码5.25所示,其中,返回结果的处理方式请参考代码5.19。
代码5.25 有序集合类型数据的常用操作
//向有序集合添加值,指令:ZADD key score value
const char* key = "数据的键名称";
const char* score = "分数"; //分数为浮点型,如14.32
const char* value = "值";
redisReply *reply = (redisReply *)redisCommand(connection, "ZADD %s %s
%s ",
key, score, value);
//移除有序集合中的值,指令:ZREM key value
const char* key = "数据的键名称";
const char* value = "值";
redisReply *reply = (redisReply *)redisCommand(connection, "ZREM %s %s",
key, value);
//增加有序集合中值的分数,指令:ZINCRBY key increment value
const char* key = "数据的键名称";
const char* increment = "增加的分数"; //分数为浮点型,负数时为减
const char* value = "值";
redisReply *reply = (redisReply *)redisCommand(connection, " ZINCRBY %s
%s %s ",
key, increment, value);
//获取有序集合中指定分数区间的值,指令:ZREVRANGEBYSCORE key min max
const char* destination = "存储的键名称"
const char* key = "数据的键名称";
const char* min = "下限分数"; //分数为浮点型
const char* max = "上限分数"; //分数为浮点型
redisReply *reply = (redisReply *)redisCommand(connection,
"ZREVRANGEBYSCORE
%s %s %s",
key, min, max);
//获取有序集合中指定值的分数,指令:ZSCORE key value
const char* key = "数据的键名称";
const char* value = "值";
redisReply *reply = (redisReply *)redisCommand(connection, "ZSCORE %s
%s", key, value);
3.Redis的发布订阅模式
Redis除了提供数据存储功能以外,还支持消息发布订阅模式。Redis的消息发布订阅模式可以充当消息队列,发布者向Redis的指定频道发送消息后,订阅该频道的订阅者都会收到消息。但Redis的发布订阅模式提供的功能相当简单,与RabbitMQ相比,其不支持消息确认和消息持久化等功能。另外,订阅者只能收到订阅时间节点以后发送的消息。
因此,Redis提供的发布订阅功能一般是不被提倡使用的,除非应用场景非常简单,且发布出去的消息允许丢失。
本文给大家讲解的内容是云计算服务架构:进度数据池与状态数据池的搭建和使用,Redis数据库下篇文章给大家讲解的内容是云计算服务架构:进度数据池与状态数据池的搭建和使用感谢大家的支持!
标签: #云计算php