PHP Redis 会话锁定内部结构

Chr*_*nch 5 php phpredis

phpredis会话锁定内部是如何工作的?它是否在内部存储一个值并不断检查它?如果我有很高的redis.session.lock_retries意愿,如果需要 10 秒才能获得锁定并且必须尝试数千次,那么会给服务器带来负载?

\n\n

以下是配置参数。

\n\n
; Should the locking be enabled? Defaults to: 0.\nredis.session.locking_enabled = 1\n; How long should the lock live (in seconds)? Defaults to: value of max_execution_time.\nredis.session.lock_expire = 60\n; How long to wait between attempts to acquire lock, in microseconds (\xc2\xb5s)?. Defaults to: 2000\nredis.session.lock_wait_time = 50000\n; Maximum number of times to retry (-1 means infinite). Defaults to: 10\nredis.session.lock_retries = 10\n
Run Code Online (Sandbox Code Playgroud)\n

apo*_*fos 5

添加此内容的提交位于此处

这似乎暗示它使用Redis 文档中描述的锁定配方。

总的来说,这个配方依赖于原子地尝试设置一个密钥,如果它不存在(这是锁),并且如果它已经存在则失败。这意味着每次尝试都是对 Redis 服务器的命令,其本身速度非常快,但如果您的 Redis 服务器是远程托管的,则存在网络往返的开销


bis*_*hop 4

看起来这是一个热循环:

static int lock_acquire(RedisSock *redis_sock, redis_session_lock_status *lock_status)
{
  ...
  for (i = 0; retries == -1 || i <= retries; i++) {
      set_lock_key_result = set_session_lock_key(redis_sock, cmd, cmd_len);
      ...
      /* Sleep unless we're done making attempts */
      if (retries == -1 || i < retries) {
        usleep(lock_wait_time);
      }
Run Code Online (Sandbox Code Playgroud)

对于长时间阻塞的请求,没有指数退避或其他缓解措施。如果你有一个很高的扩展(例如,有时是即时锁定获取,有时是 1 秒,有时是 10 秒等),那么我建议将锁定尝试长度设置得相当低,然后编写自己的热循环,该循环更符合您的预计等待时间。如果您有一个相当稳定的预期等待时间(例如总是大约 10 秒),那么只需将等待时间设置得相当高即可。