redis持久化(persistence)
redis支持两种方式的持久化,可以单独使用或者结合起来使用。
第一种:RDB方式(redis默认的持久化方式)
rdb方式的持久化是通过快照完成的,当符合一定条件时redis会自动将内存中的所有数据执行快照操作并存储到硬盘上。默认存储在dump.rdb文件中。(文件名在配置文件中dbfilename)
redis进行快照的时机(在配置文件redis.conf中)
save 900 1 //表示900秒内至少一个键被更改则进行快照。
save 300 10 //表示300秒内10条被更改则快照
save 60 10000 //60秒内10000条
第二种:AOF方式
aof方式的持久化是通过日志文件的方式。默认情况下redis没有开启aof,可以通过参数appendonly参数开启。
appendonly yes
aof文件的保存位置和rdb文件的位置相同,都是dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改
appendfilename appendonly.aof
redis写命令同步的时机
appendfsync always 每次都会执行
appendfsync everysec 默认 每秒执行一次同步操作(推荐,默认)
appendfsync no不主动进行同步,由操作系统来做,30秒一次
宝塔设置:
redis中键的生存时间(expire)
class Myredis{
protected $redis;
public function __construct() {
//实例化Redis类
$redis = new Redis();
//选择指定的redis数据库连接,默认端口号为6379
$redis->connect('127.0.0.1',6379);
$this->redis = $redis;
}
public function expire(string $name,int $expire){
$this->redis->expire($name, $expire);
// $redis->ttl(‘foo’); //返回有效期值1s
// $redis->expire(‘foo’); //取消expire行为
}
}
$redis = new Myredis();
$redis->expire("name",10); //(单位/秒)
redis的事务(transaction)
public function transaction(){
//Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
/**
//1 Redis事务没有隔离级别
$this->redis->multi();
$this->redis->decrby("number",10);
//发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。
if($this->redis->get("number") < 0){
return $this->redis->discard();
}
$this->redis->incrby("number2",10);
$this->redis->exec(); //number:-10, number2:10
*/
/**
//2 Redis不保证原子性
//Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。
$this->redis->multi();
$this->redis->decrby("number",10);
$this->redis->incrby("number2",10,21,321); //err
$this->redis->incrby("number3",10);
$this->redis->exec(); //number:-10, number3: 10
//Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。
*/
// Watch 命令用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断
$this->redis->watch('number');
sleep(10); //期间改掉number,下面的命令都不会执行
$this->redis->multi();
$this->redis->set('favorite_fruit','cherry');
$this->redis->incrBy('number',3);
$this->redis->exec();
}
$redis->transaction();
发布/订阅
//调用
public function Publish_Subscribe(){
//通过订阅/发布,添加数据库数据。 tb_people表
$channelName = "tb_people";
//向指定频道发送消息
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
for ($i=0;$i<5;$i++){
$data = array('name' => 'key'.$i);
$ret = $redis->publish($channelName, json_encode($data));
print_r($ret);
}
} catch (Exception $e){
echo $e->getMessage();
}
}
xxxx.php:单独起个php文件,订阅信息
<?php
//设置php脚本执行时间
set_time_limit(0);
//设置socket连接超时时间
ini_set('default_socket_timeout', -1);
$servername = "localhost";
$username = "root";
$password = "root";
try {
$conn = new PDO("mysql:host=$servername;dbname=my_mysql;port=3306", $username, $password);
// echo "连接成功";
}catch(PDOException $e){
echo $e->getMessage();
}
//声明测试频道名称
$channelName = "tb_people";
try {
$redis = new Redis();
//建立一个长链接
$redis->pconnect('127.0.0.1', 6379);
//阻塞获取消息
$redis->subscribe(array($channelName), function ($redis, $chan, $msg) use($conn){
// echo "channel:".$chan.",message:".$msg."\n";
$arr_msg = json_decode($msg,true);
$sqlquery = "INSERT INTO tb_people (name)
VALUES ('".$arr_msg['name']."')";
$conn->query($sqlquery);
echo "成功";
});
} catch (Exception $e){
echo $e->getMessage();
}
mysql_close($con);