降低PHP Redis内存占用

时间:2017-04-08

不管列表、散列、有序集合、集合,当超出限制的条件后,就会转换为更为典型的底层结构类型。因为随着紧凑结构的体积不断变大,操作这些结构的速度将会变得越来越慢。

测试:

#将采用list进行代表性测试

测试思路:

1、在默认配置下往test-list推入50000条数据,查看所需时间;接着在使用rpoplpush将test-list数据全部推入到新列表list-new中,查看所需时间

2、修改配置,list-max-ziplist-entries 100000,再执行上面的同样操作

3、对比时间,得出结论

默认配置下测试:

1、插入数据,查看时间

#test1.php
<?php
header("content-type: text/html;charset=utf8;");
$redis=new Redis();
$redis->connect('192.168.95.11','6379');
$start=time();
for ($i=0; $i<50000 ; $i++) 
{ 
  $redis->lpush('test-list',$i.'-aaaassssssddddddkkk');
}
$end=time();
echo "插入耗时为:".($end-$start).'s';
?>

结果耗时4秒

2、执行相应命令,查看耗时

#test2.php
<?php
header("content-type: text/html;charset=utf8;");
$redis=new Redis();
$redis->connect('192.168.95.11','6379');
$start=time();
$num=0;
while($redis->rpoplpush('test-list','test-new'))
{
  $num+=1;
}
echo '执行次数为:'.$num."<br/>";
$end=time();
echo "耗时为:".($end-$start).'s';
?>

更改配置文件下测试  

1、先修改配置文件

list-max-ziplist-entries 100000  #将这个值修改大一点,可以更好的凸显对性能的影响

list-max-ziplist-value 64    #此值可不做修改

2、插入数据

执行test1.php

结果为:耗时12s

3、执行相应命令,查看耗时

执行test2.php

结果为:执行次数:50000,耗时12s

结论:

在本机中执行测试50000条数据就相差8s,若在高并发下,长压缩列表和大整数集合将起不到任何的优化,反而使得性能降低。

3、片结构

分片的本质就是基于简单的规则将数据划分为更小的部分,然后根据数据所属的部分来决定将数据发送到哪个位置上。很多数据库使用这种技术来扩展存储空间,并提高自己所能处理的负载量。

结合前面讲到的,我们不难发现分片结构对于redis的重要意义。因此我们需要在配置文件中关于ziplist以及intset的相关配置做出适当的调整。

3.1、分片式散列

#ShardHash.class.php

<?php
class ShardHash
{
  private $redis=''; #存储redis对象
  /**
  * @desc 构造函数
  * 
  * @param $host string | redis主机
  * @param $port int  | 端口
  */
  public function __construct($host,$port=6379)
  {
    $this->redis=new Redis();
    $this->redis->connect($host,$port);
  } 
  /**
  * @desc 计算某key的分片ID
  *
  * @param $base string | 基础散列
  * @param $key  string | 要存储到分片散列里的键名
  * @param $total int  | 预计非数字分片总数
  * 
  * @return string | 返回分片键key
  */
  public function shardKey ($base,$key,$total)
  {
    if(is_numeric($key))
    {
      $shard_id=decbin(substr(bindec($key),0,5)); #取$key二进制高五位的十进制值
    }
    else
    {
      $shard_id=crc32($key)%$shards; #求余取模
    }
    return $base.'_'.$shard_id;
  }
  /**
  * @desc 分片式散列hset操作
  *
  * @param $base string | 基础散列
  * @param $key  string | 要存储到分片散列里的键名
  * @param $total int  | 预计元素总数
  * @param $value string/int | 值
  *
  * @return bool | 是否hset成功
  */
  public function shardHset($base,$key,$total,$value)
  {
    $shardKey=$this->shardKey($base,$key,$total);
    return $this->redis->hset($shardKey,$key,$value);
  }
  /**
  * @desc 分片式散列hget操作
  *
  * @param $base string | 基础散列
  * @param $key  string | 要存储到分片散列里的键名
  * @param $total int  | 预计元素总数
  *
  * @return string/false | 成功返回value
  */
  public function shardHget($base,$key,$total)
  {
    $shardKey=$this->shardKey($base,$key,$total);
    return $this->redis->hget($shardKey,$key);
  }
} 
$obj=new ShardHash('192.168.95.11');
echo $obj->shardHget('hash-','key',500);
?>
  • 共4页:
  • 上一页
  • 2/4
  • 下一页
  • 上一篇:php PDO实现的事务回滚示例 下一篇:使用Codeigniter重写insert的方法(推荐)

    相关文章

    最新文章