Redis是一种跨平台NoSql内存数据库,这几年各大公司系统应用中非常多见,支持多种数据类型,可以持久化保存数据,很多公司直接拿来作为数据库使用.
相比于Memcached,Redis支持持久化保存数据,重启服务,数据不丢失,支持分布式缓存,多个服务主从读写分离,大大提高效率。
网上可下载https://github.com/MicrosoftArchive/redis 文件,msi文件可视化安装,安装成功后Windows服务中有Redis服务,鼠标右键启动、停止
如何进行多实例端口运行,整体思路:
1)、更换新端口
2)、配置RDB数据文件路径
3)、配置logs日志文件路径
具体如下:
1、找到安装后的程序目录,复制 redis.windows-service.conf 命名为 redis.windows-service-6380.conf
2、修改此配置文件中的配置属性
# 本地数据库名称
dbfilename dump-6380.rdb
# 日志文件
logfile "logs/server_log_6380.txt"
# 日志输出
syslog-enabled yes
3、启动cmd命令行,执行
redis-server.exe --service-install redis.windows-service-6380.conf --service-name redis6380 --port 6380
4、创建后执行命令,启动服务
redis-server.exe --service-start --service-name redis6380
5、cmd执行命令测试登录
redis-cli.exe -h 127.0.0.1 -p 6380
6、若需要删除实例服务则执行
redis-server.exe --service-uninstall --service-name redis6380
servers = $servers;
// 重试延迟时间 毫秒
$this->retryDelay = $retryDelay;
// 重试次数
$this->retryCount = $retryCount;
// 最少存活redis个数
$this->quorum = min(count($servers), (count($servers) / 2 + 1));
}
/**
* 加锁
* 逻辑:
*
* @param $resource
* @param $ttl
* @return array|bool
*/
public function lock($resource, $ttl)
{
// 初始化实例
$this->initInstances();
// 获取唯一值
$token = uniqid();
// 重试次数
$retry = $this->retryCount;
do {
$n = 0;
$startTime = microtime(true) * 1000;
foreach ($this->instances as $instance) {
if ($this->lockInstance($instance, $resource, $token, $ttl)) {
$n++;
}
}
# Add 2 milliseconds to the drift to account for Redis expires
# precision, which is 1 millisecond, plus 1 millisecond min drift
# for small TTLs.
//偏移量 = (锁的过期时间*锁过期的一个基数) + 2ms
$drift = ($ttl * $this->clockDriftFactor) + 2;
// 此时间为: 锁的过期时间-(加锁过程的时间)- 偏移量
$validityTime = $ttl - (microtime(true) * 1000 - $startTime) - $drift;
if ($n >= $this->quorum && $validityTime > 0) {
return [
'validity' => $validityTime,
'resource' => $resource,
'token' => $token,
];
} else {
foreach ($this->instances as $instance) {
$this->unlockInstance($instance, $resource, $token);
}
}
// Wait a random delay before to retry
// 获取一个重试延迟时间 (在 重试延迟时间的一半 到 重试延迟时间 中间取一个值)
$delay = mt_rand(floor($this->retryDelay / 2), $this->retryDelay);
// 休息一会 重新再取
usleep($delay * 1000);
// 重试次数减一
$retry--;
} while ($retry > 0);
return false;
}
/**
* 解锁
* @param array $lock
*/
public function unlock(array $lock)
{
$this->initInstances();
$resource = $lock['resource'];
$token = $lock['token'];
foreach ($this->instances as $instance) {
$this->unlockInstance($instance, $resource, $token);
}
}
/**
* 初始化所有redis实例
*/
private function initInstances()
{
if (empty($this->instances)) {
foreach ($this->servers as $server) {
list($host, $port, $timeout) = $server;
$redis = new \Redis();
$redis->connect($host, $port, $timeout);
$this->instances[] = $redis;
}
}
}
/**
* 加锁
* @param $instance
* @param $resource
* @param $token
* @param $ttl
* @return mixed
*/
private function lockInstance($instance, $resource, $token, $ttl)
{
return $instance->set($resource, $token, ['NX', 'PX' => $ttl]);
}
/**
* 解锁
* @param $instance
* @param $resource
* @param $token
* @return mixed
*/
private function unlockInstance($instance, $resource, $token)
{
$script = '
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])
else
return 0
end
';
return $instance->eval($script, [$resource, $token], 1);
}
}
lock('test', 10000);
if ($lock) {
//todo 处理业务数据 处理网完毕调用解锁
print_r($lock);
} else {
print "Lock not acquired\n";
}
}
}catch (\Exception $e){
var_dump($e);
}
参考资料:https://www.cnblogs.com/jaylongli/p/11170085.html
https://www.cnblogs.com/jaylongli/p/11170085.html