查看redis占用内存大小的方法

查看redis占用内存大小的方法

redis-cli 
auth 密码
info
# Memory

used_memory:13490096 //数据占用了多少内存(字节 byte)

used_memory_human:12.87M //数据占用了多少内存(带单位的,可读性好)

used_memory_rss:13490096  //redis占用了多少内存

used_memory_peak:15301192 //占用内存的峰值(字节)

used_memory_peak_human:14.59M //占用内存的峰值(带单位的,可读性好)

used_memory_lua:31744  //lua引擎所占用的内存大小(字节)

mem_fragmentation_ratio:1.00  //内存碎片率

mem_allocator:libc //redis内存分配器版本,在编译时指定的。有libc、jemalloc、tcmalloc这3种。

看 used_memory就行了

关闭redis持久化功能

关闭redis持久化功能
持久化会报如下信息
会影响硬盘写入性能 所以没什么用 就关掉吧

修改redis配置文件,redis.conf 第115行左右。

1.注释掉原来的持久化规则

#save 900 1
#save 300 10
#save 60 10000

2.设置为空

save ""

然后重启redis服务即可。

ps:linux RDB: 10 MB of memory used by copy-on-write 一般说明内存不够用了

phpredis封装

<?php
/**
 * This is a Redis exntend class
 */

class RedisClient
{
    private static $instance = NULL;


    /**
     * Get a instance of MyRedisClient
     *
     * @param string $key
     * @return object
     */
    public  static function getInstance()
    {
        if (!self::$instance) {
            $redis = new \Redis();
            $redis->connect('127.0.0.1', 6379);
            $redis->auth('23');
            self::$instance = $redis;
        }
        return self::$instance;
    }




}




   $redis = \RedisClient::getInstance();
        $redis->incr('moban_fangwen');
        print_r($redis->get('moban_fangwen'));
        exit();
?>

win7 64bit安装redis

win7 64bit安装redis

1 先安装redis客户端

1、下载Redis的压缩包

https://github.com/dmajkic/redis/downloads

我下载的是redis-2.4.5-win32-win64.zip

下载完后将其解压放在自己要放的目录下

解压后的目录

如果你是32位的话就进32bit的文件夹,64位就进64bit文件夹

文件夹进去后会看到一下的几个文件

redis-benchmark.exe: 性能测试 模拟N个客户端发送set,get请求

redis-check-aof.exe:更新日志检查

redis-check-dump.exe:本地数据库检查

redis-server.exe:服务程序

接下来就是安装了

打开dos命令栏,进入到redis的目录下面,输入以下命令:

d: && cd D:\Downloads\redis-2.4.5-win32-win64\64bit && redis-server.exe redis.conf

安装OK!

然后再打开一个dos命令栏,进入到redis的目录下,输入以下命令:

redis-cli.exe -h 127.0.0.1 -p 6379

测试一下

set key value 存值

get key 取值

 

2 安装phpredis

Redis扩展下载

http://pecl.php.net/package/redis/2.2.7/windows

查看phpinfo()信息

Compiler

Architecture

选择对应的版本下载(不然没效果),解压,将php_redis.dll放入PHP的ext目录下

修改php.ini,加入

extension=php_redis.dll

重启apache,查看phpinfo就有redis扩展的信息了。

注意:查看以下信息,下载相应版本

redis主从配置笔记

redis主从配置笔记
redis主从配置可比mysql主从简单多了

1 直接进入slave 配置redis.conf
slaveof 121.41.35.30 6379 (映射到主服务器上)
如果master设置了验证密码,还需配置masterauth。楼主的master设置了验证密码为admin,所以配置masterauth admin。
 配置完之后启动slave的Redis服务,OK,主从配置完成。下面测试一下:

  在master和slave分别执行info命令,查看结果如下:

  master:
    # Replication
role:master
connected_slaves:1
slave0:ip=121.40.134.7,port=6379,

  slave:
# Replication
role:slave
master_host:121.41.35.30
master_port:6379
master_link_status:up //这个代表连接上

输入如上那就是一般就是成功了

然后在master执行set age 24

在slave执行get age,看是否能得到24,如果能够得到值则说明配置成功。

redis在项目中的应用

redis在项目中的应用 ps:PHP 会自动 关redis连接 不需要手动关 对于临时的数据 可以不经过数据库直接redis上操作


	/*消息队列实例 消息队列详细步骤在http://newmiracle.cn/?p=227*/

	public function insertinfo(){

	  //连接本地的 Redis 服务
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);
        //存储数据到列表中
    $infos =  array('info1' => 66, 'info2' => 88);
        $redis->lpush($key, json_encode($infos));

        // 获取存储的数据并输出
        $arList = $redis->lrange("tutorial-list", 0, 30);
        print_r($arList);
        exit();
	}


/*读取实例*/
 //$key一般写数据库名字 leftjoin的话取第一个数据库
    function getinfos($sql,$key)
    {
        $md5key=md5($sql);
        //连接本地的 Redis 服务
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);
        // 获取存储的数据

        //用与left join
        if(is_array($key)){
             foreach ($key as $k=>$v){
                 $result = $redis->get($key);
                 $result=json_decode($result,'true');
                 if(empty($result)){
                     $result=0;
                 }
             }
            if(!$result){
                $result = $redis->get($key[0]);
                $result=json_decode($result,'true');
            }
            //用户普通sql语句
        }else{
            $result = $redis->get($key);
            $result=json_decode($result,'true');
        }

        if (empty($result)) {
            $VModel = new HuanShanVoteModel();
            $result = $VModel->query($sql);
            $list[$md5key]=$result;
            $redis->set($key,json_encode($list));
            return $result;
        }else{
            $list=$result[$md5key];
            return $list;
        }
    }

/*更新实例*/

	public function updateinfo(){


		//运行sql语句
		$sql="update mobantestinfo set info1=1 where id=40";
		$VModel = new HuanShanVoteModel();
		$isOk = $VModel->execute($sql);

		//连接本地的 Redis 服务
		$redis = new \Redis();
		$redis->connect('127.0.0.1', 6379);
		/*删除key*/
		$redis->del('tutoriallist');
	}
	/*删除实例*/

	public function deleteinfo(){


		//运行sql语句
		$sql="delete from mobantestinfo where id=40";
		$VModel = new HuanShanVoteModel();
		$isOk = $VModel->execute($sql);

		//连接本地的 Redis 服务
		$redis = new \Redis();
		$redis->connect('127.0.0.1', 6379);
		$redis->del('tutoriallist');
	}
    function insertinfos($key, $sql)
    {
        //运行sql语句
        $VModel = new HuanShanVoteModel();
        $isOk = $VModel->execute($sql);

        //连接本地的 Redis 服务
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->del($key);
        return $isOk;
    }

php 使用redis锁解决并发访问的问题

分享一个php使用redis加锁解决并发访问的问题。

1.并发访问限制问题

对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功。

例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制的情况下,用户则可以使用同一个换领码同时兑换到多张优惠券。

常见的业务逻辑代码如下:

if A(可以换领)
B(执行换领)
C(更新为已换领)
D(结束)

如果用户并发提交换领码,都能通过可以换领(A)的判断,因为必须有一个执行换领(B)后,才会更新为已换领(C)。因此如果用户在有一个更新为已换领之前,有多少次请求,这些请求都可以执行成功。

2.并发访问限制方法

使用文件锁可以实现并发访问限制,但对于分布式架构的环境,使用文件锁不能保证多台服务器的并发访问限制。

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

本文将使用其setnx方法实现分布式锁功能。setnx即Set it N**ot eX**ists。

当键值不存在时,插入成功(获取锁成功),如果键值已经存在,则插入失败(获取锁失败)

具体的 redis 加锁类和示例代码如下:

<?php
/**
 *  Redis锁操作类
 *  Date:   2016-06-30
 *  Author: fdipzone
 *  Ver:    1.0
 *
 *  Func:
 *  public  lock    获取锁
 *  public  unlock  释放锁
 *  private connect 连接
 */
class RedisLock { // class start

    private $_config;
    private $_redis;

    /**
     * 初始化
     * @param Array $config redis连接设定
     */
    public function __construct($config=array()){
        $this->_config = $config;
        $this->_redis = $this->connect();
    }

    /**
     * 获取锁
     * @param  String  $key    锁标识
     * @param  Int     $expire 锁过期时间
     * @return Boolean
     */
    public function lock($key, $expire=5){
        $is_lock = $this->_redis->setnx($key, time()+$expire);

        // 不能获取锁
        if(!$is_lock){

            // 判断锁是否过期
            $lock_time = $this->_redis->get($key);

            // 锁已过期,删除锁,重新获取
            if(time()>$lock_time){
                $this->unlock($key);
                $is_lock = $this->_redis->setnx($key, time()+$expire);
            }
        }

        return $is_lock? true : false;
    }

    /**
     * 释放锁
     * @param  String  $key 锁标识
     * @return Boolean
     */
    public function unlock($key){
        return $this->_redis->del($key);
    }

    /**
     * 创建redis连接
     * @return Link
     */
    private function connect(){
        try{
            $redis = new Redis();
            $redis->connect($this->_config['host'],$this->_config['port'],$this->_config['timeout'],$this->_config['reserved'],$this->_config['retry_interval']);
            if(empty($this->_config['auth'])){
                $redis->auth($this->_config['auth']);
            }
            $redis->select($this->_config['index']);
        }catch(RedisException $e){
            throw new Exception($e->getMessage());
            return false;
        }
        return $redis;
    }
}

$config = array(
    'host' => 'localhost',
    'port' => 6379,
    'index' => 0,
    'auth' => '',
    'timeout' => 1,
    'reserved' => NULL,
    'retry_interval' => 100,
);

// 创建redislock对象
$oRedisLock = new RedisLock($config);

// 定义锁标识
$key = 'mylock';

// 获取锁
$is_lock = $oRedisLock->lock($key, 10);

if($is_lock){
    echo 'get lock success<br>';
    echo 'do sth..<br>';
    sleep(5);
    echo 'success<br>';
	//释放锁
    $oRedisLock->unlock($key);

// 获取锁失败
}else{
    echo 'request too frequently<br>';
}

测试方法:

打开两个不同的浏览器,同时在A,B中访问demo.php ,如果先访问的会获取到锁,输出:

get lock success
do sth..
success

另一个获取锁失败则会输出request too frequently ,保证同一时间只有一个访问有效,有效限制并发访问。

为了避免系统突然出错导致死锁,所以在获取锁的时候增加一个过期时间,如果已超过过期时间,即使是锁定状态都会释放锁,避免死锁导致的问题。

redis实现消息队列教程

redis实现消息队列教程(ps:这个消息队列因为是每秒插入一次数据 对于实时性比较高的就不要用消息队列了 就是直接插入数据库)

第一步:读取redis队列 并且存入数据库 后再移除 代码如下



<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/10/18
 * Time: 17:00
 */

file_put_contents('log.log', date("Y-m-d H:i:s") . " " . var_export('测试每秒请求', TRUE) . PHP_EOL, FILE_APPEND | LOCK_EX);
require_once 'queenchuli/common/mysql.php';

redisc('tutorial-list',99,'mobantestinfo');


/**
 * @param $key redis key
 * @param $percount 一次性操作多少数据
 * @param $table  要插入的数据库
 */
function redisc($key,$percount,$table){

    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    $redis->auth('zhiweiredis');

    $arList = $redis->lrange($key, 0, $percount);

    if(!empty($arList)){
        foreach ($arList as $k=>$v){
            $arList[$k]=json_decode($v,true);
        }
        for ($i = 0; $i < $percount; $i++) {
            $redis->rPop($key);
        }
        $db = new mysql();
        $isOk=inserts($arList, $table);
        if ($isOk==1) {

        } else {
            //如果失败 就记录sql语句
            file_put_contents('/data/web/mircoweb/wwwroot/Public/queenchuli/moban/log.log', date("Y-m-d H:i:s") . " " . var_export($isOk, TRUE) . PHP_EOL, FILE_APPEND | LOCK_EX);
        }
    }
}


/**
 * 插入数组记录的操作
 * @param array $array
 * @param string $table
 * @return boolean
 */
function inserts($array, $table)
{

    $i = 0;
    $arraynew=array();
    foreach ($array as $k => $v) {
        if ($i == 0) {
            //运行一次就可以了
            $keys = join(',', array_keys($v));
        }

        $val='('.join(',',$v).')';
        $arraynew[]=$val;
        $i++;
    }

    $values = join(',',$arraynew);
    $sql = "insert {$table}({$keys}) VALUES {$values}";

    $res = mysql_query($sql);
    if ($res) {
        return 1;
    } else {
        return $sql;
    }
}


// some code

?>

第二步 shell脚本写定时器每秒触发 这个PHP文件

    step=1 #间隔的秒数,不能大于60  
      
    for (( i = 0; i < 60; i=(i+step) )); do  
        $(php '/home/wwwroot/default/wordpress/cronb.php')  
		echo i
        sleep $step  
    done  
      
    exit 0  

保存为crontab.sh

然后sh运行它就是了 测试下 是不是有了 每次redis有新数据 都会插入数据库后 然后移除

swoole学习笔记第三季

ps:每次PHP 运行swoole的时候 都是把代码写入内存然后执行 每次执行的都是内存里的代码 所以 每次改完以后 需要重新PHP执行 从存储中写入内存执行

以下代码就是 swoole收到的数据存入redis缓存
on(‘open’, function ($ws, $request) {
foreach($ws->connections as $fd)
{
$ws->push($request->fd, “hello, welcome1\n”);

}
//获取连接总数
echo ‘获取所有链接数’.count($ws->connections).’\n’;
});

//监听WebSocket消息事件
$ws->on(‘message’, function ($ws, $frame) {
echo “Message: {$frame->data}\n”;

//连接本地的 Redis 服务
$redis = new Redis();
$redis->connect(‘127.0.0.1’, 6379);
echo “Connection to server sucessfully”;
//存储数据到列表中
$redis->lpush(“tutorial-list”, “Redis”);
$redis->lpush(“tutorial-list”, “Mongodb”);
$redis->lpush(“tutorial-list”, “Mysql”);
// 获取存储的数据并输出
$arList = $redis->lrange(“tutorial-list”, 0 ,5);
echo “Stored string in redis”;
var_dump($arList);

$ws->push($frame->fd, “server: {$frame->data}”);
});

//监听WebSocket连接关闭事件
$ws->on(‘close’, function ($ws, $fd) {
echo “client-{$fd} is closed\n”;
});

$ws->start();