本文引自网络

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

本文将使用其incr(自增),get(获取),delete(清除)方法来实现计数器类。

1.Redis计数器类代码及演示实例

RedisCounter.class.php

<?php
/**
* PHP基于Redis计数器类
* Date: 2017-10-28
* Author: fdipzone
* Version: 1.0
*
* Descripton:
* php基于Redis实现自增计数,主要使用redis的incr方法,并发执行时保证计数自增唯一。
*
* Func:
* public incr 执行自增计数并获取自增后的数值
* public get 获取当前计数
* public reset 重置计数
* private connect 创建redis连接
*/
class RedisCounter{ // class start private $_config;
private $_redis; /**
* 初始化
* @param Array $config redis连接设定
*/
public function __construct($config){
$this->_config = $config;
$this->_redis = $this->connect();
} /**
* 执行自增计数并获取自增后的数值
* @param String $key 保存计数的键值
* @param Int $incr 自增数量,默认为1
* @return Int
*/
public function incr($key, $incr=1){
return intval($this->_redis->incr($key, $incr));
} /**
* 获取当前计数
* @param String $key 保存计数的健值
* @return Int
*/
public function get($key){
return intval($this->_redis->get($key));
} /**
* 重置计数
* @param String $key 保存计数的健值
* @return Int
*/
public function reset($key){
return $this->_redis->delete($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;
} } // class end
?>

demo.php

<?php
Require 'RedisCounter.class.php'; // redis连接设定
$config = array(
'host' => 'localhost',
'port' => 6379,
'index' => 0,
'auth' => '',
'timeout' => 1,
'reserved' => NULL,
'retry_interval' => 100,
); // 创建RedisCounter对象
$oRedisCounter = new RedisCounter($config); // 定义保存计数的健值
$key = 'mycounter'; // 执行自增计数,获取当前计数,重置计数
echo $oRedisCounter->get($key).PHP_EOL; //
echo $oRedisCounter->incr($key).PHP_EOL; //
echo $oRedisCounter->incr($key, 10).PHP_EOL; //
echo $oRedisCounter->reset($key).PHP_EOL; //
echo $oRedisCounter->get($key).PHP_EOL; // 0
?>

输出:

0
1
11
1
0

2.并发调用计数器,检查计数唯一性

测试代码如下:

<?php
Require 'RedisCounter.class.php'; // redis连接设定
$config = array(
'host' => 'localhost',
'port' => 6379,
'index' => 0,
'auth' => '',
'timeout' => 1,
'reserved' => NULL,
'retry_interval' => 100,
); // 创建RedisCounter对象
$oRedisCounter = new RedisCounter($config); // 定义保存计数的健值
$key = 'mytestcounter'; // 执行自增计数并返回自增后的计数,记录入临时文件
file_put_contents('/tmp/mytest_result.log', $oRedisCounter->incr($key).PHP_EOL, FILE_APPEND);
?>

测试并发执行,我们使用ab工具进行测试,设置执行次,个并发。

ab -c 15 -n 150 http://localhost/test.php

执行结果:

ab -c 15 -n 150 http://localhost/test.php
This is ApacheBench, Version 2.3 <$Revision: 1554214 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking home.rabbit.km.com (be patient).....done Server Software: nginx/1.6.3
Server Hostname: localhost
Server Port: 80 Document Path: /test.php
Document Length: 0 bytes Concurrency Level: 15
Time taken for tests: 0.173 seconds
Complete requests: 150
Failed requests: 0
Total transferred: 24150 bytes
HTML transferred: 0 bytes
Requests per second: 864.86 [#/sec] (mean)
Time per request: 17.344 [ms] (mean)
Time per request: 1.156 [ms] (mean, across all concurrent requests)
Transfer rate: 135.98 [Kbytes/sec] received Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 1
Processing: 3 16 3.2 16 23
Waiting: 3 16 3.2 16 23
Total: 4 16 3.1 17 23 Percentage of the requests served within a certain time (ms)
50% 17
66% 18
75% 18
80% 19
90% 20
95% 21
98% 22
99% 22
100% 23 (longest request)

检查计数是否唯一

生成的总计数
wc -l /tmp/mytest_result.log
150 /tmp/mytest_result.log 生成的唯一计数
sort -u /tmp/mytest_result.log | wc -l
150

可以看到在并发调用的情况下,生成的计数也保证唯一。

源码下载地址:点击查看

php 基于redis计数器类的更多相关文章

  1. 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享

    因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXi ...

  2. 分布式锁 基于Redis

    分布式锁的实现(基于Redis) 参考:http://www.jb51.net/article/75439.htm http://www.linuxidc.com/Linux/2015-01/1118 ...

  3. 基于Redis的CAS服务端集群

    为了保证生产环境CAS(Central Authentication Service)认证服务的高可用,防止出现单点故障,我们需要对CAS Server进行集群部署. CAS的Ticket默认是以Ma ...

  4. 设计模式之PHP项目应用——单例模式设计Memcache和Redis操作类

    1 单例模式简单介绍 单例模式是一种经常使用的软件设计模式. 在它的核心结构中仅仅包括一个被称为单例类的特殊类. 通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问.从而方便对实例个 ...

  5. 基于Redis缓存的Session共享(附源码)

    基于Redis缓存的Session共享(附源码) 在上一篇文章中我们研究了Redis的安装及一些基本的缓存操作,今天我们就利用Redis缓存实现一个Session共享,基于.NET平台的Seesion ...

  6. 基于Redis的在线用户列表解决方案

    前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案可以采用SessionListener来完成 ...

  7. [项目回顾]基于Redis的在线用户列表解决方案

    迁移:基于Redis的在线用户列表解决方案 前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案 ...

  8. 记一次企业级爬虫系统升级改造(六):基于Redis实现免费的IP代理池

    前言: 首先表示抱歉,春节后一直较忙,未及时更新该系列文章. 近期,由于监控的站源越来越多,就偶有站源做了反爬机制,造成我们的SupportYun系统小爬虫服务时常被封IP,不能进行数据采集. 这时候 ...

  9. [转载] 基于Redis实现分布式消息队列

    转载自http://www.linuxidc.com/Linux/2015-05/117661.htm 1.为什么需要消息队列?当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消 ...

随机推荐

  1. .net 多线程的使用(Thread)

    上篇 net 同步异步 中篇 多线程的使用(Thread) 下篇 net 任务工厂实现异步多线程 Thread多线程概述 上一篇我们介绍了net 的同步与异步,我们异步演示的时候使用的是委托多线程来实 ...

  2. IDEA@Data注释使用

    @Data注解主要是帮助解决Setter 和 Getter以及 toString这种重复的无脑工作 加入@Data注解可以直接帮助我们添加实体类相应的Setter 和 Getter以及 toStrin ...

  3. LINQ to Objects系列(2)两种查询语法介绍

    LINQ为我们提供了两种查询语法,分别是查询表达式和查询方法语法.这篇文章分为以下几个方面进行总结. 1,一个包含两种查询语法的简单示例 2,查询表达式的结构 3,查询方法相关的运算符 一个包含两种查 ...

  4. java锁的简化

    java使用单独的锁对象的代码展示 private Lock bankLock = new ReentrantLock(); //因为sufficientFunds是锁创建的条件所以称其为条件对象也叫 ...

  5. ElasticSearch 使用小结

    写在前面 要做个元数据服务,包括存储和查询.元数据除了一些基本字段外,其他格式是自由的,存储输入为一个JSON形式.比如下面是一个文件对象的元数据: { "name":" ...

  6. python实现贪婪算法解决01背包问题

    一.背包问题 01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2至Wn,与之相对应的价值为P1,P2至Pn.01背包是背包问题中最简单的问题.01背包的约束条件是给定几种物 ...

  7. 高并发情况下,如何生成分布式全局id

    1.使用UUID生成全局id,不占用宽带 2.基于数据库自增或者序列生成全局id,占用宽带,设置自增步长实现集群,但可扩展性差 3.基于redis生成全局id,占用宽度,设置自增步长实现集群,性能比数 ...

  8. 纯小白入手 vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单

    vue3.0 CLI 真小白一步一步入手全教程系列:https://www.cnblogs.com/ndos/category/1295752.html 我的 github 地址 - vue3.0St ...

  9. MBTIles实现

    MBTIles实现 3.1 Compliant(符合) python: raster2mb (write) python: mbutil (read/write) python: landez (wr ...

  10. Python Django框架笔记(四):数据分页和CSRF跨站点请求伪造

    (一)数据分页  可以参考  https://docs.djangoproject.com/en/2.0/topics/pagination/ 模板:如果只要显示 1.2.3.4.5.6....的话, ...