Przeglądaj źródła

#2098 Add Redis cache to caching engines

Aleksandr T 9 miesięcy temu
rodzic
commit
a81ea0c688

+ 174 - 0
inc/classes/BxDolCacheRedis.php

@@ -0,0 +1,174 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+class BxDolCacheRedis extends BxDolCache
+{
+    protected $iTTL = 3600;
+    protected $oRedis = null;
+
+    /**
+     * constructor
+     */
+    function __construct()
+    {
+        parent::__construct();
+        
+        $s = getParam('sys_cache_redis_connection_string');
+        if (class_exists('Redis') && false !== ($a = parse_url($s))) {
+            $this->oRedis = new Redis();
+            $sHost = $a['host'] ?? 'localhost';
+            $iPort = isset($a['port']) && (int)$a['port'] != 0 ? (int)$a['port'] : 6379;
+            $iDatabase = $a['path'] ? (int)trim($a['path'], '/') : 0;
+            $sPassword = $a['user'] ?? '';
+
+            try {
+                if (!$this->oRedis->connect($sHost, $iPort)) {
+                    $this->oRedis = null;
+                } else {
+                    if ($sPassword && !$this->oRedis->auth($sPassword)) {
+                        $this->oRedis = null;
+                    } elseif (!$this->oRedis->select($iDatabase)) {
+                        $this->oRedis = null;
+                    }
+                }
+            } catch (Exception $e) {
+                $this->oRedis = null;
+            }
+
+            if ($this->oRedis != null) {
+                $serializer = (
+                    defined('Redis::SERIALIZER_IGBINARY') &&
+                    extension_loaded('igbinary')
+                ) ? Redis::SERIALIZER_IGBINARY : Redis::SERIALIZER_PHP;                
+                $this->oRedis->setOption(Redis::OPT_SERIALIZER, $serializer);
+                //echoDbgLog("Serializer:" . $this->oRedis->getOption(Redis::OPT_SERIALIZER));
+            }
+        }
+    }
+
+    /**
+     * Get data from cache server
+     *
+     * @param  string $sKey - cache key
+     * @param  int    $iTTL - time to live
+     * @return the    data is got from cache.
+     */
+    function getData($sKey, $iTTL = false)
+    {
+        if (!$this->oRedis) {
+            return null;
+        }
+        
+        $mixedData = $this->oRedis->get($sKey);
+        return false === $mixedData ? null : $mixedData;
+    }
+
+    /**
+     * Save data in cache server
+     *
+     * @param  string  $sKey      - cache key
+     * @param  mixed   $mixedData - the data to be cached
+     * @param  int     $iTTL      - time to live
+     * @return boolean result of operation.
+     */
+    function setData($sKey, $mixedData, $iTTL = false)
+    {
+        if (!$this->oRedis) {
+            return false;
+        }
+        
+        $iExpire = false === $iTTL ? $this->iTTL : $iTTL;
+        if ($iExpire) {
+            return $this->oRedis->setex($sKey, $iExpire, $mixedData);
+        } else {
+            return $this->oRedis->set($sKey, $mixedData);
+        }
+    }
+
+    /**
+     * Delete cache from cache server
+     *
+     * @param  string $sKey - cache key
+     * @return result of the operation
+     */
+    function delData($sKey)
+    {
+        if (!$this->oRedis) {
+            return false;
+        }
+        
+        $this->oRedis->del($sKey);
+        return true;
+    }
+
+    /**
+     * Remove all keys by prefix
+     *
+     * @param  string $sPrefix - key prefix
+     * @return boolean result of operation.
+     */
+    function removeAllByPrefix($sPrefix)
+    {
+        if (!$this->oRedis) {
+            return false;
+        }
+        
+        $aKeys = $this->oRedis->keys($sPrefix . '*');
+        if ($aKeys && count($aKeys) > 0) {
+            return $this->oRedis->del($aKeys) > 0;
+        }
+        
+        return true;
+    }
+
+    /**
+     * Get size of all keys by prefix
+     *
+     * @param  string $sPrefix - key prefix
+     * @return int size in bytes or 0 if no keys found.
+     */
+    function getSizeByPrefix($sPrefix)
+    {
+        if (!$this->oRedis) {
+            return 0;
+        }
+        
+        $aKeys = $this->oRedis->keys($sPrefix . '*');
+        if (!$aKeys) {
+            return 0;
+        }
+
+        $iSize = 0;
+        foreach ($aKeys as $sKey) {
+            $iSize += strlen($this->oRedis->rawCommand('MEMORY', 'USAGE', $sKey));
+        }
+        
+        return $iSize;
+    }
+
+    /**
+     * Check if Redis is available
+     * @return boolean
+     */
+    function isAvailable()
+    {
+        return $this->oRedis == null ? false : true;
+    }
+
+    /**
+     * Check if Redis extension is loaded
+     * @return boolean
+     */
+    function isInstalled()
+    {
+        return extension_loaded('redis');
+    }
+}
+
+/** @} */

+ 19 - 18
install/sql/system.sql

@@ -605,29 +605,30 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `info`, `value`, `ty
 INSERT INTO `sys_options_categories`(`type_id`, `name`, `caption`, `hidden`, `order`) VALUES (@iTypeId, 'cache', '_adm_stg_cpt_category_cache', 0, 6);
 SET @iCategoryId = LAST_INSERT_ID();
 
-INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
-(@iCategoryId, 'sys_content_cache_enable', '_adm_stg_cpt_option_sys_content_cache_enable', 'on', 'checkbox', '', '', '', 5),
-(@iCategoryId, 'sys_content_cache_engine', '_adm_stg_cpt_option_sys_content_cache_engine', 'File', 'select', 'File,Memcache,APC,XCache', '', '', 6),
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `info`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'sys_content_cache_enable', '_adm_stg_cpt_option_sys_content_cache_enable', '', 'on', 'checkbox', '', '', '', 5),
+(@iCategoryId, 'sys_content_cache_engine', '_adm_stg_cpt_option_sys_content_cache_engine', '', 'File', 'select', 'File,Memcache,APC,XCache,Redis', '', '', 6),
 
-(@iCategoryId, 'sys_db_cache_enable', '_adm_stg_cpt_option_sys_db_cache_enable', 'on', 'checkbox', '', '', '', 10),
-(@iCategoryId, 'sys_db_cache_engine', '_adm_stg_cpt_option_sys_db_cache_engine', 'File', 'select', 'File,Memcache,APC,XCache', '', '', 11),
+(@iCategoryId, 'sys_db_cache_enable', '_adm_stg_cpt_option_sys_db_cache_enable', '', 'on', 'checkbox', '', '', '', 10),
+(@iCategoryId, 'sys_db_cache_engine', '_adm_stg_cpt_option_sys_db_cache_engine', '', 'File', 'select', 'File,Memcache,APC,XCache,Redis', '', '', 11),
 
-(@iCategoryId, 'sys_cache_memcache_host', '_adm_stg_cpt_option_sys_cache_memcache_host', '', 'digit', '', '', '', 20),
-(@iCategoryId, 'sys_cache_memcache_port', '_adm_stg_cpt_option_sys_cache_memcache_port', '11211', 'digit', '', '', '', 21),
+(@iCategoryId, 'sys_cache_memcache_host', '_adm_stg_cpt_option_sys_cache_memcache_host', '', '', 'digit', '', '', '', 20),
+(@iCategoryId, 'sys_cache_memcache_port', '_adm_stg_cpt_option_sys_cache_memcache_port', '', '11211', 'digit', '', '', '', 21),
+(@iCategoryId, 'sys_cache_redis_connection_string', '_adm_stg_cpt_option_sys_cache_redis_connection_string', '_adm_stg_cpt_option_sys_cache_redis_connection_string_info', '', 'digit', '', '', '', 25),
 
-(@iCategoryId, 'sys_page_cache_enable', '_adm_stg_cpt_option_sys_page_cache_enable', 'on', 'checkbox', '', '', '', 30),
-(@iCategoryId, 'sys_page_cache_engine', '_adm_stg_cpt_option_sys_page_cache_engine', 'File', 'select', 'File,Memcache,APC,XCache', '', '', 31),
+(@iCategoryId, 'sys_page_cache_enable', '_adm_stg_cpt_option_sys_page_cache_enable', '', 'on', 'checkbox', '', '', '', 30),
+(@iCategoryId, 'sys_page_cache_engine', '_adm_stg_cpt_option_sys_page_cache_engine', '', 'File', 'select', 'File,Memcache,APC,XCache,Redis', '', '', 31),
 
-(@iCategoryId, 'sys_pb_cache_enable', '_adm_stg_cpt_option_sys_pb_cache_enable', 'on', 'checkbox', '', '', '', 40),
-(@iCategoryId, 'sys_pb_cache_engine', '_adm_stg_cpt_option_sys_pb_cache_engine', 'File', 'select', 'File,Memcache,APC,XCache', '', '', 41),
+(@iCategoryId, 'sys_pb_cache_enable', '_adm_stg_cpt_option_sys_pb_cache_enable', '', 'on', 'checkbox', '', '', '', 40),
+(@iCategoryId, 'sys_pb_cache_engine', '_adm_stg_cpt_option_sys_pb_cache_engine', '', 'File', 'select', 'File,Memcache,APC,XCache,Redis', '', '', 41),
 
-(@iCategoryId, 'sys_template_cache_enable', '_adm_stg_cpt_option_sys_template_cache_enable', 'on', 'checkbox', '', '', '', 50),
-(@iCategoryId, 'sys_template_cache_engine', '_adm_stg_cpt_option_sys_template_cache_engine', 'FileHtml', 'select', 'FileHtml,Memcache,APC,XCache', '', '', 51),
-(@iCategoryId, 'sys_template_cache_css_enable', '_adm_stg_cpt_option_sys_template_cache_css_enable', 'on', 'checkbox', '', '', '', 55),
-(@iCategoryId, 'sys_template_cache_js_enable', '_adm_stg_cpt_option_sys_template_cache_js_enable', 'on', 'checkbox', '', '', '', 56),
-(@iCategoryId, 'sys_template_cache_minify_css_enable', '_adm_stg_cpt_option_sys_template_cache_minify_css_enable', 'on', 'checkbox', '', '', '', 57),
-(@iCategoryId, 'sys_template_cache_minify_js_enable', '_adm_stg_cpt_option_sys_template_cache_minify_js_enable', 'on', 'checkbox', '', '', '', 58),
-(@iCategoryId, 'sys_template_cache_compress_enable', '_adm_stg_cpt_option_sys_template_cache_compress_enable', 'on', 'checkbox', '', '', '', 59);
+(@iCategoryId, 'sys_template_cache_enable', '_adm_stg_cpt_option_sys_template_cache_enable', '', 'on', 'checkbox', '', '', '', 50),
+(@iCategoryId, 'sys_template_cache_engine', '_adm_stg_cpt_option_sys_template_cache_engine', '', 'FileHtml', 'select', 'FileHtml,Memcache,APC,XCache,Redis', '', '', 51),
+(@iCategoryId, 'sys_template_cache_css_enable', '_adm_stg_cpt_option_sys_template_cache_css_enable', '', 'on', 'checkbox', '', '', '', 55),
+(@iCategoryId, 'sys_template_cache_js_enable', '_adm_stg_cpt_option_sys_template_cache_js_enable', '', 'on', 'checkbox', '', '', '', 56),
+(@iCategoryId, 'sys_template_cache_minify_css_enable', '_adm_stg_cpt_option_sys_template_cache_minify_css_enable', '', 'on', 'checkbox', '', '', '', 57),
+(@iCategoryId, 'sys_template_cache_minify_js_enable', '_adm_stg_cpt_option_sys_template_cache_minify_js_enable', '', 'on', 'checkbox', '', '', '', 58),
+(@iCategoryId, 'sys_template_cache_compress_enable', '_adm_stg_cpt_option_sys_template_cache_compress_enable', '', 'on', 'checkbox', '', '', '', 59);
 
 
 --

+ 2 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -1649,6 +1649,8 @@
     <string name="_adm_stg_inf_option_sys_autoupdate"><![CDATA[Try to update core  system and modules automatically.]]></string>
     <string name="_adm_stg_cpt_option_sys_cache_memcache_host"><![CDATA[Memcached server host]]></string>
     <string name="_adm_stg_cpt_option_sys_cache_memcache_port"><![CDATA[Memcached server port]]></string>
+    <string name="_adm_stg_cpt_option_sys_cache_redis_connection_string"><![CDATA[Redis server connection string]]></string>
+    <string name="_adm_stg_cpt_option_sys_cache_redis_connection_string_info"><![CDATA[For example: redis://pwdhere@localhost:6379/2, where 2 is database number (0 by default)]]></string>
     <string name="_adm_stg_cpt_option_sys_captcha_default"><![CDATA[Default Сaptcha]]></string>
     <string name="_adm_stg_cpt_option_sys_cf_enable"><![CDATA[Enable content filters]]></string>
     <string name="_adm_stg_cpt_option_sys_cf_enable_comments"><![CDATA[Enable content filters for comments]]></string>

+ 2 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -1624,6 +1624,8 @@
     <string name="_adm_stg_inf_option_sys_autoupdate"><![CDATA[Автоматически обновлять (если это возможно) основную систему и модули.]]></string>
     <string name="_adm_stg_cpt_option_sys_cache_memcache_host"><![CDATA[Memcached - адрес сервера]]></string>
     <string name="_adm_stg_cpt_option_sys_cache_memcache_port"><![CDATA[Memcached - порт сервера]]></string>
+    <string name="_adm_stg_cpt_option_sys_cache_redis_connection_string"><![CDATA[Redis - строка реквизитов доступа]]></string>
+    <string name="_adm_stg_cpt_option_sys_cache_redis_connection_string_info"><![CDATA[Например: redis://pwdhere@localhost:6379/2, где 2 это номер базы данных (0 по умолчанию)]]></string>
     <string name="_adm_stg_cpt_option_sys_captcha_default"><![CDATA[CAPTCHA по умолчанию]]></string>
     <string name="_adm_stg_cpt_option_sys_cf_enable"><![CDATA[Включить контентные фильтры]]></string>
     <string name="_adm_stg_cpt_option_sys_cf_enable_comments"><![CDATA[Включить контентные фильтры для комментариев]]></string>