SWAPDB:互换数据库

SWAPDB命令接受两个数据库号码作为输入,然后对指定的两个数据库进行互换,最后返回OK作为结果:

SWAPDB x y
bash

在SWAPDB命令执行完毕之后,原本存储在数据库x中的键值对将出现在数据库y中,而原本存储在数据库y中的键值对将出现在数据库x中。

举个例子,对于以下这个包含键k1、k2和k3的0号数据库:

db0> KEYS *
1) "k3"
2) "k2"
3) "k1"
bash

以及以下这个包含键k4、k5和k6的1号数据库来说:

db1> KEYS *
1) "k5"
2) "k4"
3) "k6"
bash

如果我们执行以下命令,对0号数据库和1号数据库实行互换:

db0> SWAPDB 0 1
O
bash

那么在此之后,原本存储在0号数据库中的键k1、k2和k3将出现在1号数据库中:

db1> KEYS *
1) "k3"
2) "k2"
3) "k1"
bash

而原本存储在1号数据库中的键k4、k5和k6将出现在0号数据库中:

db0> KEYS *
1) "k5"
2) "k4"
3) "k6"
bash

因为互换数据库这一操作可以通过调整指向数据库的指针来实现,这个过程不需要移动数据库中的任何键值对,所以SWAPDB命令的复杂度是O(1)而不是O(N),并且执行这个命令也不会导致服务器阻塞。

其他信息

  • 复杂度:O(1)。

  • 版本要求:SWAPDB命令从Redis 4.0版本开始可用。

示例:使用SWAPDB命令实行在线替换数据库

正如11.15节所介绍的,SWAPDB 命令可以以非阻塞方式互换给定的两个数据库。因为这个命令的执行速度是如此之快,并且完全不会阻塞服务器,所以用户实际上可以使用这个命令来实行在线的数据库替换操作。

举个例子,假设我们拥有一个Redis服务器,它的0号数据库存储了用户的邮件地址以及经过加密的用户密码,这些数据可以用于登录用户账号。不幸的是,因为一次漏洞事故,这个服务器遭到了黑客入侵,并且经过确认,这个服务器存储的所有用户密码均已泄露。为了保障用户的信息安全,我们决定立即重置所有用户密码,具体的做法是: 遍历所有用户的个人档案,为每个用户生成一个新的随机密码,并使用这个新密码替换已经泄露的旧密码。

代码清单11-4展示了一个用于重置用户密码的脚本,它的 reset_user_password() 函数会迭代 origin 数据库中的所有用户数据,为其生成新密码,并将更新后的用户信息存储到new数据库中。在此之后,函数会使用SWAPDB 命令互换新旧两个数据库,并以异步方式移除旧数据库。

代码清单11-4 用于重置用户密码的脚本代码:/database/reset_user_password.py
import random

from redis import Redis
from hashlib import sha256

def generate_new_password():
    random_string = str(random.getrandbits(256)).encode('utf-8')
    return sha256(random_string).hexdigest()

def reset_user_password(origin, new):
    # 两个客户端,分别连接两个数据库
    origin_db = Redis(db=origin)
    new_db = Redis(db=new)

    for key in origin_db.scan_iter(match="user::*"):
        # 从源数据库获取现有用户信息
        user_data = origin_db.hgetall(key)
        # 重置用户密码
        user_data["password"] = generate_new_password()
        # 将新的用户信息储存到新数据库里面
        new_db.hmset(key, user_data)

    # 互换新旧数据库
    origin_db.swapdb(origin, new)

    # 以异步方式移除旧数据库
    # (new_db 变量现在已经指向旧数据库)
    new_db.flushdb(asynchronous=True)
python

作为例子,表11-5和表11-6分别展示了设置新密码之前和之后的用户数据。注意,为了凸显新旧密码之间的区别,重置之前的用户密码是未经加密的。

image 2025 01 05 15 48 24 508
Figure 1. 表11-5 重置之前的用户数据
image 2025 01 05 15 48 42 571
Figure 2. 表11-6 重置之后的用户数据