本来博客搭建在自己的服务器上,不知道多久没有维护和更新后,再一看域名都需要重新备案了。介于本人的“懒惰性”,还是迁过来不浪费资源了。
最近搭建一个业务,号称每秒响应需要1W次请求,然后LZ各种折腾php、mysql和nginx配置。最后放弃mysql使用redis单机版,最后的最后使用redis集群。
1、生产环境
ubuntu16.04
redis-3.0.7
内网机器IP:192.168.140.180和192.168.140.181
机器CPU:4核
2、搭建
LZ在搭建集群前是使用的redis单机版,而单机版的启动直接使用redis.server /etc/redis/redis.conf的,也就是说完全没有理解redis的单核运行原理 【手动滑稽,LZ是个菜】,还是记录一下redis的单线程:
redis是用"单线程-多路复用io模型"来实现高性能的内存数据服务的,这种机制避免了使用锁,但是同时这种机制在进行sunion之类的比较耗时的命令时会使redis的并发下降。因为是单一线程,所以同一时刻只有一个操作在进行,所以,耗时的命令会导致并发的下降,不只是读并发,写并发也会下降。而单一线程也只能用到一个cpu核心。
cd /data/bao
wget "http://download.redis.io/releases/redis-3.0.7.tar.gz"
tar -zxvf redis-3.0.7.tar.gz
、
cd redis-3.0.7 make test
wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
sudo tar xzvf tcl8.6.1-src.tar.gz -C /usr/local/
cd /usr/local/tcl8.6.1/unix/
sudo ./configure
sudo make
sudo make install
cd /data/bao/redis-3.0.7 && make && make install
cd /data/bao/redis-3.0.7/src
下有 redis-server 和 redis-cli 文件。./redis-cli 就可以使用连接了。
mkdir -p /data/redis/7000
mkdir -p /data/redis/7001
mkdir -p /data/redis/7002
mkdir -p /data/redis/7003
cp /data/bao/redis-3.0.7/src/redis-server /data/redis
vi /data/redis/redis.con
port 7000 #运行端口,和你将要放入的文件夹名称对应
cluster-enabled yes
cluster-config-file nodes.conf #节点配置信息
cluster-node-timeout 5000 #超时
appendonly no
daemonize yes #后台运行
cd /data/redis/7000/ && taskset -c 0 /data/redis/redis-server /data/redis/7000/redis.conf
cd /data/redis/7001/ && taskset -c 1 /data/redis/redis-server /data/redis/7001/redis.conf
cd /data/redis/7002/ && taskset -c 2 /data/redis/redis-server /data/redis/7002/redis.conf
cd /data/redis/7003/ && taskset -c 3 /data/redis/redis-server /data/redis/7003/redis.conf
apt update
apt install ruby
gem install redis
cd /data/bao/redis-3.0.7/src
redis-trib.rb create --replicas 1 192.168.140.180:7000 192.168.140.180:7001 192.168.140.180:7002 192.168.140.180:7003 192.168.140.180:7000 192.168.140.181:7000 192.168.140.181:7001 192.168.140.181:7002 192.168.140.181:7003
redis-cli -p 7000 -c
楼主使用的是yiiredis拓展,github地址:https://github.com/phpnode/YiiRedis
然而,这个拓展没有cluster的链接【微笑】
没办法,山寨的楼主只能用phpredis来写个简单的拓展放里边。。。
_client = $client;
}
/**
* Gets the redis client
* @return RedisCluster the redis client
*/
public function getClient($reconnect = false)
{
if ($this->_client === null || $reconnect) {
if(empty($this->clusterConfig)){
throw new CException('Redis Cluster Config Error');
}
$clusterList = [];
foreach ($this->clusterConfig as $item){
$clusterList[] = $item['host'] . ':' . $item['port'];
}
if(empty($clusterList)){
throw new CException('Redis Cluster Config Error');
}
$this->_client = new RedisCluster(null,$clusterList);
// $this->_client->connect($this->hostname, $this->port, $this->timeout);
//phpredis not support password yet
// if (isset($this->password)) {
// if ($this->_client->auth($this->password) === false) {
// throw new CException('Redis authentication failed!');
// }
// }
// $this->_client->setOption(Redis::OPT_PREFIX, $this->prefix);
// $this->_client->select($this->database);
}
return $this->_client;
}
/**
* Returns a property value based on its name.
* Do not call this method. This is a PHP magic method that we override
* to allow using the following syntax to read a property
*
* $value=$component->propertyName;
*
* @param string $name the property name
* @return mixed the property value
* @throws CException if the property is not defined
* @see __set
*/
public function __get($name) {
$getter='get'.$name;
if (property_exists($this->getClient(),$name)) {
return $this->getClient()->{$name};
}
elseif(method_exists($this->getClient(),$getter)) {
return $this->$getter();
}
return parent::__get($name);
}
/**
* Sets value of a component property.
* Do not call this method. This is a PHP magic method that we override
* to allow using the following syntax to set a property
*
* $this->propertyName=$value;
*
* @param string $name the property name
* @param mixed $value the property value
* @return mixed
* @throws CException if the property is not defined or the property is read only.
* @see __get
*/
public function __set($name,$value)
{
$setter='set'.$name;
if (property_exists($this->getClient(),$name)) {
return $this->getClient()->{$name} = $value;
}
elseif(method_exists($this->getClient(),$setter)) {
return $this->getClient()->{$setter}($value);
}
return parent::__set($name,$value);
}
/**
* Checks if a property value is null.
* Do not call this method. This is a PHP magic method that we override
* to allow using isset() to detect if a component property is set or not.
* @param string $name the property name
* @return boolean
*/
public function __isset($name)
{
$getter='get'.$name;
if (property_exists($this->getClient(),$name)) {
return true;
}
elseif (method_exists($this->getClient(),$getter)) {
return true;
}
return parent::__isset($name);
}
/**
* Sets a component property to be null.
* Do not call this method. This is a PHP magic method that we override
* to allow using unset() to set a component property to be null.
* @param string $name the property name or the event name
* @throws CException if the property is read only.
* @return mixed
*/
public function __unset($name)
{
$setter='set'.$name;
if (property_exists($this->getClient(),$name)) {
$this->getClient()->{$name} = null;
}
elseif(method_exists($this,$setter)) {
$this->$setter(null);
}
else {
parent::__unset($name);
}
}
/**
* Calls a method on the redis client with the given name.
* Do not call this method. This is a PHP magic method that we override to
* allow a facade in front of the redis object.
* @param string $name the name of the method to call
* @param array $parameters the parameters to pass to the method
* @return mixed the response from the redis client
*/
public function __call($name, $parameters) {
return call_user_func_array(array($this->getClient(),$name),$parameters);
}
}
'clusterConfig' => [
[
'host' => '192.168.140.180',
'port' => 7000,
],
[
'host' => '192.168.140.180',
'port' => 7001,
],
[
'host' => '192.168.140.181',
'port' => 7000,
],
[
'host' => '192.168.140.181',
'port' => 7001,
],
],
嗯,然后你就能在代码里边欢快的set和get: Yii:app->clusterConfig->get() 。
由于是基于phpredis拓展的,所以需要在ubuntu上为php装上拓展别忘了亲。。。拓展的安装在楼主的另外一篇文章 搭建nginx+php+mysql脚本。