Skip to content

Commit 159c737

Browse files
committed
Adding support of Redis Sentinel to Cache, PageCache, and Session.
Update version of CM modules requirement. Adding Tests for Redis Session Configuration. Update unit tests for Redis usage with Sentinel. Update version of CM modules requirement.
1 parent 6f4ab5f commit 159c737

File tree

9 files changed

+433
-35
lines changed

9 files changed

+433
-35
lines changed

lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,26 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface
100100
*/
101101
const PARAM_BREAK_AFTER = 'session/redis/break_after';
102102

103+
/**
104+
* Configuration path for number of seconds to wait before completely failing to break the lock
105+
*/
106+
const PARAM_FAIL_AFTER = 'session/redis/fail_after';
107+
108+
/**
109+
* The name of master to reach via Sentinel servers.
110+
*/
111+
const PARAM_SENTINEL_MASTER = 'session/redis/sentinel_master';
112+
113+
/**
114+
* Configuration path indicating if master status should be verified during connections.
115+
*/
116+
const PARAM_SENTINEL_VERIFY_MASTER = 'session/redis/sentinel_master_verify';
117+
118+
/**
119+
* Configuration path indicating the number of connect retries for sentinel servers connection.
120+
*/
121+
const PARAM_SENTINEL_CONNECT_RETRIES = 'session/redis/sentinel_connect_retries';
122+
103123
/**
104124
* Cookie lifetime config path
105125
*/
@@ -300,10 +320,52 @@ public function getLifetime()
300320
}
301321

302322
/**
303-
* {@inheritdoc}
323+
* Get number of seconds to wait before completely failing to break the lock
324+
*
325+
* @return int
304326
*/
305327
public function getFailAfter()
306328
{
307-
return self::DEFAULT_FAIL_AFTER;
329+
return $this->deploymentConfig->get(self::PARAM_FAIL_AFTER . '_' . $this->appState->getAreaCode());
330+
}
331+
332+
/**
333+
* Get list of redis sentinels
334+
*
335+
* @return string
336+
*/
337+
public function getSentinelServers()
338+
{
339+
return $this->getHost();
340+
}
341+
342+
/**
343+
* Get sentinel master name
344+
*
345+
* @return string
346+
*/
347+
public function getSentinelMaster()
348+
{
349+
return $this->deploymentConfig->get(self::PARAM_SENTINEL_MASTER);
350+
}
351+
352+
/**
353+
* Verify master status flag
354+
*
355+
* @return string
356+
*/
357+
public function getSentinelVerifyMaster()
358+
{
359+
return $this->deploymentConfig->get(self::PARAM_SENTINEL_VERIFY_MASTER);
360+
}
361+
362+
/**
363+
* Connection retries for sentinels
364+
*
365+
* @return string
366+
*/
367+
public function getSentinelConnectRetries()
368+
{
369+
return $this->deploymentConfig->get(self::PARAM_SENTINEL_CONNECT_RETRIES);
308370
}
309371
}

lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,20 @@ public function testBreakAfter()
216216
$this->assertEquals($this->config->getBreakAfter(), $breakAfter);
217217
}
218218

219+
public function testFailAfter()
220+
{
221+
$areaCode = 'frontend';
222+
$breakAfter = 5;
223+
$this->deploymentConfigMock->expects($this->once())
224+
->method('get')
225+
->with(Config::PARAM_FAIL_AFTER . '_' . $areaCode)
226+
->willReturn($breakAfter);
227+
$this->appStateMock->expects($this->once())
228+
->method('getAreaCode')
229+
->willReturn($areaCode);
230+
$this->assertEquals($this->config->getFailAfter(), $breakAfter);
231+
}
232+
219233
public function testGetLifetimeAdmin()
220234
{
221235
$areaCode = 'adminhtml';
@@ -246,4 +260,44 @@ public function testGetLifetimeFrontend()
246260
->willReturn($expectedLifetime);
247261
$this->assertEquals($this->config->getLifetime(), $expectedLifetime);
248262
}
263+
264+
public function testGetSentinelServers()
265+
{
266+
$expected = 'tcp://127.0.0.1:26379,tcp://127.0.0.2:26379';
267+
$this->deploymentConfigMock->expects($this->once())
268+
->method('get')
269+
->with(Config::PARAM_HOST)
270+
->willReturn($expected);
271+
$this->assertEquals($this->config->getSentinelServers(), $expected);
272+
}
273+
274+
public function testGetSentinelMaster()
275+
{
276+
$expected = 'redismaster';
277+
$this->deploymentConfigMock->expects($this->once())
278+
->method('get')
279+
->with(Config::PARAM_SENTINEL_MASTER)
280+
->willReturn($expected);
281+
$this->assertEquals($this->config->getSentinelMaster(), $expected);
282+
}
283+
284+
public function testGetSentinelVerifyMaster()
285+
{
286+
$expected = '1';
287+
$this->deploymentConfigMock->expects($this->once())
288+
->method('get')
289+
->with(Config::PARAM_SENTINEL_VERIFY_MASTER)
290+
->willReturn($expected);
291+
$this->assertEquals($this->config->getSentinelVerifyMaster(), $expected);
292+
}
293+
294+
public function testGetSentinelConnectRetries()
295+
{
296+
$expected = '3';
297+
$this->deploymentConfigMock->expects($this->once())
298+
->method('get')
299+
->with(Config::PARAM_SENTINEL_CONNECT_RETRIES)
300+
->willReturn($expected);
301+
$this->assertEquals($this->config->getSentinelConnectRetries(), $expected);
302+
}
249303
}

setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,30 @@ class Cache implements ConfigOptionsListInterface
2626
const INPUT_KEY_CACHE_BACKEND_REDIS_SERVER = 'cache-backend-redis-server';
2727
const INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE = 'cache-backend-redis-db';
2828
const INPUT_KEY_CACHE_BACKEND_REDIS_PORT = 'cache-backend-redis-port';
29+
const INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER = 'cache-backend-redis-sentinel-master';
30+
const INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY = 'cache-backend-redis-sentinel-master-verify';
31+
const INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES= 'cache-backend-redis-sentinel-load-from-slaves';
2932

3033
const CONFIG_PATH_CACHE_BACKEND = 'cache/frontend/default/backend';
3134
const CONFIG_PATH_CACHE_BACKEND_SERVER = 'cache/frontend/default/backend_options/server';
3235
const CONFIG_PATH_CACHE_BACKEND_DATABASE = 'cache/frontend/default/backend_options/database';
3336
const CONFIG_PATH_CACHE_BACKEND_PORT = 'cache/frontend/default/backend_options/port';
37+
const CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER = 'cache/frontend/default/backend_options/sentinel_master';
38+
const CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY =
39+
'cache/frontend/default/backend_options/sentinel_master_verify';
40+
const CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES =
41+
'cache/frontend/default/backend_options/load_from_slaves';
3442

3543
/**
3644
* @var array
3745
*/
3846
private $defaultConfigValues = [
3947
self::INPUT_KEY_CACHE_BACKEND_REDIS_SERVER => '127.0.0.1',
4048
self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE => '0',
41-
self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT => '6379'
49+
self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT => '6379',
50+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER => null,
51+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY => null,
52+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES => null,
4253
];
4354

4455
/**
@@ -55,6 +66,11 @@ class Cache implements ConfigOptionsListInterface
5566
self::INPUT_KEY_CACHE_BACKEND_REDIS_SERVER => self::CONFIG_PATH_CACHE_BACKEND_SERVER,
5667
self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE => self::CONFIG_PATH_CACHE_BACKEND_DATABASE,
5768
self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT => self::CONFIG_PATH_CACHE_BACKEND_PORT,
69+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER => self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER,
70+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY =>
71+
self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY,
72+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES =>
73+
self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES,
5874
];
5975

6076
/**
@@ -102,7 +118,26 @@ public function getOptions()
102118
TextConfigOption::FRONTEND_WIZARD_TEXT,
103119
self::CONFIG_PATH_CACHE_BACKEND_PORT,
104120
'Redis server listen port'
105-
)
121+
),
122+
new TextConfigOption(
123+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER,
124+
TextConfigOption::FRONTEND_WIZARD_TEXT,
125+
self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER,
126+
'Redis sentinel master'
127+
),
128+
new TextConfigOption(
129+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY,
130+
TextConfigOption::FRONTEND_WIZARD_TEXT,
131+
self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY,
132+
'Verify connected server is actually master'
133+
),
134+
new TextConfigOption(
135+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES,
136+
TextConfigOption::FRONTEND_WIZARD_TEXT,
137+
self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES,
138+
'Using the value \'1\' indicates to only load from slaves and \'2\' ' .
139+
'to include the master in the random read slave selection'
140+
),
106141
];
107142
}
108143

@@ -191,7 +226,21 @@ private function validateRedisConfig(array $options, DeploymentConfig $deploymen
191226
$this->getDefaultConfigValue(self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE)
192227
);
193228

194-
return $this->redisValidator->isValidConnection($config);
229+
$config['sentinel_master'] = isset($options[self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER])
230+
? $options[self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER]
231+
: $deploymentConfig->get(
232+
self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER,
233+
$this->getDefaultConfigValue(self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER)
234+
);
235+
236+
$config['sentinel_master_verify'] = isset($options[self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY])
237+
? $options[self::INPUT_KEY_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY]
238+
: $deploymentConfig->get(
239+
self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY,
240+
$this->getDefaultConfigValue(self::CONFIG_PATH_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY)
241+
);
242+
243+
return $this->redisValidator->isValidConnection(array_filter($config));
195244
}
196245

197246
/**

setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,22 @@ class PageCache implements ConfigOptionsListInterface
2727
const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_DATABASE = 'page-cache-redis-db';
2828
const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_PORT = 'page-cache-redis-port';
2929
const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_COMPRESS_DATA = 'page-cache-redis-compress-data';
30+
const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER = 'page-cache-redis-sentinel-master';
31+
const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY = 'page-cache-redis-sentinel-master-verify';
32+
const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES= 'page-cache-redis-sentinel-load-from-slaves';
3033

3134
const CONFIG_PATH_PAGE_CACHE_BACKEND = 'cache/frontend/page_cache/backend';
3235
const CONFIG_PATH_PAGE_CACHE_BACKEND_SERVER = 'cache/frontend/page_cache/backend_options/server';
3336
const CONFIG_PATH_PAGE_CACHE_BACKEND_DATABASE = 'cache/frontend/page_cache/backend_options/database';
3437
const CONFIG_PATH_PAGE_CACHE_BACKEND_PORT = 'cache/frontend/page_cache/backend_options/port';
35-
const CONFIG_PATH_PAGE_CACHE_BACKEND_COMPRESS_DATA = 'cache/frontend/page_cache/backend_options/compress_data';
38+
const CONFIG_PATH_PAGE_CACHE_BACKEND_COMPRESS_DATA =
39+
'cache/frontend/page_cache/backend_options/compress_data';
40+
const CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER =
41+
'cache/frontend/page_cache/backend_options/sentinel_master';
42+
const CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY =
43+
'cache/frontend/page_cache/backend_options/sentinel_master_verify';
44+
const CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES =
45+
'cache/frontend/page_cache/backend_options/load_from_slaves';
3646

3747
/**
3848
* @var array
@@ -41,7 +51,10 @@ class PageCache implements ConfigOptionsListInterface
4151
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SERVER => '127.0.0.1',
4252
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_DATABASE => '1',
4353
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_PORT => '6379',
44-
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_COMPRESS_DATA => '0'
54+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_COMPRESS_DATA => '0',
55+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER => null,
56+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY => null,
57+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES => null,
4558
];
4659

4760
/**
@@ -58,7 +71,13 @@ class PageCache implements ConfigOptionsListInterface
5871
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SERVER => self::CONFIG_PATH_PAGE_CACHE_BACKEND_SERVER,
5972
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_DATABASE => self::CONFIG_PATH_PAGE_CACHE_BACKEND_DATABASE,
6073
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_PORT => self::CONFIG_PATH_PAGE_CACHE_BACKEND_PORT,
61-
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_COMPRESS_DATA => self::CONFIG_PATH_PAGE_CACHE_BACKEND_COMPRESS_DATA
74+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_COMPRESS_DATA => self::CONFIG_PATH_PAGE_CACHE_BACKEND_COMPRESS_DATA,
75+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER =>
76+
self::CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER,
77+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY =>
78+
self::CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY,
79+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES =>
80+
self::CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES,
6281
];
6382

6483
/**
@@ -112,7 +131,26 @@ public function getOptions()
112131
TextConfigOption::FRONTEND_WIZARD_TEXT,
113132
self::CONFIG_PATH_PAGE_CACHE_BACKEND_COMPRESS_DATA,
114133
'Set to 1 to compress the full page cache (use 0 to disable)'
115-
)
134+
),
135+
new TextConfigOption(
136+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER,
137+
TextConfigOption::FRONTEND_WIZARD_TEXT,
138+
self::CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER,
139+
'Redis sentinel master'
140+
),
141+
new TextConfigOption(
142+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY,
143+
TextConfigOption::FRONTEND_WIZARD_TEXT,
144+
self::CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY,
145+
'Verify connected server is actually master'
146+
),
147+
new TextConfigOption(
148+
self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES,
149+
TextConfigOption::FRONTEND_WIZARD_TEXT,
150+
self::CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_LOAD_FROM_SLAVES,
151+
'Using the value \'1\' indicates to only load from slaves ' .
152+
'and \'2\' to include the master in the random read slave selection'
153+
),
116154
];
117155
}
118156

@@ -202,7 +240,22 @@ private function validateRedisConfig(array $options, DeploymentConfig $deploymen
202240
$this->getDefaultConfigValue(self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_DATABASE)
203241
);
204242

205-
return $this->redisValidator->isValidConnection($config);
243+
$config['sentinel_master'] = isset($options[self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER])
244+
? $options[self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER]
245+
: $deploymentConfig->get(
246+
self::CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER,
247+
null
248+
);
249+
250+
$config['sentinel_master_verify'] =
251+
isset($options[self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY])
252+
? $options[self::INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY]
253+
: $deploymentConfig->get(
254+
self::CONFIG_PATH_PAGE_CACHE_BACKEND_REDIS_SENTINEL_MASTER_VERIFY,
255+
null
256+
);
257+
258+
return $this->redisValidator->isValidConnection(array_filter($config));
206259
}
207260

208261
/**

0 commit comments

Comments
 (0)