PHP Connect Redis Driver
I was using Predis before. But it seems that our company is using another one in the common codes. So I plan to follow that and use that one instead.
https://github.com/phpredis/phpredis#readme
Installation
> git clone https://github.com/phpredis/phpredis
> cd phpredis/
> phpize
> ./configure
> make
> sudo make install
After installation, we can try these classes as follow:
<?php
namespace BillingConsumerPHP;
require __DIR__.'/../../vendor/autoload.php';
use \Redis;
class PHPRedisClient
{
private $client = null;
private $ioc = null;
public function __construct($ioc)
{
$this->ioc = $ioc;
$logger = $this->ioc->getService("logger");
$config = $this->ioc->getService("config");
$logger->info("==============Redis config start ==============");
$logger->info("redisHost = " . $config['redisHost']);
$logger->info("redisPort = " . $config['redisPort']);
$logger->info("===============================================");
try
{
$this->client = new Redis();
$this->client->pconnect($config['redisHost'], $config['redisPort'], 0.5);
$logger->debug("Successfully connected to Redis");
}
catch (Exception $e)
{
$logger->error("Couldn't connected to Redis");
$logger->error($e->getMessage());
}
}
public function isRecoverNeeded(){
$max = $this->client->get("job_id_counter");
//if counter is 0 or empty, redis already crashed.
return $max <= 4294967295;
}
public function incrJobIDCounter(){
return $this->client->incr("job_id_counter");
}
public function getJobIDCounter(){
return $this->client->get("job_id_counter");
}
public function setJobIDCounter($number){
$this->client->set("job_id_counter", $number);
}
public function cleanJobIDCounter(){
$this->client->del("job_id_counter");
}
public function incrAndFetchSpend($jobID, $date, $spend){
$dateTimeUtil = $this->ioc->getService("dateTimeUtil");
//life time spend
$lifeTimeSpend = $this->client->hincrby("job_budget_{$jobID}", 'lifetimespend', $spend);
//daily spend
$dateString = $dateTimeUtil->getDateString($date);
$dailySpend = $this->client->hincrby("job_dailyspend_{$jobID}", $dateString, $spend);
//monthly spend
$monthString = $dateTimeUtil->getMonthString($date);
$monthlySpend = $this->client->hincrby("job_monthlyspend_{$jobID}", $monthString, $spend);
return array(
'lifeTimeSpend'=>$lifeTimeSpend,
'dailySpend'=>$dailySpend,
'monthlySpend'=>$monthlySpend,
);
}
public function updateJobIDMapping($jobIDMappings){
foreach ($jobIDMappings as $jobIDMap){
$sourceID = $jobIDMap['source_id'];
$referenceID = $jobIDMap['job_reference'];
$jobID = $jobIDMap['job_id'];
//step1 sourceID_referenceID => jobID => value
$jobSourceKey = "job_{$sourceID}_{$referenceID}";
$columnName = "job_id";
$this->client->hset($jobSourceKey, $columnName, $jobID);
//step2 jobID => sourceID_referenceID
$redisKey = "idmapping_{$jobID}";
$redisValue = "{$sourceID}_{$referenceID}";
$this->client->set($redisKey, $redisValue);
}
}
public function getJobIDMapping($jobID)
{
$redisKey = "idmapping_{$jobID}";
$redisValue = $this->client->get($key);
if(null !== $redisValue){
$infos = explode("_", $redisValue);
if(count($infos) > 1){
return array(
'sourceID' => $infos[0],
'referenceID' => $infos[1],
);
}else{
return null;
}
}else{
return null;
}
}
public function updateHistoryDailySpending($spendings){
foreach ($spendings as $spend){
$jobID = $spend['job_id'];
$redisKey = "job_dailyspend_{$jobID}";
$redisColumn = $spend['date'];
$redisValue = $spend['spend']; //m cents
$this->client->hincrbyfloat($redisKey, $redisColumn, $redisValue);
}
}
public function updateHistoryMonthlySpending($spendings){
foreach ($spendings as $spend){
$jobID = $spend['job_id'];
$redisValue = $spend['spend'] * 1000; //m cents
$month = $spend['month'];
$redisKey = "job_monthlyspend_{$jobID}";
$redisColumn = $month;
$this->client->hincrbyfloat($redisKey, $redisColumn, $redisValue);
}
}
public function getBudget($jobID){
$result = $this->client->hmget("job_budget_{$jobID}", array('budget', 'budgetType'));
return $result;
}
public function sendRawJobContent($key, $message){
$logger = $this->ioc->getService("logger");
//send to redis
$this->client->setEx($key, TIME_3DAY, $message);
}
}
?>
This class can be tested by phpunit
<?php
use \BillingConsumerPHP\IOCUtil;
/**
* RUNNING_ENV=test phpunit --bootstrap vendor/autoload.php tests/BillingConsumerPHP/PHPRedisClientTest
* @author carl
*/
class PHPRedisClientTest extends PHPUnit_Framework_TestCase
{
private $phpRedisClient;
protected function setUp()
{
$ioc = new IOCUtil();
$this->phpRedisClient = $ioc->getService("phpRedisClient");
}
public function testDummy()
{
$this->assertTrue(true);
}
public function testDailySpending(){
$jobIDs = "4294967295";
$date = "2016-08-22";
$spending = 12.34;
$spendings = array();
for($i = 0; $i<10; $i++){
$spendings[] = array(
'job_id' => $jobIDs . $i,
'date' => $date,
'spend' => $spending,
);
}
$this->phpRedisClient->updateHistoryDailySpending($spendings);
}
public function testCrash(){
$this->phpRedisClient->cleanJobIDCounter();
$result1 = $this->phpRedisClient->isRecoverNeeded();
$this->assertTrue($result1);
$this->phpRedisClient->setJobIDCounter(12);
$result2 = $this->phpRedisClient->isRecoverNeeded();
$this->assertTrue($result2);
$this->phpRedisClient->setJobIDCounter(42949672951);
$result3 = $this->phpRedisClient->isRecoverNeeded();
$this->assertFalse($result3);
}
}
?>
I am always using docker image to deploy my things. Actually, comparing Predis which is not an extension, the installation of extension is a little complex.
Dockerfile
#install Redis Native PHP Client
RUN yum install -y git
RUN git clone https://github.com/phpredis/phpredis
WORKDIR /install/phpredis
RUN phpize
RUN ./configure
RUN make
RUN make install
And we have to add extension configuration in php.ini
extension=iconv.so
extension=raphf.so
extension=propro.so
extension=http.so
extension=redis.so
References:
http://www.thegeekstuff.com/2014/02/phpredis/
PHP Connect Redis Driver
猜你喜欢
转载自sillycat.iteye.com/blog/2339901
今日推荐
周排行