Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
afe31d6
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jun 23, 2020
df6c550
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jun 23, 2020
c91a6c3
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jun 23, 2020
8840f8c
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jun 23, 2020
4227ea4
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jun 23, 2020
f46406a
Merge branch 'develop' into MCLOUD-6023
shiftedreality Jul 13, 2020
1bc6da8
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 13, 2020
0dec115
Merge remote-tracking branch 'origin/MCLOUD-6023' into MCLOUD-6023
shiftedreality Jul 13, 2020
c2dd5b2
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 14, 2020
da2bfdc
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 14, 2020
fd30afd
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 14, 2020
ccee8c5
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 15, 2020
081d40d
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 15, 2020
1b78a6c
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 15, 2020
2fcf856
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 15, 2020
e951d50
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 15, 2020
98b2239
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 15, 2020
f7b609d
MCLOUD-6023: Investigate Redis scan keys eviction
shiftedreality Jul 15, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions Console/Command/CacheEvict.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CloudComponents\Console\Command;

use Magento\CloudComponents\Model\Cache\Evictor;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Performs force key eviction with a "scan" command.
*/
class CacheEvict extends Command
{
/**
* @var Evictor
*/
private $evictor;

/**
* @param Evictor $evictor
*/
public function __construct(Evictor $evictor)
{
$this->evictor = $evictor;

parent::__construct('cache:evict');
}

/**
* @inheritDoc
*/
protected function configure()
{
$this->setDescription('Evicts unused keys by performing scan command');
}

/**
* @inheritDoc
*/
public function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Begin scanning of cache keys');

$count = $this->evictor->evict();

$output->writeln(sprintf(
'Total scanned keys: %s',
$count
));
}
}
59 changes: 59 additions & 0 deletions Cron/Evict.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CloudComponents\Cron;

use Magento\CloudComponents\Model\Cache\Evictor;
use Magento\Framework\App\DeploymentConfig;
use Psr\Log\LoggerInterface;

/**
* The cron cprocess to evict keys.
*/
class Evict
{
/**
* @var Evictor
*/
private $evictor;

/**
* @var DeploymentConfig
*/
private $deploymentConfig;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param Evictor $evictor
* @param DeploymentConfig $deploymentConfig
* @param LoggerInterface $logger
*/
public function __construct(Evictor $evictor, DeploymentConfig $deploymentConfig, LoggerInterface $logger)
{
$this->evictor = $evictor;
$this->deploymentConfig = $deploymentConfig;
$this->logger = $logger;
}

/**
* Perform keys eviction.
*/
public function execute()
{
if (!$this->deploymentConfig->get(Evictor::CONFIG_PATH_ENABLED)) {
$this->logger->info('Keys eviction is disabled');

return;
}

$this->evictor->evict();
}
}
120 changes: 120 additions & 0 deletions Model/Cache/Evictor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CloudComponents\Model\Cache;

use Magento\Framework\App\Cache\Type\FrontendPool;
use Magento\Framework\App\DeploymentConfig;
use Psr\Log\LoggerInterface;
use Credis_Client as Client;
use Cm_Cache_Backend_Redis as Backend;

/**
* Performs force key eviction with a "scan" command.
*/
class Evictor
{
const DEFAULT_EVICTION_LIMIT = 10000;
const DEFAULT_SLEEP_TIMEOUT = 20000;
const CONFIG_PATH_ENABLED = 'cache_evict/enabled';
const CONFIG_PATH_LIMIT = 'cache_evict/limit';

/**
* @var DeploymentConfig
*/
private $deploymentConfig;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param DeploymentConfig $deploymentConfig
* @param LoggerInterface $logger
*/
public function __construct(DeploymentConfig $deploymentConfig, LoggerInterface $logger)
{
$this->deploymentConfig = $deploymentConfig;
$this->logger = $logger;
}

/**
* Evicts all keys using iterator.
*
* @return int
*/
public function evict(): int
{
$options = $this->deploymentConfig->getConfigData(FrontendPool::KEY_CACHE)[FrontendPool::KEY_FRONTEND_CACHE]
?? [];
$evictedKeys = 0;

foreach ($options as $name => $cacheConfig) {
$this->logger->info(sprintf(
'Scanning keys for "%s" database',
$name
));

if (!isset(
$cacheConfig['backend_options']['server'],
$cacheConfig['backend_options']['port'],
$cacheConfig['backend_options']['database']
)) {
$this->logger->debug(sprintf(
'Cache config for database "%s" config is not valid',
$name
));

continue;
}

$dbKeys = $this->run(
$cacheConfig['backend_options']['server'],
Copy link
Contributor

@oshmyheliuk oshmyheliuk Jul 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you should check if $cacheConfig is an array and contains required keys?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

$cacheConfig['backend_options']['port'],
$cacheConfig['backend_options']['database']
);
$evictedKeys += $dbKeys;

$this->logger->info(sprintf('Keys scanned: %s', $dbKeys));
}

return $evictedKeys;
}

/**
* @param string $host
* @param int $port
* @param int $db
* @return int
*/
private function run(string $host, int $port, int $db): int
{
$client = new Client($host, $port, null, '', $db);
$evictedKeys = 0;

do {
$keys = $client->scan(
$iterator,
Backend::PREFIX_KEY . '*',
(int)$this->deploymentConfig->get(self::CONFIG_PATH_LIMIT, self::DEFAULT_EVICTION_LIMIT)
);

if ($keys === false) {
$this->logger->debug('Reached end');
} else {
$keysCount = count($keys);
$evictedKeys += $keysCount;
}

/* Give Redis some time to handle other requests */
usleep(self::DEFAULT_SLEEP_TIMEOUT);
} while ($iterator > 0);

return $evictedKeys;
}
}
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"require": {
"php": "^7.0",
"ext-json": "*",
"colinmollenhour/cache-backend-redis": "^1.9",
"colinmollenhour/credis": "^1.6",
"newrelic/monolog-enricher": "^1.0"
},
"suggest": {
Expand All @@ -21,6 +23,9 @@
"phpunit/phpunit": "^6.2",
"squizlabs/php_codesniffer": "^3.0"
},
"config": {
"sort-packages": true
},
"scripts": {
"test": [
"@phpstan",
Expand Down
14 changes: 14 additions & 0 deletions etc/crontab.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="cache_evict">
<job name="cache_evict_keys" instance="Magento\CloudComponents\Cron\Evict" method="execute">
<schedule>0 */12 * * *</schedule>
</job>
</group>
</config>
1 change: 1 addition & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<item name="configShowStoreUrlCommand" xsi:type="object">Magento\CloudComponents\Console\Command\ConfigShowStoreUrlCommand</item>
<item name="configShowEntityUrlsCommand" xsi:type="object">Magento\CloudComponents\Console\Command\ConfigShowEntityUrlsCommand</item>
<item name="ConfigShowDefaultUrlCommand" xsi:type="object">Magento\CloudComponents\Console\Command\ConfigShowDefaultUrlCommand</item>
<item name="CacheEvict" xsi:type="object">Magento\CloudComponents\Console\Command\CacheEvict</item>
</argument>
</arguments>
</type>
Expand Down