Redis相关知识:https://www.runoob.com/redis/redis-tutorial.html
Github:https://github.com/phpredis/phpredis#close
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。 string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。 string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
SET dog "憨皮"
GET dog
DEL dog
Redis hash 是一个键值(key=>value)对集合。 Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。 每个 hash 可以存储 232 -1 键值对(40多亿)。
HMSET runoob field1 "Hello" field2 "World"
HGET runoob field1
DEL runoob [hashkey]
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
LPUSH runoobkey redis
LPUSHX runoobkey redis
LRANGE runoobkey 0 10
DEL redis
Redis 的 Set 是 string 类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
sadd runoob rabbitmq #成功返回1,失败返回0
smembers runoob
Del
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 zset的成员是唯一的,但分数(score)却可以重复。
补充
官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。
Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概念。
Redis是一个字典结构的存储服务器,而实际上一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与我们熟知的在一个关系数据库实例中可以创建多个数据库类似,所以可以将其中的每个字典都理解成一个独立的数据库。
每个数据库对外都是一个从0开始的递增数字命名,Redis默认支持16个数据库(可以通过配置文件支持更多,无上限),可以通过配置databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数据库
redis命令大全:https://redis.io/commands/、http://www.redis.cn/
redis数据库相关参考,命令行连上的默认为0号数据库:https://www.runoob.com/redis/redis-data-types.html
$ wget http://download.redis.io/releases/redis-3.2.8.tar.gz
$ tar -xzf redis-3.2.8.tar.gz
$ cd redis-3.2.8
$ make
编译完成后,在src目录下,有四个可执行文件redis-server、redis-benchmark、redis-cli和redis.conf。
redis.config在src所在的目录下,redis的安装目录就是make所在的目录。
执行文件详解:https://blog.csdn.net/baidu_41388533/article/details/108438878
Redis配置文件详解:https://www.runoob.com/redis/redis-conf.html
将上面提到的可执行文件移动到任意目录,然后执行,例如:
$ /usr/redis/redis-server /usr/redis/redis.conf
后台运行redis,将配置文件中daemonize no,改为daemonize yes,再启动即可。
参考文章:https://www.cnblogs.com/ygw1010/p/7446003.html
make命令:https://www.cnblogs.com/linshengqian/p/15585858.html
Github:https://github.com/phpredis/phpredis
$ wget https://github.com/phpredis/phpredis/archive/3.1.4.tar.gz
$ tar zxvf 3.1.4.tar.gz # 解压
$ cd phpredis-3.1.4 # 进入 phpredis 目录
$ /usr/local/php/bin/phpize # php安装后的路径
$ ./configure --with-php-config=/usr/local/php/bin/php-config
$ make && make install
修改php.ini,加入extension=redis.so;重启LNMP,大功告成。
PHP Redis相关操作方法:https://www.cnblogs.com/githup/p/13397405.html
PHP保存数组到Redis,先json或者序列化存入,取回来再反序列化,json解码。
[root@localhost ~]# which Redis
/usr/local/redis #redis安装目录
#查看redis进程
ps -aux | grep redis
#或者
ps -ef|grep redis
#假设得到redis的进程号123,然后使用以下命令查看安装位置。
ll /proc/123/cwd
<?php
/*连接本地的 Redis 服务*/
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
echo "Connection to server successfully";
/*查看服务是否运行*/
echo "Server is running: " . $redis->ping();
?>
提示
connect:脚本结束之后连接就释放了。 pconnect:脚本结束之后连接不释放,连接保持在php-fpm进程中。 所以使用pconnect代替connect,可以减少频繁建立redis连接的消耗。
cd打开redis.cli所在目录,然后输入命令进行连接:redis-cli -h 127.0.0.1 -p 6379,以下为常用命令:
1.缓存、2.数据共享分布式、3.分布式锁、4.全局ID、5.计数器、6.限流、7.位统计、8.购物车、9.用户消息时间线timeline、10.消息队列、11.抽奖、12.点赞、签到、打卡、13.商品标签、14.商品筛选、15.用户关注、推荐模型、16.排行榜
相关参考:
https://zhuanlan.zhihu.com/p/484345565 https://www.lanmper.cn/redis
参考文章:https://www.php.cn/redis/437105.html
例如
$redis->setex('key', 3600, 'value'); // setex 带生存时间的写入值
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
#根据频道名字订阅
SUBSCRIBE Channel Channel ...
#指定匹配规则订阅,可以使用*通配符
PSUBSCRIBE pattern [pattern ...]
#退订指定频道。
UNSUBSCRIBE Channel Channel ...
#退订所有给定模式的频道。
PUNSUBSCRIBE [pattern [pattern ...]]
#将信息发送到指定的频道。
PUBLISH channel message
Redis可以提供基本的发布订阅功能,但毕竟不像消息队列那种专业级别,所以会存在以下缺点:
PHP redis订阅
PHP调用订阅命令后将进入阻塞状态,除了退出无法主动取消。在swoole协程中可以通过主动取消协程中断订阅,然后在defer回调内close关闭redis,取消订阅
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
一个事务从开始到执行会经历以下三个阶段: 开始事务 -> 命令入队 -> 执行事务。
redis事务相关的命令如下:
注意
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED
redis 127.0.0.1:6379> GET book-name
QUEUED
redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED
redis 127.0.0.1:6379> SMEMBERS tag
QUEUED
redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
2) "C++"
3) "Programming"
try {
//监视一个(或多个)key,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断
$redis->watch(array($key1, $key2));
//模拟监视 key 被打断
//$redis->set($key1, '12345');
$redis->multi();
$redis->set($key1, '1123');
$redis->set($key2, '2123');
//执行事务块内的所有命令
$status = $redis->exec();
//失败则取消事务
if (!$status) {
$redis->discard();
}
} catch (Exception $e){
echo $e->getMessage();
exit;
}
“消息队列”是在消息的传输过程中保存消息的容器。“消息”是在两台计算机间传送的数据单位。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。一般具有如下特点:
每个消费组都有一份消息队列中完整的消息,不同消费组之间消费进度彼此不受影响。
也就是说,消息队列中的一条消息被 Consumer Group1 消费过,也会再给 Consumer Group2 消费。 消费组中包含多个消费者,同一个组内的消费者是竞争消费的关系,每个消费者负责消费组 内的一部分消息。如果一条消息被消费者 Consumer1 消费了,那同组的其他消费者就不 会再收到这条消息。
例如一个抢购的场景,消息队列有100份消息,一个消费组内100个人进行消费。
相关参考:https://blog.csdn.net/z2431435/article/details/124978166
Redis SAVE 命令用于创建当前数据库的备份,命令基本语法如下:
redis 127.0.0.1:6379> SAVE
该命令将在 redis 安装目录中创建dump.rdb文件。
如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。获取 redis 目录可以使用 CONFIG 命令,如下所示:
redis 127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/redis/bin"
创建 redis 备份文件也可以使用命令 BGSAVE,该命令在后台执行。
UNIX Domain Socket是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC),它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程,当用户连接到Redis通过TCP/IP连接或Unix域连接,千兆网络的典型延迟大概200us,而Unix Domain Socket可能低到30us。
# 打开 redis.conf
# bind 127.0.0.1
port 0
unixsocket /tmp/redis.sock
unixsocketperm 700
提示
unixsocket选项没有默认值,不指定unixsocket就不会监听任何。如果不指定unixsocketperm,unix socket⽂件将使⽤默认权限(umask相关)
提示
如果PHP链接Redis报错Uncaught RedisException: Permission denied
,请将上方700改成777(或者查查SELinux)
<?php
$redis = new Redis();
$redis->connect("/tmp/redis.sock");
//命令行如下
redis-cli -s /tmp/redis.sock
Redis发展至今已历经7个大版本,而每个大版本都有大量的新特性产生。例如从3.0开始支持cluster集群模式;4.0开发的lazyfree和PSYNC2解决了Redis长久的大key删除阻塞问题及同步中断无法续传的问题;5.0新增了stream数据结构使Redis具备功能完整的轻量级消息队列能力;6.0更是发布了诸多企业级特性如threaded-io、TLS和ACL等,大幅提升了Redis的性能和安全性。
Redis社区目前主流维护版本是6.0,5.0版本已经进入低维护阶段,而国内还有大量2.8,3.0,4.0版本在使用中。这就很矛盾,一方面,一些对用法,性能,稳定性和抖动控制的能力都贡献在了新版本上,另一方面,国内用户却“看的到,用不上”。
除去6.0,7.0上的高级稳定性优化不说,比如在4.0前,没有lazyfree删除一个大key是同步的会卡住数据库引擎直接导致业务中断。又比如,Redis其实安全性尤其是lua是一直有较大问题的,这些升级也都“隐含”在了新版本中。
某日使用redis,通过setex设置键值,取出来的时候都是false;排查许久,设置前的变量是存在值的,setex返回的也是true;命令行取值发现确实是空;又排查了许久,难道同步的PHP代码,出现了JS那样的异步问题?又排查发现设置的时候键名后面有一个空格。。。。。
PHPredis默认连接60s,就超时关闭链接;如下设置为永不超时:
<?php
$redis->setOption(3, -1);
redis-cli -h 192.168.0.1 -a 123456 KEYS "newHand*" | xargs redis-cli -h 192.168.0.1 -a 123456 DEL