mysql和redis主从配置

mysql主服配置:

开启二进制日志,这是必须的

log-bin=mysql-bin //开启MYSQL二进制日志
server-id=1 //服务器ID不能重复
binlog-do-db=db1 //需要做主从备份的数据库名字,多个库只能定义多个属性,不能定义在一个属性里
binlog-do-db=db2
binlog-do-db=db3

添加一个供从服同步数据的账号

GRANT REPLICATION SLAVE ON *.* TO '帐号'@'从服务器IP' IDENTIFIED BY '密码';

重启主服

重启后,设为只读

FLUSH TABLES WITH READ LOCK;

查看并记录二进制文件和位置

show master status;

解除只读状态

UNLOCK TABLES;

开始配置从服务器

server-id=2 //服务器ID不能重复
master-port=3306 //主库的端口
replicate-do-db=db1 //需要做复制的数据库名,同样,多库要设置多个属性
replicate-ignore-table=db1.pre_common_session //自动跳过的表,session表没必要做复制
slave-skip-errors = 1032,1062,126,1114,1146,1048,1396 //自动跳过的错误代码,以防复制出错被中断

手动将主服上数据同步到从服

重启从服

mysql命令行执行

change master to master_host='主服ip', master_user='主服上同步账号', master_password='同步账号密码', master_log_file='主服二进制文件名', master_log_pos=position的值;

 

启动从服
start slave;

查看从服状态

show slave status;
 Slave_IO_Running | Slave_SQL_Running,这两个yes状态就是正常了,否则的话,查看具体error信息

编辑从服配置

master-host=192.168.1.2 //主库A的IP
master-user=rep //刚才在主库创建的帐号
master-password=123 //密码

redis主从设置

主服务器不需要做什么调整,直接在从服务器配置文件里,加上

slaveof 192.168.0.2  6379

从属于 主机ip 端口

redis持久化

redis持久化有两种方式,这里不详细介绍,我用的是默认方式,刚才重启服务器,发现没有载入持久文件,问题出在哪里呢?

出在配置文件上,配置文件指定的持久化dump.rdb文件,没指定路径,而安装的时候,是在安装目录直接启动redis服务的,所以持久化文件默认放在安装目录里,这次重启,rdb默认找到root目录了,没有找到rdb文件,当然就不会载入了,还好发现的早,修改配置文件,改成绝对路径,然后把安装目录下的rdb文件拷贝到指定目录,重启redis,一切恢复正常,中间丢了一点key,不过问题不大。

基于redis的缓存系统,防Dogpile效应

首先解释一下什么叫Dogpile效应,缓存顾名思义,只是暂缓存储,终归会失效的,问题就出在失效的那个时间点上,假设某应用,访问量为1000pv/s,某缓存直接读库需要5秒时间,那么在失效到完成读库重新缓存的这5秒时间里,瞬时产生了5000次读库请求,这是很苦B的,再假如,偏偏有多个缓存key在同一时间点失效,直接抓狂。

先定义cache类

<?php
class cache{
	private $redis = NULL;

	public function __construct(){
		// 应搞成单例类,这里偷懒一下,请自己完善
		$redis_host = '127.0.0.1';
		$redis_port = 6379;
		$redis = new Redis();
		$redis->connect($redis_host, $redis_port);
		$this->redis = $redis;
	}

	public function get($key){
		return $this->redis->get($key);
	}

	public function set($key,$value,$exp = 0){
		if($exp){
			return $this->redis->setex($key,$exp,$value);
		}else{
			return $this->redis->set($key,$value);
		}
	}

	// 这个方法是关键,加锁的关键方法,如果key有效,本方法会返回false
	public function setnx($key,$value,$exp = 0){
		$rs = $this->redis->setnx($key,$value);
		if($rs && $exp)
			$this->redis->expire($key,$exp);
		return $rs;
	}

	public function del($key){
		$this->redis->del($key);
	}
}

下面是应用实例

<?php
// 初始化cache实例
$cache = new cache();
// 获取一个key
$rs = $cache->get("testkey");
if($rs){
	// 匹配到,直接输出
	echo 'match:'.$rs;
}else{
	// 没匹配到,直接加锁,锁的有效时间根据具体应用确定
	$lock = $cache->setnx("lock.testkey",1,30);
	if($lock){
		// 这里只有失效后第一个访问才能进来,为了看到效果,休眠15秒,在这15秒内,其他访问都会到else里
		sleep(15);
		// 重新设置缓存
		$cache->set("testkey",2,60);
		// 删除锁
		$cache->del("lock.testkey");
		echo 'reset:2';
	}else{
		echo 'locked!';
		// 在缓存失效到重新缓存期间,这段时间的请求,就无法返回数据了,也不建议空等,最好直接返回相关错误提示,比如系统忙,稍后再试。
	}
}

 

一个高效的根据IP自动显示天气预报信息的案例

这个案例里使用的东西,在前几篇日记里已经陆续提供了,比如中国气象的json数据接口,中国气象地区编码库,iplocation以及redis等。

先简单介绍一下这个案例的技术要点。

首先要能高效快速获取一个ip地址的地区信息,这个有php的扩展iplocation,可以实现。http://www.hao535.com/archives/166

获得地区信息后,再通过中国气象的地区编码库,获得地区编码:http://www.hao535.com/archives/195

再通过中国气象的json数据接口获得天气数据,实际上整个案例效率最低的就是这步,这个接口连接比较慢,所以要加一层缓存,考虑到天气数据更新频率并不高,一天可能就更新2、3次吧,缓存设个1小时足够了,建议使用redis:http://www.hao535.com/archives/26

以上几个关键的东西,iplocation、area.php和redis都安装和准备好了,就可以使用下面范例代码实现天气预报了,本方案有实际应用,低配日pv500万没有问题。 继续阅读“一个高效的根据IP自动显示天气预报信息的案例”

redis批量删除key

redis查询key时可以使用*匹配符,类似sql里的like %

redis-cli -a password -n 0 keys “mykey*” | xargs redis-cli -a password -n 0 del

这个使用管道连接的两条命令,先找出mykey打头的key,然后删除。如果是php端,没法使用exec等命令函数,可以先找出key,然后挨个删除,效率方面肯定是比命令行低了,代码参考如下:

$redis_host = ‘127.0.0.1’;
$redis_port = 6379;
/* redis connect */
$redis = new Redis();
$redis->connect($redis_host, $redis_port);
$rs = $redis->keys(“mykey*”);
foreach($rs as $v)
$redis->del($v);