cjprinse/magento-redis-session

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

安装: 35

依赖者: 0

建议者: 0

安全性: 0

星级: 0

关注者: 2

分支: 120

类型:magento-module

2.0.4 2017-03-22 16:14 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);完全禁用锁定。
  • 需要PHP >= 5.3。是的,这是一个功能。欢迎您。 ;)

锁定算法属性

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

会话Cookie管理

Cookie生命周期在这里配置(Magento默认):系统 > 配置 > 网络 > 会话Cookie管理 > Cookie生命周期。如果您需要调整会话生命周期设置,可以通过设置<max_lifetime><min_lifetime>处理程序来覆盖此模块的默认会话生命周期设置。请注意,如果<max_lifetime>设置低于Cookie生命周期,则将采用<max_lifetime>设置。

安装

  1. 使用modman安装模块

     modman clone https://github.com/colinmollenhour/Cm_RedisSession
    
  2. 如果需要,通过app/etc/local.xml配置,添加一个global/redis_session部分,包含适当的配置。请参阅下面的“配置示例”。

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

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

     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 -->
        </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 并减少网络利用率。默认的 compression threshold 是 2048 字节,因此等于或大于此大小的任何会话数据都将使用所选的 compression_lib 进行压缩,默认为 gzip。可以通过将 compression_lib 设置为 none 来禁用压缩。然而,lzfsnappy 提供了具有可比压缩比率的更快压缩,因此如果您有 root 权限,我绝对推荐使用其中之一。lzf 可以通过 pecl 安装。

sudo pecl install lzf

注意: 如果使用带有会话数据加密的 suhosin(默认为 suhosin.session.encrypt=on),有两个问题

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

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

机器人检测

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

Cm_Cache_Backend_Redis 一起使用

与 Cm_Cache_Backend_Redis 一起使用 Cm_RedisSession 应该没有问题。要牢记的主要事情是,如果缓存和会话都使用相同的数据库,则刷新缓存后端也会刷新会话!所以,如果您只运行一个 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).