摘要:綱要中集群的應用對集群模式的底層實現中集群的應用這部分我想分享下中集群的配置官網也有集群的配置講解但是版還是有點不足只是說了將配置項設為,但光這樣一個選項不能代表,一個新手直接可用集群這部分還包括客戶端的事,所以后面我也會分享下關于的源碼分
綱要:
laravel中redis集群的應用
predis對redis集群模式的底層實現
laravel中redis集群的應用這部分我想分享下laravel5.2中redis集群的配置(官網也有redis集群的配置講解,但是5.2版還是有點不足,只是說了將cluster配置項設為true,但光這樣一個選項不能代表,一個新手直接可用redis集群,這部分還包括predis客戶端的事,所以后面我也會分享下關于predis的源碼分析)。
redis—cluster的搭建:Easy Building Redis-cluster (輕松搭建reids集群)
系統軟件清單:
laravel版本:5.2
redis版本:>=3.0下載最新版即可
predis:>=1.0下載地址
配置文件:config/database.php
"redis" => [ "cluster" => env("REDIS_CLUSTER", true), **"options"=>["cluster"=>"redis"]**, //官網沒說這個,這是必須的!!后面會講為什么這么配? "default" => [ "host" => env("REDIS_HOST", "127.0.0.1"), //任選一個master節點 "port" => env("REDIS_PORT",6379), "database" => 0, "timeout"=>15, "read_write_timeout"=>1800 //redis客戶端連接以后的讀寫超時時間(默認是60s) ], "extra"=>[ "host"=>env("REDIS_EXTRA_HOST","127.0.0.1"), //任意一個集群中的節點即可 "port"=>env("REDIS_EXTRA_PORT",7001) ] ]
ok,配完上面的步驟,redis集群就可以用了.
具體使用redis集群的應用場景根據業務需求有很多種,比如集群存session等.
app("request")->session()->put("key","value");就存到集群中了.
ok,想要了解配置文件中的參數,還是得看源代碼,當然也是predis,上代碼.
IlluminateSupportServiceProviderRedisServiceProvider; public function register() { $this->app->singleton("redis", function ($app) { return new Database($app["config"]["database.redis"]); }); } IlluminateRedisDatabase; public function __construct(array $servers = []) { $cluster = Arr::pull($servers, "cluster"); //獲取"cluster"的鍵值 $options = (array) Arr::pull($servers, "options"); //options 就是database.php中"options"的鍵值,是一個數組(但官網沒有提到,是個坑.) if ($cluster) { $this->clients = $this->createAggregateClient($servers, $options); //集群模式"cluster=true" } else { $this->clients = $this->createSingleClients($servers, $options); //單機模式 "cluster=false" } } protected function createAggregateClient(array $servers, array $options = []) { return ["default" => new Client(array_values($servers), $options)]; //predis的Client類 } ---------- 注意:這里提醒一下各參數的值: 此時$servers=[ [ "host" => env("REDIS_HOST", "127.0.0.1"), "port" => env("REDIS_PORT",6379), "database" => 0, "timeout"=>15, "read_write_timeout"=>1800 ], [ "host"=>env("REDIS_EXTRA_HOST","127.0.0.1"), "port"=>env("REDIS_EXTRA_PORT",7001) ] ] $options = ["cluster"=>"redis"] 其實到這兒,就可以解釋在database.php中增加options選項,而且是必選項,因為底層代碼需要判斷數據切片的方式. 除了看源碼, predis的包文檔也做了解釋.https://packagist.org/packages/predis/predis -------
接下來我們看看這些底層要初始化的類吧.
PredisClient; public function __construct($parameters = null, $options = null) { $this->options = $this->createOptions($options ?: array()); #$this->connection = $this->createConnection($parameters ?: array()); #$this->profile = $this->options->profile; } protected function createOptions($options) { if (is_array($options)) { return new Options($options); //如你所見,實例化Options類 } if ($options instanceof OptionsInterface) { return $options; } throw new InvalidArgumentException("Invalid type for client options."); } public function __construct(array $options = array()) { $this->input = $options; $this->options = array(); $this->handlers = $this->getHandlers(); }
$this->connection = $this->createConnection($parameters ?: array())
PredisClient 文件 protected function createConnection($parameters) { # if ($parameters instanceof ConnectionInterface) { # return $parameters; # } # if ($parameters instanceof ParametersInterface || is_string($parameters)) { # return $this->options->connections->create($parameters); # } # if (is_array($parameters)) { # if (!isset($parameters[0])) { # return $this->options->connections->create($parameters); # } $options = $this->options; # if ($options->defined("aggregate")) { # $initializer = $this->getConnectionInitializerWrapper($options->aggregate); # $connection = $initializer($parameters, $options); # } else { # if ($options->defined("replication") && $replication = $options->replication) { # $connection = $replication; # } else { $connection = $options->cluster; // # } $options->connections->aggregate($connection, $parameters); # } return $connection; # } # if (is_callable($parameters)) { # $initializer = $this->getConnectionInitializerWrapper($parameters); # $connection = $initializer($this->options); # return $connection; # } # throw new InvalidArgumentException("Invalid type for connection parameters."); } PredisConfigurationOptions; protected function getHandlers() { return array( "cluster" => "PredisConfigurationClusterOption", "connections" => "PredisConfigurationConnectionFactoryOption", #"exceptions" => "PredisConfigurationExceptionsOption", #"prefix" => "PredisConfigurationPrefixOption", #"profile" => "PredisConfigurationProfileOption", #"replication" => "PredisConfigurationReplicationOption", ); } public function __get($option) { #if (isset($this->options[$option]) || array_key_exists($option, $this->options)) { # return $this->options[$option]; #} if (isset($this->input[$option]) || array_key_exists($option, $this->input)) { $value = $this->input[$option]; unset($this->input[$option]); # if (is_object($value) && method_exists($value, "__invoke"){ # $value = $value($this, $option); # } if (isset($this->handlers[$option])) { $handler = $this->handlers[$option]; $handler = new $handler(); //會實例化PredisConfigurationClusterOption類 $value = $handler->filter($this, $value); } return $this->options[$option] = $value; } # if (isset($this->handlers[$option])) { # return $this->options[$option] = $this->getDefault($option); # } # return; } PredisConfigurationClusterOption文件 public function filter(OptionsInterface $options, $value) { if (is_string($value)) { $value = $this->createByDescription($options, $value); } # if (!$value instanceof ClusterInterface) { # throw new InvalidArgumentException( # "An instance of type "PredisConnectionAggregateClusterInterface" was expected." # ); # } return $value; } protected function createByDescription(OptionsInterface $options, $id) { switch ($id) { * Abstraction for a cluster of aggregate connections to various Redis servers * implementing client-side sharding based on pluggable distribution strategies. # case "predis": # case "predis-cluster": # return new PredisCluster(); //這個模式是客戶端通過CRC16算法在客戶端進行數據切片, 顯然這種模式的集群是脆弱的,如果一個master節點掛了, 那其備節點若也掛了,那么獲取數據就成問題了; 再有這種模式擴展性很差,維護成本高, 因此這個模式不推薦.當然用最新predis不存在這個問題. 我這邊predis,1.0算比較老了. case "redis": case "redis-cluster": return new RedisCluster($options->connections); //這種模式是基于服務端的數據切片,相較于第一種模式,優點也顯而易見,維護成本低,擴展性好等. default: return; } } public function __get($option) { #if (isset($this->options[$option]) || array_key_exists($option, $this->options)) { # return $this->options[$option]; #} # if (isset($this->input[$option]) || array_key_exists($option, $this->input)) { # $value = $this->input[$option]; # unset($this->input[$option]); # if (is_object($value) && method_exists($value, "__invoke"){ # $value = $value($this, $option); # } # if (isset($this->handlers[$option])) { # $handler = $this->handlers[$option]; # $handler = new $handler(); # $value = $handler->filter($this, $value); # } # return $this->options[$option] = $value; #} if (isset($this->handlers[$option])) { //$options="connections" return $this->options[$option] = $this->getDefault($option); # } # return; } public function getDefault($option) { if (isset($this->handlers[$option])) { $handler = $this->handlers[$option]; //$handler = "PredisConfigurationConnectionFactoryOption"; $handler = new $handler(); return $handler->getDefault($this); } } PredisConfigurationConnectionFactoryOption文件 public function getDefault(OptionsInterface $options) { return new Factory(); //最后實例化了一個"工廠"類 }
$this->profile = $this->options->profile;
PredisConfigurationProfileOption文件 public function __get($option) { #if (isset($this->options[$option]) || array_key_exists($option, $this->options)) { # return $this->options[$option]; #} # if (isset($this->input[$option]) || array_key_exists($option, $this->input)) { # $value = $this->input[$option]; # unset($this->input[$option]); # if (is_object($value) && method_exists($value, "__invoke"){ # $value = $value($this, $option); # } # if (isset($this->handlers[$option])) { # $handler = $this->handlers[$option]; # $handler = new $handler(); # $value = $handler->filter($this, $value); # } # return $this->options[$option] = $value; #} if (isset($this->handlers[$option])) { //$options="profile" return $this->options[$option] = $this->getDefault($option); # } # return; } public function getDefault($option) { if (isset($this->handlers[$option])) { $handler = $this->handlers[$option]; //$handler = "PredisConfigurationProfileOption"; $handler = new $handler(); return $handler->getDefault($this); } } PredisConfigurationProfileOption文件 public function getDefault(OptionsInterface $options) { $profile = Factory::getDefault(); //實例化了PredisProfileRedisVersion300類 $this->setProcessors($options, $profile); return $profile; }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/23076.html
摘要:綱要中集群的應用對集群模式的底層實現中集群的應用這部分我想分享下中集群的配置官網也有集群的配置講解但是版還是有點不足只是說了將配置項設為,但光這樣一個選項不能代表,一個新手直接可用集群這部分還包括客戶端的事,所以后面我也會分享下關于的源碼分 綱要: laravel中redis集群的應用 predis對redis集群模式的底層實現 laravel中redis集群的應用 這部分我想分享...
摘要:環境配置機器下載獨立文件位置安裝關鍵點工具實現集群復制到目錄下。創建集群命令發現環境需要下安裝方案下安裝方案如果不好用,可以切換到淘寶源然后再次執行即可。說明集群正常工作。互聯網時代,時刻要保持學習,攜手千鋒。 1 環境配置: ubuntu16.04 redis3.0.62 機器: 192.168.50.156 192.168.50.154 192.168.50.1553 下載red...
閱讀 2308·2021-11-24 09:39
閱讀 3039·2021-10-15 09:39
閱讀 3088·2021-07-26 23:38
閱讀 2288·2019-08-30 11:14
閱讀 3409·2019-08-29 16:39
閱讀 1713·2019-08-29 15:23
閱讀 778·2019-08-29 13:01
閱讀 2663·2019-08-29 12:29