当前位置: 首页 > 原理解释

phpsession共享redis原理-PHP 共享 Redis 原理

PHP 的 session 和 Redis 的共享机制,说白了就是个“临时记事本”和“云端草稿纸”的合体。 PHP 用户登录时,服务器拿到这个人资料,然后往 Redis 里塞个 IO_NID 的 ID,说“嘿,赶明儿找他,就找这个 ID 就行”。代码里就连懒得查数据库,直接拿 ID 去 Redis 里搜名字,搜不到就报错。
这实际上是最笨的写法,对吧?就像你找东西,既要在身边随手翻个口袋,又得把手机揣兜里再翻。但为了省事,还是如此干了。 这就有点尴尬了。
要是用户换了机子,要么服务器重启,那个临时记事本就扔了,ID 也找不到了。数据就会丢。
故此务必有个“地方存着”,不然下次来了就乱套。Redis 做这个存数据的仓库,PHP 则负责去仓库里查。
这就是最好办的两层架构,一层本地,一层远程。 这里得提个醒,PHP 的 session 实际上默认是存 Redis 里的。
要是你没在代码里 explicitly(明确地)写 `session_set_save_handler` 是个啥,那它可能会落在本地磁盘上。但要是你不关心本地性能,要么服务器配置了 session 存驱动为 redis 的,那一切就顺了。 这时候还得聊聊 Redis 如何负责这个“查”。Redis 本身是个内存里的超级快鸡,但为了保险,一般/平平用户查数据还得走一个“审批”流程。PHP 代码里查 session,会连接到 Redis 服务。Redis 先检查用户是不是当前账号的“管理员”,不是,那就回绝,直接回 401 毛病。
要是是管理员,那就查 ID,ID 找到了,才展示名字。 这个调用过程有点小操作。PHP 用户发起请求,服务器先拿 ID 去 Redis 里“翻”,翻一翻,ID 在,名字也在,回给前端。前端收到数据,显示出来。整个过程大约 50 毫秒,在这个时代简直像蜗牛爬,但比查本地数据库快了不止一倍。 为了验证这个逻辑对不对,我们能够造个测试用例。假设一启动有 5 个用户,ID 分别是 001 到 005,Redis 里存着他们的名字。PHP 代码里写死一个 ID 为 006 的用户,名字就是 Bob。目前让一个没登录的浏览器去访问,PHP 代码里就搜不到这个名字。出于它不是当前会话的 ID,故此 Redis 直接不给名字。结局就是浏览器显示“401 Unauthorized",根本看不见 Bob。 这就证明白 PHP 和 Redis 在“验证身份”这一步上配合默契。PHP 负责“你是哪位”,Redis 负责“你是哪位的人”。两者缺一不可,否则就是盲人摸象。 但这不只是是验证,存也是个活儿。
每次用户操作,比如修改了资料,PHP 代码里会触发一个事件。
这个事件会发给 Redis,说“嘿,用户 A 的操作记录更新了”。Redis 收到通知,从内存里把那条记录取出来,更新数据库,再往 Redis 里存一条新记录。 这里有个细节要注意,不是所有操作都要往 Redis 存。
比如登录、登出、修改密码这种敏感操作,务必存 Redis,保证数据不丢,用户不管几台机器,都能对上号。但像点赞这种“读多写少”的操作,Redis 里存了也没关系,查重也能找个理由回绝,性能更好。 数据量大起来之后,Redis 也得扩容。PHP 没法直接去 Redis 写,得找个中间人。最常用的就是 Lua 脚本。PHP 写个脚本,脚本里写“要是 Redis 里的 ID 存有,就回名字;不存有,就回空”。
这个脚本务必在 Redis 里执行,PHP 只能触发它。出于 Redis 是只读的,PHP 不能直接写,故此得用这种“脚本”来强制更新。 有时候为了省工夫,PHP 用户直接用 `session_regenerate_id` 这个功能。意思是刷新一次会话,把旧的 ID 扔掉,换成新的 ID。PHP 在 Redis 里搜那个旧 ID,没找到就回退。
然后代码里把新 ID 塞进去。
这样就算 Redis 重启了,旧的 ID 丢了,PHP 再搜也搜不到,就自动换成新 ID 了。
这招挺狠的,相当于把老本行重新来过,彻底告别了数据丢失的烦恼。 最终得说说 Redis 的持久化。Redis 别看快,但断电数据就丢了。
故此它得有手段。
一般是用 RDB 快照,就是每 1 秒拍一张照。
要么用 AOF 日志,写日志啥的。PHP 端一般不直接管这些,而是让 Redis 自己管。PHP 只要记得“这个用户 ID 重定向过 Redis 了”,到了 Redis 就重新生成 ID。 整个流程就是:PHP 用户 -> 验证身份(Redis)-> 操作数据(Redis)-> 写回本地(PHP 本地或 Redis)-> 下次请求重复验证。环环相扣,缺一不可。 说到底,PHP 的 session 和 Redis 的结合,就是把“本地临时内存”和“远程持久化存”通过一个唯一的 ID 串起来。PHP 负责拿着 ID 去 Redis 里找名字,Redis 负责照着 ID 存名字。中间没有半点遗漏,数据就稳当。 这种架构有个益处,用户只要登录一次,赶明儿用几台服务器、几百台机器,只要 ID 还在,就能一直用,不用重新注册。就像 Identity Server 那种模式,别看 PHP 没直接参与,但逻辑是通的。PHP 用户只要从 Redis 里拿到 ID,后续所有操作都在 Redis 里转,逻辑上就一模一样。 自然,也不是说 PHP 就彻底不动了。PHP 还是得把 ID 拿过来,告诉 Redis:“我目前要存这个新数据”。
要是 Redis 写错了,PHP 就得重来。
要是 Redis 网络断了,PHP 就得重试。
这就是分布式系统的坑,也是它务必得如此设计的初衷。 最终总结一下,PHP 和 Redis 的共享原理,就是一层看身份,一层处理数据。PHP 负责“我是哪位”,Redis 负责“我存啥”。两者配合,既能保证数据保险,又能保证访问速度。别看代码里看起来有点绕,但逻辑上好办明白,只要 ID 对得上,就能把数据保险地存下来,哪位也拿不走。
相关标签:

猜你喜欢

热门阅读

  • 赖柴尔定理-赖柴尔定理
  • 迪拜哪个国家的城市?-迪拜在哪国城市
  • 李毅吧番号及出处-李毅吧番号及出处
  • 贴春联的由来简介50字-春联由来简述
  • 思乡的名言和出处-思乡名言及出处

其他分站