From 3c6be673247702144d04e62194b34a0bd2c52e4e Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov Date: Tue, 18 Feb 2020 15:08:29 -0600 Subject: [PATCH] MC-21504: Decrease Redis CPU consumptions by loading cache that frequently used in one pipeline P1 --- .../Magento/Framework/Cache/Backend/Redis.php | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Cache/Backend/Redis.php b/lib/internal/Magento/Framework/Cache/Backend/Redis.php index a2ce7001fa4a6..d2c7e9ecd9da8 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Redis.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Redis.php @@ -7,10 +7,60 @@ namespace Magento\Framework\Cache\Backend; /** - * Redis wrapper to suppress exceptions on save + * Redis wrapper to extend current implementation behaviour. */ class Redis extends \Cm_Cache_Backend_Redis { + /** + * Local state of preloaded keys. + * + * @var array + */ + private $preloadedData = []; + + /** + * Array of keys to be preloaded. + * + * @var array + */ + private $preloadKeys = []; + + /** + * @param array $options + */ + public function __construct($options = array()) + { + $this->preloadKeys = $options['preload_keys'] ?? []; + parent::__construct($options); + } + + /** + * Load value with given id from cache + * + * @param string $id Cache id + * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested + * @return bool|string + */ + public function load($id, $doNotTestCacheValidity = false) + { + if (!empty($this->preloadKeys) && empty($this->preloadedData)) { + $redis = $this->_slave ?? $this->_redis; + $redis = $redis->pipeline(); + + foreach ($this->preloadKeys as $key) { + $redis->hGet(self::PREFIX_KEY . $key, self::FIELD_DATA); + } + + $this->preloadedData= array_combine($this->preloadKeys, $redis->exec()); + } + + if (isset($this->preloadedData[$id])) { + return $this->_decodeData($this->preloadedData[$id]); + } + + return parent::load($id, $doNotTestCacheValidity = false); + } + /** * The idea is that base implementation doesn't handle errors on save operations. * Which may occurs when Redis cannot evict keys, which is expected in some cases.