@@ -150,17 +150,14 @@ protected function getClientOptions($options = array())
150150 */
151151 public function __construct ($ options = array ())
152152 {
153- if ( empty ($ options ['server ' ]) ) {
153+ if ( empty ($ options ['server ' ]) && empty ( $ options [ ' cluster ' ]) ) {
154154 Zend_Cache::throwException ('Redis \'server \' not specified. ' );
155155 }
156156
157- $ port = isset ($ options ['port ' ]) ? $ options ['port ' ] : 6379 ;
158- $ slaveSelect = isset ($ options ['slave_select_callable ' ]) && is_callable ($ options ['slave_select_callable ' ]) ? $ options ['slave_select_callable ' ] : null ;
159- $ sentinelMaster = empty ($ options ['sentinel_master ' ]) ? NULL : $ options ['sentinel_master ' ];
160-
161157 $ this ->_clientOptions = $ this ->getClientOptions ($ options );
162158
163159 // If 'sentinel_master' is specified then server is actually sentinel and master address should be fetched from server.
160+ $ sentinelMaster = empty ($ options ['sentinel_master ' ]) ? NULL : $ options ['sentinel_master ' ];
164161 if ($ sentinelMaster ) {
165162 $ sentinelClientOptions = isset ($ options ['sentinel ' ]) && is_array ($ options ['sentinel ' ])
166163 ? $ this ->getClientOptions ($ options ['sentinel ' ] + $ options )
@@ -220,6 +217,7 @@ public function __construct($options = array())
220217 if ($ options ['load_from_slaves ' ] == 2 ) {
221218 array_push ($ slaves , $ this ->_redis ); // Also send reads to the master
222219 }
220+ $ slaveSelect = isset ($ options ['slave_select_callable ' ]) && is_callable ($ options ['slave_select_callable ' ]) ? $ options ['slave_select_callable ' ] : null ;
223221 if ($ slaveSelect ) {
224222 $ slave = $ slaveSelect ($ slaves , $ this ->_redis );
225223 } else {
@@ -240,28 +238,52 @@ public function __construct($options = array())
240238 }
241239
242240 // Instantiate Credis_Cluster
241+ // DEPRECATED
243242 else if ( ! empty ($ options ['cluster ' ])) {
244243 $ this ->_setupReadWriteCluster ($ options );
245244 }
246245
247- // Direct connection to single Redis server
246+ // Direct connection to single Redis server and optional slaves
248247 else {
248+ $ port = isset ($ options ['port ' ]) ? $ options ['port ' ] : 6379 ;
249249 $ this ->_redis = new Credis_Client ($ options ['server ' ], $ port , $ this ->_clientOptions ->timeout , $ this ->_clientOptions ->persistent );
250250 $ this ->_applyClientOptions ($ this ->_redis );
251251
252252 // Support loading from a replication slave
253253 if (isset ($ options ['load_from_slave ' ])) {
254254 if (is_array ($ options ['load_from_slave ' ])) {
255- $ server = $ options ['load_from_slave ' ]['server ' ];
256- $ port = $ options ['load_from_slave ' ]['port ' ];
257-
258- $ clientOptions = $ this ->getClientOptions ($ options ['load_from_slave ' ] + $ options );
259- } else {
255+ if (isset ($ options ['load_from_slave ' ]['server ' ])) { // Single slave
256+ $ server = $ options ['load_from_slave ' ]['server ' ];
257+ $ port = $ options ['load_from_slave ' ]['port ' ];
258+ $ clientOptions = $ this ->getClientOptions ($ options ['load_from_slave ' ] + $ options );
259+ $ totalServers = 2 ;
260+ } else { // Multiple slaves
261+ $ slaveKey = array_rand ($ options ['load_from_slave ' ], 1 );
262+ $ slave = $ options ['load_from_slave ' ][$ slaveKey ];
263+ $ server = $ slave ['server ' ];
264+ $ port = $ slave ['port ' ];
265+ $ clientOptions = $ this ->getClientOptions ($ slave + $ options );
266+ $ totalServers = count ($ options ['load_from_slave ' ]) + 1 ;
267+ }
268+ } else { // String
260269 $ server = $ options ['load_from_slave ' ];
261270 $ port = 6379 ;
262271 $ clientOptions = $ this ->_clientOptions ;
272+
273+ // If multiple addresses are given, split and choose a random one
274+ if (strpos ($ server , ', ' ) !== FALSE ) {
275+ $ slaves = preg_split ('/\s*,\s*/ ' , $ server , -1 , PREG_SPLIT_NO_EMPTY );
276+ $ slaveKey = array_rand ($ slaves , 1 );
277+ $ server = $ slaves [$ slaveKey ];
278+ $ port = NULL ;
279+ $ totalServers = count ($ slaves ) + 1 ;
280+ } else {
281+ $ totalServers = 2 ;
282+ }
263283 }
264- if (is_string ($ server )) {
284+ // Skip setting up slave if master is not write only and it is randomly chosen to be the read server
285+ $ masterWriteOnly = isset ($ options ['master_write_only ' ]) ? (int ) $ options ['master_write_only ' ] : FALSE ;
286+ if (is_string ($ server ) && $ server && ! (!$ masterWriteOnly && rand (1 ,$ totalServers ) === 1 )) {
265287 try {
266288 $ slave = new Credis_Client ($ server , $ port , $ clientOptions ->timeout , $ clientOptions ->persistent );
267289 $ this ->_applyClientOptions ($ slave , TRUE , $ clientOptions );
@@ -394,50 +416,39 @@ protected function _applyClientOptions(Credis_Client $client, $forceSelect = FAL
394416 }
395417 }
396418
397- protected function _setupReadWriteCluster ($ options ) {
398- $ clusterNodes = array ();
399-
400- if (array_key_exists ('master ' , $ options ['cluster ' ]) && !empty ($ options ['cluster ' ]['master ' ])) {
419+ /**
420+ * @deprecated - Previously this setup an instance of Credis_Cluster but this class was not complete or flawed
421+ * @param $options
422+ */
423+ protected function _setupReadWriteCluster ($ options )
424+ {
425+ if (!empty ($ options ['cluster ' ]['master ' ])) {
401426 foreach ($ options ['cluster ' ]['master ' ] as $ masterNode ) {
402427 if (empty ($ masterNode ['server ' ]) || empty ($ masterNode ['port ' ])) {
403428 continue ;
404429 }
405430
406- $ clusterNodes [] = array (
407- 'host ' => $ masterNode ['server ' ],
408- 'port ' => $ masterNode ['port ' ],
409- 'alias ' => 'master ' ,
410- 'master ' => true ,
411- 'write_only ' => true ,
412- 'timeout ' => $ this ->_clientOptions ->timeout ,
413- 'persistent ' => $ this ->_clientOptions ->persistent ,
414- 'db ' => (int ) $ options ['database ' ],
431+ $ this ->_redis = new Credis_Client (
432+ $ masterNode ['host ' ],
433+ $ masterNode ['port ' ],
434+ isset ($ masterNode ['timeout ' ]) ? $ masterNode ['timeout ' ] : 2.5 ,
435+ isset ($ masterNode ['persistent ' ]) ? $ masterNode ['persistent ' ] : ''
415436 );
416-
417- break ; // limit to 1
437+ $ this -> _applyClientOptions ( $ this -> _redis );
438+ break ;
418439 }
419440 }
420441
421- if (!empty ($ clusterNodes ) && array_key_exists ('slave ' , $ options ['cluster ' ]) && !empty ($ options ['cluster ' ]['slave ' ])) {
422- foreach ($ options ['cluster ' ]['slave ' ] as $ slaveNodes ) {
423- if (empty ($ masterNode ['server ' ]) || empty ($ masterNode ['port ' ])) {
424- continue ;
425- }
426-
427- $ clusterNodes [] = array (
428- 'host ' => $ slaveNodes ['server ' ],
429- 'port ' => $ slaveNodes ['port ' ],
430- 'alias ' => 'slave ' . count ($ clusterNodes ),
431- 'timeout ' => $ this ->_clientOptions ->timeout ,
432- 'persistent ' => $ this ->_clientOptions ->persistent ,
433- 'db ' => (int ) $ options ['database ' ],
434- 'password ' => $ options ['password ' ],
435- );
436- }
437- }
438-
439- if (!empty ($ clusterNodes )) {
440- $ this ->_redis = new Credis_Cluster ($ clusterNodes );
442+ if (!empty ($ options ['cluster ' ]['slave ' ])) {
443+ $ slaveKey = array_rand ($ options ['cluster ' ]['slave ' ], 1 );
444+ $ slave = $ options ['cluster ' ]['slave ' ][$ slaveKey ];
445+ $ this ->_slave = new Credis_Client (
446+ $ slave ['host ' ],
447+ $ slave ['port ' ],
448+ isset ($ slave ['timeout ' ]) ? $ slave ['timeout ' ] : 2.5 ,
449+ isset ($ slave ['persistent ' ]) ? $ slave ['persistent ' ] : ''
450+ );
451+ $ this ->_applyClientOptions ($ this ->_redis , TRUE );
441452 }
442453 }
443454
0 commit comments