colinmollenhour/magento-redis-session

一个基于Redis的具有乐观锁功能的Magento会话处理器。

安装: 94,626

依赖: 1

建议者: 1

安全: 0

星星: 209

关注者: 32

分支: 120

开放问题: 12

类型:magento-module

3.2.0 2023-10-03 14:21 UTC

README

一个基于Redis的具有乐观锁功能的Magento会话处理器。

功能

  • 如果无法连接到Redis,将回退到mysql处理器。mysql处理器将回退到文件处理器。
  • 当会话数据大小超过压缩阈值时,会话数据将被压缩。
  • 支持的压缩库有 'gzip', 'lzf', 'lz4', 和 'snappy'。 -- Gzip是速度最慢的,但提供最佳的压缩比。 -- Lzf可以通过PECL轻松安装。 -- Lz4由HHVM支持。
  • 可以在不丢失会话数据的情况下实时启用、禁用或重新配置压缩。
  • Redis处理过期,无需垃圾回收。
  • 当会话由于没有或丢失锁而无法写入时记录日志。
  • 在返回503错误之前限制并发锁请求的数量。
  • 检测不活跃的等待进程以防止并发节流中的假阳性。
  • 检测崩溃的进程以防止会话死锁(仅限Linux)。
  • 给爬虫和机器人分配更短的生命周期以减少资源浪费。
  • 可以通过配置或使用define('CM_REDISSESSION_LOCKING_ENABLED', FALSE);或通过在控制器预处理中设置$this->setFlag('', Cm_RedisSession_Model_Session::FLAG_READ_ONLY, 1)标志完全禁用锁定。
  • 需要PHP >= 5.3。是的,这是一个功能。谢谢。 ;)

锁定算法属性

  • 一个进程可能只能对会话获得一个写锁。
  • 如果另一个进程中断它,一个进程可能会丢失它的锁,在这种情况下,会话将不会被写入。
  • 锁定可能在BREAK_AFTER秒后中断,获得锁的进程是不确定的。
  • 只有MAX_CONCURRENCY个进程可以等待同一会话的锁,否则将返回503错误。

会话Cookie管理

Cookie生存期在此配置(默认值):系统 > 配置 > 网络 > 会话Cookie管理 > Cookie生存期。如果您需要调整会话生存期设置,可以通过设置<max_lifetime><min_lifetime>来覆盖此模块的默认会话生存期设置。请注意,如果<max_lifetime>设置低于Cookie生存期,则取<max_lifetime>设置。

安装

此扩展可以通过Composer或modman安装。

重要:3.0.0版本仅作为composer模块打包,不能使用modman安装。如果您不使用composer,请坚持使用2.x版本。

当前不支持Magento编译器功能。

modman安装

  1. 使用modman安装模块

     modman clone https://github.com/colinmollenhour/Cm_RedisSession
    

    如果您想安装特定版本,可以在命令中添加-- --branch x.y.z

  2. 如有必要,通过app/etc/local.xml添加一个global/redis_session部分进行配置。请参见下面的“配置示例”。

  3. 刷新配置缓存以允许模块通过Magento安装。

  4. 通过运行--test模式的migrateSessions.php脚本来测试配置。

     sudo php .modman/Cm_RedisSession/migrateSessions.php --test
    
  5. 在app/etc/local.xml中将global/session_save配置更改为“db”。“db”值是MySQL处理器,但Cm_RedisSession覆盖它以避免修改核心文件。

  6. 将旧会话迁移到Redis。有关详细信息,请参阅下面的“迁移”部分。迁移脚本将在迁移完成后清除配置缓存,以激活第5步中进行的配置更改。

配置示例

<config>
    <global>
        ...
        <session_save>db</session_save>
        <redis_session>                       <!-- All options seen here are the defaults -->
            <host>127.0.0.1</host>            <!-- Specify an absolute path if using a unix socket -->
            <port>6379</port>
            <password></password>             <!-- Specify if your Redis server requires authentication -->
            <timeout>2.5</timeout>            <!-- This is the Redis connection timeout, not the locking timeout -->
            <persistent></persistent>         <!-- Specify unique string to enable persistent connections. E.g.: sess-db0; bugs with phpredis and php-fpm are known: https://github.com/nicolasff/phpredis/issues/70 -->
            <db>0</db>                        <!-- Redis database number; protection from accidental loss is improved by using a unique DB number for sessions -->
            <compression_threshold>2048</compression_threshold>  <!-- Known bug with strings over 64k: https://github.com/colinmollenhour/Cm_Cache_Backend_Redis/issues/18 -->
            <compression_lib>gzip</compression_lib>              <!-- gzip, lzf, lz4, snappy or none to disable compression -->
            <log_level>1</log_level>               <!-- 0 (emergency: system is unusable), 4 (warning; additional information, recommended), 5 (notice: normal but significant condition), 6 (info: informational messages), 7 (debug: the most information for development/testing) -->
            <max_concurrency>6</max_concurrency>                 <!-- maximum number of processes that can wait for a lock on one session; for large production clusters, set this to at least 10% of the number of PHP processes -->
            <break_after_frontend>5</break_after_frontend>       <!-- seconds to wait for a session lock in the frontend; not as critical as admin -->
            <fail_after>10</fail_after>                          <!-- seconds after which we bail from attempting to obtain lock (in addition to break after time) -->
            <break_after_adminhtml>30</break_after_adminhtml>
            <first_lifetime>600</first_lifetime>                 <!-- Lifetime of session for non-bots on the first write. 0 to disable -->
            <bot_first_lifetime>60</bot_first_lifetime>          <!-- Lifetime of session for bots on the first write. 0 to disable -->
            <bot_lifetime>7200</bot_lifetime>                    <!-- Lifetime of session for bots on subsequent writes. 0 to disable -->
            <disable_locking>0</disable_locking>                 <!-- Disable session locking entirely. -->
            <min_lifetime>60</min_lifetime>                      <!-- Set the minimum session lifetime -->
            <max_lifetime>2592000</max_lifetime>                 <!-- Set the maximum session lifetime -->
            <log_exceptions>0</log_exceptions>                   <!-- Log connection failure and concurrent connection exceptions in exception.log. -->
        </redis_session>
        ...
    </global>
    ...
</config>

迁移

包含一个脚本,用于将文件存储的会话迁移到Redis,以实现最小停机时间。使用类似下面的shell脚本执行“安装”部分的第6步。

cd /var/www              # Magento installation root
touch maintenance.flag   # Enter maintenance mode
sleep 2                  # Allow any running processes to complete
# This will copy sessions into redis and clear the config cache so local.xml changes will take effect
sudo php .modman/Cm_RedisSession/migrateSessions.php -y
rm maintenance.flag      # All done, exit maintenance mode

根据您的服务器配置,可能需要进行一些更改。旧会话不会被删除,因此如果出现问题,您可以再次运行它。migrateSessions.php脚本有一个--test模式,您绝对应该在最终迁移之前使用它。此外,--test模式可以用于比较压缩性能和比率。最重要的是,--test模式可以大致告诉您压缩会话将占用多少空间,以便您大致了解如何配置maxmemory(如果需要)。所有会话都有过期时间,因此volatile-lruallkeys-lru都是很好的maxmemory-policy设置。

压缩

会话数据压缩得很好,因此使用压缩是增加容量而不需要为Redis分配大量RAM并减少网络利用率的好方法。默认的压缩阈值是2048字节,因此任何等于或大于此大小的会话数据都将使用默认的compression_lib(gzip)进行压缩。可以通过将compression_lib设置为none来禁用压缩。然而,lzfsnappy提供了与可比压缩比率的高速压缩,所以我强烈建议如果您有root权限,则使用其中之一。lzf可以通过pecl轻松安装。

sudo pecl install lzf

注意:如果使用suhosin并启用会话数据加密(默认为suhosin.session.encrypt=on),则有两件事

  1. 您可能会得到非常差的压缩比率。
  2. 在我的经验中,lzf无法压缩加密数据。不知道为什么...

如果任何压缩库无法压缩会话数据,系统日志中将会记录错误,并且会话将未压缩地保存。如果您启用了suhosin.session.encrypt=on,我建议您禁用它(除非您在共享主机上,因为Magento已经进行自己的会话验证)或禁用压缩,或者至少不要在启用加密的情况下使用lzf。

机器人检测

机器人和爬虫通常不使用cookies,这意味着您可能存储了成千上万的会话,这些会话没有任何作用。更糟糕的是,攻击者可能会利用您有限的会话存储来攻击您,通过淹没您的后端,从而使您的合法会话被驱逐。然而,您不希望错误地将用户识别为机器人并无意中终止他们的会话。此模块使用正则表达式以及会话写入次数的计数器来决定会话寿命。

Cm_Cache_Backend_Redis一起使用

与Cm_RedisSession一起使用Cm_Cache_Backend_Redis应该没有问题。需要注意的是,如果缓存和会话都使用相同的数据库,则刷新缓存后端也会刷新会话!因此,如果您只运行一个Redis实例,请不要为两者使用相同的'db'编号。然而,为每个使用单独的Redis实例是推荐的,以确保其中一个不会无限制地消耗空间并导致另一个的驱逐。例如,配置两个实例,每个实例100M最大内存,而不是一个200M最大内存的实例。

许可

@copyright  Copyright (c) 2013 Colin Mollenhour (http://colin.mollenhour.com)
This project is licensed under the "New BSD" license (see source).